diff --git a/dist/css/ionic.css b/dist/css/ionic.css index ef5a161aad..92bd4120b1 100644 --- a/dist/css/ionic.css +++ b/dist/css/ionic.css @@ -4,7 +4,7 @@ * -------------------------------------------------- * Useful utilities and mixins for SCSS files. */ -/*! +/* Ionicons, v1.3.3 Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ https://twitter.com/helloimben https://twitter.com/ionicframework @@ -2046,7 +2046,7 @@ sub { fieldset { margin: 0 2px; padding: 0.35em 0.625em 0.75em; - border: 1px solid #c0c0c0; } + border: 1px solid silver; } /** * 1. Correct `color` not being inherited in IE 8/9. @@ -2647,8 +2647,11 @@ a.subdued‎ { text-align: center; text-overflow: ellipsis; white-space: nowrap; + overflow: hidden; font-size: 18px; line-height: 44px; } + .bar .title.title-left { + text-align: left; } .bar .title a { color: inherit; } .bar .button { @@ -4136,7 +4139,7 @@ input[type="file"] { line-height: 34px; } select { - border: 1px solid #ccc; + border: 1px solid #cccccc; background-color: white; } select[multiple], @@ -4195,7 +4198,7 @@ input[type="checkbox"][readonly] { border-radius: 50%; background: white; content: ' '; - transition: background-color .1s ease-in-out; } + transition: background-color 0.1s ease-in-out; } /* the checkmark within the box */ .checkbox input:after { @@ -4210,7 +4213,7 @@ input[type="checkbox"][readonly] { border-right: 0; content: ' '; opacity: 0; - transition: opacity .05s ease-in-out; + transition: opacity 0.05s ease-in-out; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } @@ -4752,7 +4755,7 @@ input[type="range"] { .button-icon:active, .button-icon.active { background: none; box-shadow: none; - text-shadow: 0px 0px 10px #fff; } + text-shadow: 0px 0px 10px white; } .padding > .button.block:first-child { margin-top: 0; } diff --git a/dist/css/themes/ionic-ios7.css b/dist/css/themes/ionic-ios7.css index e119d59757..e027d9919a 100644 --- a/dist/css/themes/ionic-ios7.css +++ b/dist/css/themes/ionic-ios7.css @@ -1,3 +1,4 @@ +@charset "UTF-8"; /** * Mixins * -------------------------------------------------- @@ -123,7 +124,7 @@ right: 20px; transition: 0.2s ease; transition-property: left, right; - transition-delay: 0s, .05s; } + transition-delay: 0s, 0.05s; } .toggle :checked + .track { /* When the toggle is "on" */ @@ -138,4 +139,4 @@ right: 0; left: 20px; -webkit-transform: none; - transition-delay: .05s, 0s; } + transition-delay: 0.05s, 0s; } diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index 77d02e4549..ebb1889cba 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -16,6 +16,7 @@ angular.module('ionic.ui', [ 'ionic.ui.content', 'ionic.ui.tabs', 'ionic.ui.nav', + 'ionic.ui.header', 'ionic.ui.sideMenu', 'ionic.ui.list', 'ionic.ui.checkbox', @@ -584,6 +585,41 @@ angular.module('ionic.ui.content', []) })(); ; +(function(ionic) { +'use strict'; + +angular.module('ionic.ui.header', ['ngAnimate']) + + +.directive('headerBar', function() { + return { + restrict: 'E', + replace: true, + transclude: true, + template: '
', + scope: { + type: '@', + alignTitle: '@', + }, + link: function($scope, $element, $attr) { + var hb = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $scope.alignTitle || 'center' + }); + + $element.addClass($scope.type); + + $scope.headerBarView = hb; + + $scope.$on('$destroy', function() { + // + }); + } + }; +}); + +})(ionic); +; (function() { 'use strict'; @@ -773,6 +809,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges // Pop function, throttled this.popController = ionic.throttle(function() { _this.pop(); + $scope.$broadcast('navs.pop'); }, 300, { trailing: false }); @@ -820,6 +857,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges */ $scope.pushController = function(scope, element) { _this.push(scope); + $scope.$broadcast('navs.push', scope); }; $scope.navController = this; @@ -846,22 +884,46 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges restrict: 'E', require: '^navs', replace: true, - scope: true, + scope: { + type: '@', + backButtonType: '@', + alignTitle: '@' + }, template: '', - link: function(scope, element, attrs, navCtrl) { - scope.navController = navCtrl; + link: function($scope, $element, $attr, navCtrl) { + var backButton; - scope.barType = attrs.barType || 'bar-dark'; - element.addClass(scope.barType); + $scope.navController = navCtrl; - scope.$watch('navController.controllers.length', function(value) { - }); - scope.goBack = function() { + $scope.goBack = function() { navCtrl.popController(); }; + + + var hb = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $scope.alignTitle || 'center' + }); + + $element.addClass($scope.type); + + $scope.headerBarView = hb; + + $scope.$parent.$on('navs.push', function() { + backButton = angular.element($element[0].querySelector('.button')); + backButton.addClass($scope.backButtonType); + hb.align(); + }); + $scope.$parent.$on('navs.pop', function() { + hb.align(); + }); + + $scope.$on('$destroy', function() { + // + }); } }; }) diff --git a/dist/js/ionic.js b/dist/js/ionic.js index f5067571ea..c9a0cca61d 100644 --- a/dist/js/ionic.js +++ b/dist/js/ionic.js @@ -135,6 +135,29 @@ window.ionic = { ; (function(ionic) { ionic.DomUtil = { + getTextBounds: function(textNode) { + if(document.createRange) { + var range = document.createRange(); + range.selectNodeContents(textNode); + if(range.getBoundingClientRect) { + var rect = range.getBoundingClientRect(); + + var sx = window.scrollX; + var sy = window.scrollY; + + return { + top: rect.top + sy, + left: rect.left + sx, + right: rect.left + sx + rect.width, + bottom: rect.top + sy + rect.height, + width: rect.width, + height: rect.height + }; + } + } + return null + }, + getChildIndex: function(element) { return Array.prototype.slice.call(element.parentNode.children).indexOf(element); }, @@ -2844,22 +2867,95 @@ window.ionic = { initialize: function(opts) { this.el = opts.el; - this._titleEl = this.el.querySelector('.title'); + ionic.extend(this, { + alignTitle: 'center' + }, opts); + + this.align(); }, - resizeTitle: function() { - var e, j, i, - title, - titleWidth, - children = this.el.children; - for(i = 0, j = children.length; i < j; i++) { - e = children[i]; - if(/h\d/.test(e.nodeName.toLowerCase())) { - title = e; + /** + * Align the title text given the buttons in the header + * so that the header text size is maximized and aligned + * correctly as long as possible. + */ + align: function() { + var _this = this; + + window.rAF(ionic.proxy(function() { + var i, c, childSize, childStyle; + var children = this.el.children; + var childNodes = this.el.childNodes; + var styles = window.getComputedStyle(this.el, null); + + // Get the padding of the header for calculations + var paddingLeft = parseFloat(styles['paddingLeft']); + var paddingRight = parseFloat(styles['paddingRight']); + + // Get the full width of the header + var headerWidth = this.el.offsetWidth; + + // Find the title element + var title = this.el.querySelector('.title'); + if(!title) { + return; } - } + + var leftWidth = 0; + var rightWidth = 0; + var titlePos = Array.prototype.indexOf.call(this.el.childNodes, title); - titleWidth = title.offsetWidth; + // Compute how wide the left children are + for(i = 0; i < titlePos; i++) { + childSize = null; + c = childNodes[i]; + if(c.nodeType == 3) { + childSize = ionic.DomUtil.getTextBounds(c); + } else if(c.nodeType == 1) { + childSize = c.getBoundingClientRect(); + } + if(childSize) { + leftWidth += childSize.width; + } + } + + // Compute how wide the right children are + for(i = titlePos + 1; i < childNodes.length; i++) { + childSize = null; + c = childNodes[i]; + if(c.nodeType == 3) { + childSize = ionic.DomUtil.getTextBounds(c); + } else if(c.nodeType == 1) { + childSize = c.getBoundingClientRect(); + } + if(childSize) { + rightWidth += childSize.width; + } + } + + var margin = Math.max(leftWidth, rightWidth) + 10; + + // Size and align the header title based on the sizes of the left and + // right children, and the desired alignment mode + if(this.alignTitle == 'center') { + title.style.left = margin + 'px'; + title.style.right = margin + 'px'; + + console.log(title.offsetWidth, title.scrollWidth); + if(title.offsetWidth < title.scrollWidth) { + title.style.textAlign = 'left'; + title.style.right = (rightWidth + 5) + 'px'; + } else { + title.style.textAlign = 'center'; + } + } else if(this.alignTitle == 'left') { + title.style.textAlign = 'left'; + title.style.left = (leftWidth + 15) + 'px'; + } else if(this.alignTitle == 'right') { + title.style.textAlign = 'right'; + title.style.right = (rightWidth + 15) + 'px'; + } + }, this)); } }); diff --git a/js/ext/angular/src/directive/ionicHeader.js b/js/ext/angular/src/directive/ionicHeader.js new file mode 100644 index 0000000000..ef72aa721f --- /dev/null +++ b/js/ext/angular/src/directive/ionicHeader.js @@ -0,0 +1,34 @@ +(function(ionic) { +'use strict'; + +angular.module('ionic.ui.header', ['ngAnimate']) + + +.directive('headerBar', function() { + return { + restrict: 'E', + replace: true, + transclude: true, + template: '
', + scope: { + type: '@', + alignTitle: '@', + }, + link: function($scope, $element, $attr) { + var hb = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $scope.alignTitle || 'center' + }); + + $element.addClass($scope.type); + + $scope.headerBarView = hb; + + $scope.$on('$destroy', function() { + // + }); + } + }; +}); + +})(ionic); diff --git a/js/ext/angular/src/directive/ionicNav.js b/js/ext/angular/src/directive/ionicNav.js index c588d4f77c..efab4025d7 100644 --- a/js/ext/angular/src/directive/ionicNav.js +++ b/js/ext/angular/src/directive/ionicNav.js @@ -32,6 +32,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges // Pop function, throttled this.popController = ionic.throttle(function() { _this.pop(); + $scope.$broadcast('navs.pop'); }, 300, { trailing: false }); @@ -79,6 +80,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges */ $scope.pushController = function(scope, element) { _this.push(scope); + $scope.$broadcast('navs.push', scope); }; $scope.navController = this; @@ -105,22 +107,46 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges restrict: 'E', require: '^navs', replace: true, - scope: true, + scope: { + type: '@', + backButtonType: '@', + alignTitle: '@' + }, template: '', - link: function(scope, element, attrs, navCtrl) { - scope.navController = navCtrl; + link: function($scope, $element, $attr, navCtrl) { + var backButton; - scope.barType = attrs.barType || 'bar-dark'; - element.addClass(scope.barType); + $scope.navController = navCtrl; - scope.$watch('navController.controllers.length', function(value) { - }); - scope.goBack = function() { + $scope.goBack = function() { navCtrl.popController(); }; + + + var hb = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $scope.alignTitle || 'center' + }); + + $element.addClass($scope.type); + + $scope.headerBarView = hb; + + $scope.$parent.$on('navs.push', function() { + backButton = angular.element($element[0].querySelector('.button')); + backButton.addClass($scope.backButtonType); + hb.align(); + }); + $scope.$parent.$on('navs.pop', function() { + hb.align(); + }); + + $scope.$on('$destroy', function() { + // + }); } }; }) diff --git a/js/ext/angular/src/ionicAngular.js b/js/ext/angular/src/ionicAngular.js index 98a56c8fd9..0a3f1360d3 100644 --- a/js/ext/angular/src/ionicAngular.js +++ b/js/ext/angular/src/ionicAngular.js @@ -16,6 +16,7 @@ angular.module('ionic.ui', [ 'ionic.ui.content', 'ionic.ui.tabs', 'ionic.ui.nav', + 'ionic.ui.header', 'ionic.ui.sideMenu', 'ionic.ui.list', 'ionic.ui.checkbox', diff --git a/js/ext/angular/test/header.html b/js/ext/angular/test/header.html new file mode 100644 index 0000000000..36b105b4ed --- /dev/null +++ b/js/ext/angular/test/header.html @@ -0,0 +1,40 @@ + + + + Header + + + + + + + + + + + +

A really really long title here here here here her

+
+ + + + + diff --git a/js/ext/angular/test/nav.html b/js/ext/angular/test/nav.html index 2be7571a69..0f4f4c0a0c 100644 --- a/js/ext/angular/test/nav.html +++ b/js/ext/angular/test/nav.html @@ -32,16 +32,17 @@ - + + -
- - -
+
+ + +