From d5d32ae31b5d98e8dba7021a49132511ffbc4190 Mon Sep 17 00:00:00 2001 From: Rickert Mulder Date: Wed, 13 Aug 2014 01:35:00 +0200 Subject: [PATCH 01/17] fix(modal): Make off screen modals accessible --- src/modal/modal.js | 8 +++++--- template/modal/window.html | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/modal/modal.js b/src/modal/modal.js index ff31594..7b35ef4 100644 --- a/src/modal/modal.js +++ b/src/modal/modal.js @@ -113,8 +113,8 @@ angular.module('mm.foundation.modal', ['mm.foundation.transition']) }; }]) - .factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap', - function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) { + .factory('$modalStack', ['$window', '$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap', + function ($window, $transition, $timeout, $document, $compile, $rootScope, $$stackedMap) { var OPENED_MODAL_CLASS = 'modal-open'; @@ -229,7 +229,9 @@ angular.module('mm.foundation.modal', ['mm.foundation.transition']) body.append(backdropDomEl); } - var angularDomEl = angular.element('
'); + var openAt = window.outerWidth > 800 ? $window.scrollY + 100 : $window.scrollY; + + var angularDomEl = angular.element('
'); angularDomEl.attr('window-class', modal.windowClass); angularDomEl.attr('index', openedWindows.length() - 1); angularDomEl.attr('animate', 'animate'); diff --git a/template/modal/window.html b/template/modal/window.html index d47569f..0b8cc5e 100644 --- a/template/modal/window.html +++ b/template/modal/window.html @@ -1,5 +1,5 @@
+ style="display: block; visibility: visible">
From 1304c91feaf2e84950574d41d4b5f58ad7cf228e Mon Sep 17 00:00:00 2001 From: Rickert Mulder Date: Mon, 18 Aug 2014 05:07:33 +0200 Subject: [PATCH 02/17] fix(modal): Removed redundant offset --- src/modal/modal.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/modal/modal.js b/src/modal/modal.js index 7b35ef4..e507f0b 100644 --- a/src/modal/modal.js +++ b/src/modal/modal.js @@ -228,10 +228,8 @@ angular.module('mm.foundation.modal', ['mm.foundation.transition']) backdropDomEl = $compile('
')(backdropScope); body.append(backdropDomEl); } - - var openAt = window.outerWidth > 800 ? $window.scrollY + 100 : $window.scrollY; - var angularDomEl = angular.element('
'); + var angularDomEl = angular.element('
'); angularDomEl.attr('window-class', modal.windowClass); angularDomEl.attr('index', openedWindows.length() - 1); angularDomEl.attr('animate', 'animate'); From 290de121e4e93fd33435303f8027d4599f42d381 Mon Sep 17 00:00:00 2001 From: Rickert Mulder Date: Mon, 18 Aug 2014 05:33:18 +0200 Subject: [PATCH 03/17] fix(modal): Revert the conditional 100px offset. --- src/modal/modal.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modal/modal.js b/src/modal/modal.js index e507f0b..7b35ef4 100644 --- a/src/modal/modal.js +++ b/src/modal/modal.js @@ -228,8 +228,10 @@ angular.module('mm.foundation.modal', ['mm.foundation.transition']) backdropDomEl = $compile('
')(backdropScope); body.append(backdropDomEl); } + + var openAt = window.outerWidth > 800 ? $window.scrollY + 100 : $window.scrollY; - var angularDomEl = angular.element('
'); + var angularDomEl = angular.element('
'); angularDomEl.attr('window-class', modal.windowClass); angularDomEl.attr('index', openedWindows.length() - 1); angularDomEl.attr('animate', 'animate'); From b62226944f0fdb9cce4b25a64638e14c0459337a Mon Sep 17 00:00:00 2001 From: Jeff Browning Date: Wed, 27 Aug 2014 15:08:55 -0400 Subject: [PATCH 04/17] chore(docs): Add badges to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d47209b..a33799b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Angular Components for [Foundation](http://foundation.zurb.com/) - +[![Build Status](https://semaphoreapp.com/api/v1/projects/670cabb5-3c50-4197-9df5-e75cf62c9d20/237671/badge.png)](https://semaphoreapp.com/pinecone/angular-foundation) +[![Latest Version](https://badge.fury.io/bo/angular-foundation.svg)](https://github.com/pineconellc/angular-foundation-bower) *** This project is a port of the AngularUI team's excellent [angular-bootstrap](https://github.com/angular-ui/bootstrap) project for use in the [Foundation](http://foundation.zurb.com/) framework. From 9a60585e81c9385307590d750d7cbf707a6cd547 Mon Sep 17 00:00:00 2001 From: Rickert Mulder Date: Thu, 28 Aug 2014 01:46:06 +0200 Subject: [PATCH 05/17] fix(modal): Dynamically determine the margin --- src/modal/modal.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/modal/modal.js b/src/modal/modal.js index 7b35ef4..019b605 100644 --- a/src/modal/modal.js +++ b/src/modal/modal.js @@ -229,9 +229,16 @@ angular.module('mm.foundation.modal', ['mm.foundation.transition']) body.append(backdropDomEl); } - var openAt = window.outerWidth > 800 ? $window.scrollY + 100 : $window.scrollY; + // Create a faux modal div just to measure its + // distance to top + var faux = angular.element('
'); + body.append(faux[0]); + var marginTop = parseInt(getComputedStyle(faux[0]).top); + faux.remove(); - var angularDomEl = angular.element('
'); + var openAt = $window.scrollY + marginTop; + + var angularDomEl = angular.element('
'); angularDomEl.attr('window-class', modal.windowClass); angularDomEl.attr('index', openedWindows.length() - 1); angularDomEl.attr('animate', 'animate'); From 88d7039a8852cf7205af268cca31a2e8c88d382b Mon Sep 17 00:00:00 2001 From: Rickert Mulder Date: Thu, 28 Aug 2014 14:27:09 +0200 Subject: [PATCH 06/17] fix(modal): Focus the correct element --- src/modal/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modal/modal.js b/src/modal/modal.js index 019b605..8e2792c 100644 --- a/src/modal/modal.js +++ b/src/modal/modal.js @@ -106,7 +106,7 @@ angular.module('mm.foundation.modal', ['mm.foundation.transition']) } else{ // otherwise focus the freshly-opened modal - element[0].focus(); + element[0].querySelector('div').focus(); } }); } From b60df2c157545c8c3fe23339414f562ef2468c26 Mon Sep 17 00:00:00 2001 From: Raymond Julin Date: Fri, 5 Sep 2014 15:13:16 +0200 Subject: [PATCH 07/17] fix(interchange): Support IE9 via matchMedia shim --- src/interchange/interchange.js | 6 +++--- src/interchange/test/interchange.spec.js | 11 ++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/interchange/interchange.js b/src/interchange/interchange.js index 348641e..837013d 100644 --- a/src/interchange/interchange.js +++ b/src/interchange/interchange.js @@ -6,7 +6,7 @@ * Package containing all services and directives * about the `interchange` module */ -angular.module('mm.foundation.interchange', []) +angular.module('mm.foundation.interchange', ['mm.foundation.mediaQueries']) /** * @ngdoc function @@ -92,7 +92,7 @@ angular.module('mm.foundation.interchange', []) * * Tools to help with the `interchange` module. */ - .factory('interchangeTools', ['$window', 'interchangeQueries', function ($window, namedQueries) { + .factory('interchangeTools', ['$window', 'matchMedia', 'interchangeQueries', function ($window, matchMedia, namedQueries) { /** * @ngdoc method @@ -156,7 +156,7 @@ angular.module('mm.foundation.interchange', []) var file, media, match; for (file in files) { media = namedQueries[file] || file; - match = $window.matchMedia(media); + match = matchMedia(media); if (match.matches) { return files[file]; } diff --git a/src/interchange/test/interchange.spec.js b/src/interchange/test/interchange.spec.js index 16875db..eaa1c04 100644 --- a/src/interchange/test/interchange.spec.js +++ b/src/interchange/test/interchange.spec.js @@ -91,9 +91,14 @@ describe("interchange", function () { })); beforeEach(function () { - spyOn(window, 'matchMedia').andCallFake(function (media) { - var isMatching = (matchMediaMock === media); - return isMatching ? {matches: true} : {}; + angular.module('mm.foundation.interchange') + .factory('matchMedia', function() { + return function(media) { + return { + matches: (matchMediaMock === media), + media: media + }; + }; }); }); From ac41e65a5ef379bcaf54789b3666b51d3184223e Mon Sep 17 00:00:00 2001 From: Raymond Julin Date: Tue, 23 Sep 2014 10:18:07 +0200 Subject: [PATCH 08/17] feat(stylesheets): Enable modifying head based stylesheets --- src/stylesheets/readme.md | 1 + src/stylesheets/stylesheets.js | 54 ++++++++++++++++++++++++ src/stylesheets/test/stylesheets.spec.js | 24 +++++++++++ 3 files changed, 79 insertions(+) create mode 100644 src/stylesheets/readme.md create mode 100644 src/stylesheets/stylesheets.js create mode 100644 src/stylesheets/test/stylesheets.spec.js diff --git a/src/stylesheets/readme.md b/src/stylesheets/readme.md new file mode 100644 index 0000000..3ad55c2 --- /dev/null +++ b/src/stylesheets/readme.md @@ -0,0 +1 @@ +Stylesheets provides the `stylesheetFactory` helper to manipulate ** based stylesheets. It'll allow you to easily inject a new stylesheet and give it a sensible API. diff --git a/src/stylesheets/stylesheets.js b/src/stylesheets/stylesheets.js new file mode 100644 index 0000000..42d0b10 --- /dev/null +++ b/src/stylesheets/stylesheets.js @@ -0,0 +1,54 @@ +/* + * stylesheets - Manipulate sheets in style + * @example: + + angular.module('mine', ['mm.foundation.stylesheets']) + .controller(function(stylesheetFactory) { + var element = angular.element(document.head).find('styles'); + stylesheetFactory(element).css('#myid:before', { + 'background-color': 'red', + width: '500px' + }); + }); + */ +angular.module('mm.foundation.stylesheets', []) + +.factory('stylesheetFactory', ['$document', function ($document) { + var rulesAsTextContent = function(rules) { + var textContent = ''; + for (var selector in rules) { + var props = rules[selector]; + textContent += selector + ' {\n'; + for (var prop in props) { + textContent += '\t' + prop + ': ' + props[prop] + ';\n'; + } + textContent += '}\n'; + } + return textContent; + }; + return function Stylesheet(element) { + if (!element) { + element = $document[0].createElement('style'); + element = angular.element(element); + angular.element($document[0].querySelector('head')).append(element); + } + var write = function(textContent) { + element.html(textContent); + }; + + var rules = {}; + return { + element: function() { return element; }, + css: function(selector, content) { + if (selector in rules) { + if (content == rules[selector]) { + return; + } + } + rules[selector] = content; + write(rulesAsTextContent(rules)); + return this; + } + }; + }; +}]); diff --git a/src/stylesheets/test/stylesheets.spec.js b/src/stylesheets/test/stylesheets.spec.js new file mode 100644 index 0000000..5188f09 --- /dev/null +++ b/src/stylesheets/test/stylesheets.spec.js @@ -0,0 +1,24 @@ +describe('stylesheets', function() { + var $compile, $rootScope, $document, stylesheetFactory; + + beforeEach(module('mm.foundation.stylesheets')); + + beforeEach(inject(function(_$compile_, _$rootScope_, _$document_, _stylesheetFactory_) { + $compile = _$compile_; + $rootScope = _$rootScope_; + $document = _$document_; + stylesheetFactory = _stylesheetFactory_; + $scope = $rootScope.$new(); + })); + + it('should create and inject new stylesheet', function() { + var sheetId = 'stylesheets-test'; + var sheet = stylesheetFactory(); + sheet.css('#id:before', {color:'red'}); + sheet.element().attr('id', sheetId); + + var $sheet = $document.find('#' + sheetId); + expect($sheet.text()).toEqual(sheet.element().text()); + }); +}); + From 052aa2f279feaf01decdcbe7d0e0f2be8cec8457 Mon Sep 17 00:00:00 2001 From: Raymond Julin Date: Tue, 23 Sep 2014 12:49:27 +0200 Subject: [PATCH 09/17] feat(stylesheets): Support removing rules + from DOM when empty --- src/stylesheets/stylesheets.js | 70 +++++++++++++++--------- src/stylesheets/test/stylesheets.spec.js | 26 +++++++-- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/stylesheets/stylesheets.js b/src/stylesheets/stylesheets.js index 42d0b10..e6bebca 100644 --- a/src/stylesheets/stylesheets.js +++ b/src/stylesheets/stylesheets.js @@ -17,38 +17,54 @@ angular.module('mm.foundation.stylesheets', []) var rulesAsTextContent = function(rules) { var textContent = ''; for (var selector in rules) { - var props = rules[selector]; - textContent += selector + ' {\n'; + var props = rules[selector]; + textContent += selector + ' {\n'; for (var prop in props) { - textContent += '\t' + prop + ': ' + props[prop] + ';\n'; + textContent += '\t' + prop + ': ' + props[prop] + ';\n'; } - textContent += '}\n'; + textContent += '}\n'; } - return textContent; + return textContent.slice(0, -1); }; return function Stylesheet(element) { - if (!element) { - element = $document[0].createElement('style'); - element = angular.element(element); - angular.element($document[0].querySelector('head')).append(element); + var $head = angular.element($document[0].querySelector('head')); + if (!element) { + element = $document[0].createElement('style'); + element = angular.element(element); + } + var currentContent = element.text(); + var write = function(textContent) { + if (textContent !== currentContent) { + currentContent = textContent; + element.text(textContent); + if (currentContent === '') { + element.remove(); + } + else if (!$head[0].contains(element[0])) { + $head.append(element); + } } - var write = function(textContent) { - element.html(textContent); - }; + }; - var rules = {}; - return { - element: function() { return element; }, - css: function(selector, content) { - if (selector in rules) { - if (content == rules[selector]) { - return; - } - } - rules[selector] = content; - write(rulesAsTextContent(rules)); - return this; - } - }; + var rules = {}; + return { + element: function() { return element; }, + css: function(selector, content) { + var exists = selector in rules; + if (typeof content === 'undefined') { + return exists ? rules[selector] : null; + } + if (!exists || content != rules[selector]) { + if (content === null) + delete rules[selector]; + else + rules[selector] = content; + } + return this; + }, + sync: function() { + write(rulesAsTextContent(rules)); + } + }; }; -}]); + }]); diff --git a/src/stylesheets/test/stylesheets.spec.js b/src/stylesheets/test/stylesheets.spec.js index 5188f09..983eb68 100644 --- a/src/stylesheets/test/stylesheets.spec.js +++ b/src/stylesheets/test/stylesheets.spec.js @@ -13,12 +13,30 @@ describe('stylesheets', function() { it('should create and inject new stylesheet', function() { var sheetId = 'stylesheets-test'; + var selector = '#id:before'; + var prop = 'color'; + var value = 'red'; + + var content = {}; + content[prop] = value; + var sheet = stylesheetFactory(); - sheet.css('#id:before', {color:'red'}); sheet.element().attr('id', sheetId); - var $sheet = $document.find('#' + sheetId); - expect($sheet.text()).toEqual(sheet.element().text()); + var cssEquals = function(expected) { + var $sheet = $document.find('#' + sheetId); + expect($sheet.text()).toEqual(expected); + expect(sheet.element().text()).toEqual(expected); + }; + + sheet.css(selector, content).sync(); + cssEquals('#id:before {\n\tcolor: red;\n}'); + + content[prop] = 'green'; + sheet.css(selector, content).sync(); + cssEquals('#id:before {\n\tcolor: green;\n}'); + + sheet.css(selector, null).sync(); + cssEquals(''); }); }); - From d7019dccae6b8716e43c3fc7ce4318075bc5b559 Mon Sep 17 00:00:00 2001 From: Raymond Julin Date: Wed, 24 Sep 2014 10:41:00 +0200 Subject: [PATCH 10/17] style(stylesheets): Missing if-else-braces --- src/stylesheets/stylesheets.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/stylesheets/stylesheets.js b/src/stylesheets/stylesheets.js index e6bebca..f3180c9 100644 --- a/src/stylesheets/stylesheets.js +++ b/src/stylesheets/stylesheets.js @@ -55,10 +55,12 @@ angular.module('mm.foundation.stylesheets', []) return exists ? rules[selector] : null; } if (!exists || content != rules[selector]) { - if (content === null) + if (content === null) { delete rules[selector]; - else + } + else { rules[selector] = content; + } } return this; }, From 74c1f63e335dc74b3c074ca30f6ffcaf97ffbd84 Mon Sep 17 00:00:00 2001 From: Raymond Julin Date: Wed, 24 Sep 2014 10:44:22 +0200 Subject: [PATCH 11/17] chore(stylesheets): Unbroke grunt build --- src/stylesheets/stylesheets.js | 5 ++--- src/stylesheets/test/stylesheets.spec.js | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/stylesheets/stylesheets.js b/src/stylesheets/stylesheets.js index f3180c9..02c866e 100644 --- a/src/stylesheets/stylesheets.js +++ b/src/stylesheets/stylesheets.js @@ -2,14 +2,13 @@ * stylesheets - Manipulate sheets in style * @example: - angular.module('mine', ['mm.foundation.stylesheets']) - .controller(function(stylesheetFactory) { + function(stylesheetFactory) { var element = angular.element(document.head).find('styles'); stylesheetFactory(element).css('#myid:before', { 'background-color': 'red', width: '500px' }); - }); + } */ angular.module('mm.foundation.stylesheets', []) diff --git a/src/stylesheets/test/stylesheets.spec.js b/src/stylesheets/test/stylesheets.spec.js index 983eb68..4b290b4 100644 --- a/src/stylesheets/test/stylesheets.spec.js +++ b/src/stylesheets/test/stylesheets.spec.js @@ -13,7 +13,7 @@ describe('stylesheets', function() { it('should create and inject new stylesheet', function() { var sheetId = 'stylesheets-test'; - var selector = '#id:before'; + var selector = '#id::before'; var prop = 'color'; var value = 'red'; @@ -30,11 +30,11 @@ describe('stylesheets', function() { }; sheet.css(selector, content).sync(); - cssEquals('#id:before {\n\tcolor: red;\n}'); + cssEquals('#id::before {\n\tcolor: red;\n}'); content[prop] = 'green'; sheet.css(selector, content).sync(); - cssEquals('#id:before {\n\tcolor: green;\n}'); + cssEquals('#id::before {\n\tcolor: green;\n}'); sheet.css(selector, null).sync(); cssEquals(''); From 701a62544301c518900314b09c7b1ad4d2f6e9ce Mon Sep 17 00:00:00 2001 From: Raymond Julin Date: Wed, 24 Sep 2014 10:38:07 +0200 Subject: [PATCH 12/17] feat(dropdownToggle): Place pip relative to center of initiator --- src/dropdownToggle/dropdownToggle.js | 16 ++++++++++++-- .../test/dropdownToggle.spec.js | 21 ++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/dropdownToggle/dropdownToggle.js b/src/dropdownToggle/dropdownToggle.js index 37c6e4c..e608750 100644 --- a/src/dropdownToggle/dropdownToggle.js +++ b/src/dropdownToggle/dropdownToggle.js @@ -10,7 +10,7 @@ */ -angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.foundation.mediaQueries' ]) +angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.foundation.mediaQueries', 'mm.foundation.stylesheets' ]) .controller('DropdownToggleController', ['$scope', '$attrs', 'mediaQueries', function($scope, $attrs, mediaQueries) { this.small = function() { @@ -18,7 +18,7 @@ angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.f }; }]) -.directive('dropdownToggle', ['$document', '$window', '$location', '$position', function ($document, $window, $location, $position) { +.directive('dropdownToggle', ['$document', '$window', '$location', '$position', 'stylesheetFactory', function ($document, $window, $location, $position, stylesheetFactory) { var openElement = null, closeMenu = angular.noop; return { @@ -29,6 +29,7 @@ angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.f controller: 'DropdownToggleController', link: function(scope, element, attrs, controller) { var dropdown = angular.element($document[0].querySelector(scope.dropdownToggle)); + var sheet = stylesheetFactory(); scope.$watch('$location.path', function() { closeMenu(); }); element.bind('click', function (event) { @@ -74,6 +75,17 @@ angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.f dropdown.css(css); + var dropdownLeft = $position.offset(dropdown).left; + var pipWidth = parseInt( + getComputedStyle(dropdown[0], '::before').getPropertyValue('width'), 10 + ); + var pipLeft = offset.left - dropdownLeft + Math.round((offset.width - pipWidth) / 2); + var rules = {left: pipLeft + 'px'}; + sheet + .css('#' + dropdown[0].id + '::before', rules) + .css('#' + dropdown[0].id + '::after', rules) + .sync(); + openElement = element; closeMenu = function (event) { $document.unbind('click', closeMenu); diff --git a/src/dropdownToggle/test/dropdownToggle.spec.js b/src/dropdownToggle/test/dropdownToggle.spec.js index fe8b31c..118458d 100644 --- a/src/dropdownToggle/test/dropdownToggle.spec.js +++ b/src/dropdownToggle/test/dropdownToggle.spec.js @@ -1,5 +1,5 @@ describe('dropdownToggle', function() { - var $compile, $rootScope, $document, $location, $window, elm, toggleElm, targetElm; + var $compile, $rootScope, $document, $location, $window, elm, toggleElm, targetElm, $position; function dropdown(id) { if (!id) { @@ -20,12 +20,13 @@ describe('dropdownToggle', function() { beforeEach(module('mm.foundation.dropdownToggle')); - beforeEach(inject(function(_$compile_, _$rootScope_, _$document_, _$location_, _$window_) { + beforeEach(inject(function(_$compile_, _$rootScope_, _$document_, _$location_, _$window_, _$position_) { $compile = _$compile_; $rootScope = _$rootScope_; $document = _$document_; $window = _$window_; $location = _$location_; + $position = _$position_; $scope = $rootScope.$new(); })); @@ -91,19 +92,33 @@ describe('dropdownToggle', function() { return {small: trueFn, medium: falseFn, large: falseFn }; }); - it('should be full-width', function() { + beforeEach(function() { elm = dropdown('responsive'); toggleElm = elm.find('a'); targetElm = elm.find('ul'); toggleElm.click(); + }); + it('should be full-width', function() { expect(targetElm.css('position')).toBe('absolute'); expect(targetElm.css('max-width')).toBe('none'); var expectedWidth = Math.round($window.innerWidth * 0.95); expect(targetElm.css('width')).toBe(expectedWidth + 'px'); }); + + it('should position pip', function() { + var offset = $position.offset(toggleElm); + var targetLeftOffset = parseInt($position.offset(targetElm).left, 10); + + // Find whatever left offset it should have + var styles = getComputedStyle(targetElm[0], '::before'); + var left = styles.getPropertyValue('left'); + var pipWidth = styles.getPropertyValue('width').slice(0, -2); + var expectedLeft = Math.round((offset.width - pipWidth) / 2, 10) + offset.left - targetLeftOffset; + expect(left).toBe(expectedLeft + 'px'); + }); }); }); From 229042c989806cd8600b0eb3479c28766f456a90 Mon Sep 17 00:00:00 2001 From: Raymond Julin Date: Wed, 24 Sep 2014 10:56:29 +0200 Subject: [PATCH 13/17] fix(dropdownToggle): Pip :after position off-by-one --- src/dropdownToggle/dropdownToggle.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dropdownToggle/dropdownToggle.js b/src/dropdownToggle/dropdownToggle.js index e608750..73f3db6 100644 --- a/src/dropdownToggle/dropdownToggle.js +++ b/src/dropdownToggle/dropdownToggle.js @@ -80,10 +80,9 @@ angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.f getComputedStyle(dropdown[0], '::before').getPropertyValue('width'), 10 ); var pipLeft = offset.left - dropdownLeft + Math.round((offset.width - pipWidth) / 2); - var rules = {left: pipLeft + 'px'}; sheet - .css('#' + dropdown[0].id + '::before', rules) - .css('#' + dropdown[0].id + '::after', rules) + .css('#' + dropdown[0].id + '::before', {left: pipLeft + 'px'}) + .css('#' + dropdown[0].id + '::after', {left: pipLeft - 1 + 'px'}) .sync(); openElement = element; From eb3c38cc4236438a5430e47ce0acf7dba4aef81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Phan=20H=E1=BA=A3i?= Date: Tue, 30 Sep 2014 21:27:02 +0700 Subject: [PATCH 14/17] feat(dropdownToggle): Not close content dropdown when clicking on it --- src/dropdownToggle/dropdownToggle.js | 8 ++++++++ src/dropdownToggle/test/dropdownToggle.spec.js | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/dropdownToggle/dropdownToggle.js b/src/dropdownToggle/dropdownToggle.js index 73f3db6..e7f5aea 100644 --- a/src/dropdownToggle/dropdownToggle.js +++ b/src/dropdownToggle/dropdownToggle.js @@ -92,6 +92,14 @@ angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.f closeMenu = angular.noop; openElement = null; }; + + if (dropdown.hasClass('content')) { + dropdown.bind('click', function(evt) { + evt.preventDefault(); + evt.stopPropagation(); + }); + } + $document.bind('click', closeMenu); } }); diff --git a/src/dropdownToggle/test/dropdownToggle.spec.js b/src/dropdownToggle/test/dropdownToggle.spec.js index 118458d..66cf32d 100644 --- a/src/dropdownToggle/test/dropdownToggle.spec.js +++ b/src/dropdownToggle/test/dropdownToggle.spec.js @@ -54,6 +54,12 @@ describe('dropdownToggle', function() { elm.click(); expect(targetElm.css('display')).toBe('none'); }); + + it('should not close on content elm click', function() { + targetElm.addClass('content'); + toggleElm.click(); + expect(targetElm.css('display')).toBe('block'); + }); it('should close on document click', function() { toggleElm.click(); From 606ca4ff03fb63a06752a5ccd8e7bc0c4b57b939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Phan=20H=E1=BA=A3i?= Date: Sun, 19 Oct 2014 10:33:41 +0700 Subject: [PATCH 15/17] fix(dropdownToggle): Check attribute instead of HTML class --- src/dropdownToggle/dropdownToggle.js | 2 +- src/dropdownToggle/test/dropdownToggle.spec.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dropdownToggle/dropdownToggle.js b/src/dropdownToggle/dropdownToggle.js index e7f5aea..fd3d7ea 100644 --- a/src/dropdownToggle/dropdownToggle.js +++ b/src/dropdownToggle/dropdownToggle.js @@ -93,7 +93,7 @@ angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.f openElement = null; }; - if (dropdown.hasClass('content')) { + if (dropdown.attr('show-on-click')) { dropdown.bind('click', function(evt) { evt.preventDefault(); evt.stopPropagation(); diff --git a/src/dropdownToggle/test/dropdownToggle.spec.js b/src/dropdownToggle/test/dropdownToggle.spec.js index 66cf32d..b57e2d8 100644 --- a/src/dropdownToggle/test/dropdownToggle.spec.js +++ b/src/dropdownToggle/test/dropdownToggle.spec.js @@ -55,8 +55,8 @@ describe('dropdownToggle', function() { expect(targetElm.css('display')).toBe('none'); }); - it('should not close on content elm click', function() { - targetElm.addClass('content'); + it('should not close on click if elm has show-on-click attribute', function() { + targetElm.attr('show-on-click', ''); toggleElm.click(); expect(targetElm.css('display')).toBe('block'); }); From ebfff42ab9466c4ad246fd831f5b503d48fc5045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Phan=20H=E1=BA=A3i?= Date: Sat, 8 Nov 2014 13:48:55 +0700 Subject: [PATCH 16/17] fix(dropdownToggle): Keep bubling event --- src/dropdownToggle/dropdownToggle.js | 48 +++++++++++++++++++--------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/dropdownToggle/dropdownToggle.js b/src/dropdownToggle/dropdownToggle.js index fd3d7ea..e1384c8 100644 --- a/src/dropdownToggle/dropdownToggle.js +++ b/src/dropdownToggle/dropdownToggle.js @@ -86,21 +86,39 @@ angular.module('mm.foundation.dropdownToggle', [ 'mm.foundation.position', 'mm.f .sync(); openElement = element; - closeMenu = function (event) { - $document.unbind('click', closeMenu); - dropdown.css('display', 'none'); - closeMenu = angular.noop; - openElement = null; - }; - - if (dropdown.attr('show-on-click')) { - dropdown.bind('click', function(evt) { - evt.preventDefault(); - evt.stopPropagation(); - }); - } - - $document.bind('click', closeMenu); + var shouldUnbind = true; + closeMenu = function (event) { + if (shouldUnbind) { + $document.unbind('click', closeMenu); + dropdown.css('display', 'none'); + closeMenu = angular.noop; + openElement = null; + } + shouldUnbind = true; + }; + + if (dropdown.attr('show-on-click')) { + dropdown.bind('click', function(evt) { + shouldUnbind = false; + dropdown.css('display', 'block'); + }); + } + + var closeButton = angular.element($document[0].querySelector('.close.button')); + closeButton.bind('click', function(e) { + shouldUnbind = true; + dropdown.unbind('click'); + closeMenu(); + }); + + var sendButton = angular.element($document[0].querySelector('.send.button')); + sendButton.bind('click', function(e) { + shouldUnbind = true; + dropdown.unbind('click'); + closeMenu(); + }); + + $document.bind('click', closeMenu); } }); From 413bd8562d867dc55e99ed99848210ad87f0f6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Phan=20H=E1=BA=A3i?= Date: Sat, 27 Dec 2014 06:10:59 +0700 Subject: [PATCH 17/17] fix(dropdownToggle): Duplicate code when handling click --- src/dropdownToggle/dropdownToggle.js | 29 ++++++++++------------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/dropdownToggle/dropdownToggle.js b/src/dropdownToggle/dropdownToggle.js index 9e592ee..161c1f4 100644 --- a/src/dropdownToggle/dropdownToggle.js +++ b/src/dropdownToggle/dropdownToggle.js @@ -92,18 +92,27 @@ angular.module('mm.foundation.dropdownToggle', ['mm.foundation.position', 'mm.fo }) .sync(); + if (parentHasDropdown()) { + parent.addClass('hover'); + } + openElement = element; var shouldUnbind = true; closeMenu = function(event) { if (shouldUnbind) { - $document.unbind('click', closeMenu); + $document.off('click', closeMenu); dropdown.css('display', 'none'); closeMenu = angular.noop; openElement = null; + if (parent.hasClass('hover')) { + parent.removeClass('hover'); + } } shouldUnbind = true; }; + $document.on('click', closeMenu); + if (dropdown.attr('show-on-click')) { dropdown.bind('click', function(evt) { shouldUnbind = false; @@ -124,24 +133,6 @@ angular.module('mm.foundation.dropdownToggle', ['mm.foundation.position', 'mm.fo dropdown.unbind('click'); closeMenu(); }); - - $document.bind('click', closeMenu); - if (parentHasDropdown()) { - parent.addClass('hover'); - } - - openElement = element; - - closeMenu = function(event) { - $document.off('click', closeMenu); - dropdown.css('display', 'none'); - closeMenu = angular.noop; - openElement = null; - if (parent.hasClass('hover')) { - parent.removeClass('hover'); - } - }; - $document.on('click', closeMenu); } };