reverts tabs back to use only bootstrap tabs (we can change that at a later date now that we have the code), have fixed up a lot of the detect-fold logic so that it doesn't run an insane amount of calculations, however now we need to properly fix the bootstrap tab event bindings.
This commit is contained in:
@@ -23,7 +23,6 @@ angular.module("umbraco.directives")
|
||||
|
||||
|
||||
//I hate bootstrap tabs
|
||||
//TODO: This is legacy since we aren't using bootstrap tabs anymore
|
||||
$('a[data-toggle="tab"]').on('shown', update);
|
||||
|
||||
scope.$on('$destroy', function() {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:umbEditorButtons
|
||||
* @restrict E
|
||||
* @function
|
||||
* @description
|
||||
* The button holder for editors (i.e. save, update, etc...)
|
||||
**/
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbEditorButtons', function () {
|
||||
return {
|
||||
require: "^umbTabs",
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
template: '<div class="umb-tab-buttons" detect-fold ng-class="{\'umb-dimmed\': busy}" ng-transclude></div>',
|
||||
link: function(scope, element, attrs, ngModel) {
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:umbTabs
|
||||
* @restrict E
|
||||
* @function
|
||||
* @description
|
||||
* Used to control tab changes in editors, this directive must be placed around any editors' tabs (including header tabs and body tabs)
|
||||
**/
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbTabs', function() {
|
||||
return {
|
||||
//uses a controller to expose an API
|
||||
controller: function ($scope, $attrs, $element, $parse) {
|
||||
|
||||
//NOTE: This whole $parse strategy is the same type of thing used by ngModel, we need to use it
|
||||
// because angular 1.1.5 is stupid. Normally we could just make a scope with =umbTags but that doesn't
|
||||
// work for attribute type directives, seems to only work for element directives and I don't want this to
|
||||
// be an element directive.... so we're using this.
|
||||
var tabsValueGet = $parse($attrs.umbTabs);
|
||||
|
||||
//internal props
|
||||
|
||||
var activeTabId = null;
|
||||
var tabCollectionChangedCallbacks = [];
|
||||
var activeTabChangedCallbacks = [];
|
||||
var firstRun = false;
|
||||
var tabs = [];
|
||||
|
||||
//public props/methods
|
||||
|
||||
this.getActiveTab = function() {
|
||||
return activeTabId;
|
||||
};
|
||||
this.setActiveTab = function(tabId) {
|
||||
activeTabId = tabId;
|
||||
for (var callback in activeTabChangedCallbacks) {
|
||||
activeTabChangedCallbacks[callback](activeTabId);
|
||||
}
|
||||
};
|
||||
this.onTabCollectionChanged = function (callback) {
|
||||
tabCollectionChangedCallbacks.push(callback);
|
||||
};
|
||||
this.onActiveTabChanged = function (callback) {
|
||||
activeTabChangedCallbacks.push(callback);
|
||||
};
|
||||
|
||||
$scope.$watch(function() {
|
||||
return tabsValueGet($scope);
|
||||
}, function (newValue, oldValue) {
|
||||
if ((angular.isArray(newValue) && angular.isArray(oldValue) && newValue.length !== oldValue.length|| (newValue !== undefined && oldValue === undefined))) {
|
||||
|
||||
tabs = []; //reset first
|
||||
for (var val in newValue) {
|
||||
var tab = { id: newValue[val].id, label: newValue[val].label };
|
||||
tabs.push(tab);
|
||||
}
|
||||
|
||||
//set active tab to the first one - one time
|
||||
if (firstRun === false) {
|
||||
firstRun = true;
|
||||
if (tabs.length > 0) {
|
||||
activeTabId = tabs[0].id;
|
||||
for (var activeTabCallback in activeTabChangedCallbacks) {
|
||||
activeTabChangedCallbacks[activeTabCallback](activeTabId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var callback in tabCollectionChangedCallbacks) {
|
||||
tabCollectionChangedCallbacks[callback](tabs);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
tabCollectionChangedCallbacks = [];
|
||||
activeTabChangedCallbacks = [];
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -3,7 +3,6 @@
|
||||
* @name umbraco.directives.directive:umbHeader
|
||||
* @restrict E
|
||||
* @function
|
||||
* @deprecated since version 7.3 - use umbTabHeader instead
|
||||
* @description
|
||||
* The header on an editor that contains tabs using bootstrap tabs - THIS IS OBSOLETE, use umbTabHeader instead
|
||||
**/
|
||||
|
||||
@@ -6,44 +6,9 @@
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbTab', function ($parse, $timeout) {
|
||||
return {
|
||||
require: "?^umbTabs",
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
scope: {
|
||||
id : "@",
|
||||
tabId : "@rel"
|
||||
},
|
||||
replace: true,
|
||||
transclude: 'true',
|
||||
templateUrl: 'views/directives/umb-tab.html',
|
||||
link: function(scope, elem, attrs, tabsCtrl) {
|
||||
|
||||
function toggleVisibility(tabId) {
|
||||
//default if there are no tabs
|
||||
if (tabId === null) {
|
||||
elem.addClass("active");
|
||||
}
|
||||
else {
|
||||
if (scope.tabId === String(tabId)) {
|
||||
elem.addClass("active");
|
||||
}
|
||||
else {
|
||||
elem.removeClass("active");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//need to make this optional for backwards compat since before we used to
|
||||
// use bootstrap tabs and now we use our own better implementation which
|
||||
// gives us far more control but will still support the old way.
|
||||
if (tabsCtrl) {
|
||||
|
||||
tabsCtrl.onActiveTabChanged(function (tabId) {
|
||||
toggleVisibility(tabId);
|
||||
});
|
||||
|
||||
toggleVisibility(tabsCtrl.getActiveTab());
|
||||
|
||||
}
|
||||
}
|
||||
templateUrl: 'views/directives/umb-tab.html'
|
||||
};
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name umbraco.directives.directive:umbTabHeader
|
||||
* @restrict E
|
||||
* @function
|
||||
* @description
|
||||
* The header on an editor that contains tabs
|
||||
**/
|
||||
angular.module("umbraco.directives").directive('umbTabHeader', function($parse, $timeout) {
|
||||
return {
|
||||
require: "?^umbTabs",
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: 'true',
|
||||
templateUrl: 'views/directives/umb-tab-header.html',
|
||||
link: function(scope, iElement, iAttrs, tabsCtrl) {
|
||||
|
||||
scope.showTabs = false;
|
||||
scope.activeTabId = null;
|
||||
scope.tabs = [];
|
||||
|
||||
if (tabsCtrl) {
|
||||
tabsCtrl.onTabCollectionChanged(function (tabs) {
|
||||
scope.tabs = tabs;
|
||||
scope.showTabs = scope.tabs.length > 0;
|
||||
});
|
||||
|
||||
tabsCtrl.onActiveTabChanged(function (tabId) {
|
||||
scope.activeTabId = tabId;
|
||||
});
|
||||
|
||||
scope.changeTab = function (tabId) {
|
||||
tabsCtrl.setActiveTab(tabId);
|
||||
};
|
||||
|
||||
//TODO: We'll need to destroy this I'm assuming!
|
||||
iElement.find('.nav-pills, .nav-tabs').tabdrop();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -5,31 +5,10 @@
|
||||
**/
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbTabView', function($timeout, $log){
|
||||
return {
|
||||
require: "?^umbTabs",
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: 'true',
|
||||
templateUrl: 'views/directives/umb-tab-view.html',
|
||||
compile: function () {
|
||||
return {
|
||||
pre: function (scope, iElement, iAttrs, tabsCtrl) {
|
||||
//if we have our custom tab directive it means we are not using bootstrap
|
||||
// tabs, however if there isn't a directive we'll continue using bootsrap tabs
|
||||
// this is done by adding 'tab-content' class for bootstrap or 'umb-tab-content'
|
||||
// for our custom tabs.
|
||||
|
||||
//We also MUST do this on pre-linking because the tab-content class needs to be there
|
||||
// before it hits the DOM so that bootstrap can do whatever it is that it does.
|
||||
|
||||
if (tabsCtrl) {
|
||||
iElement.children("div:first").addClass("umb-tab-content");
|
||||
}
|
||||
else {
|
||||
iElement.children("div:first").addClass("tab-content");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
templateUrl: 'views/directives/umb-tab-view.html'
|
||||
};
|
||||
});
|
||||
@@ -7,15 +7,25 @@
|
||||
angular.module("umbraco.directives.html")
|
||||
.directive('detectFold', function ($timeout, $log, windowResizeListener) {
|
||||
return {
|
||||
require: "^?umbTabs",
|
||||
restrict: 'A',
|
||||
link: function (scope, el, attrs) {
|
||||
|
||||
var state = false;
|
||||
var firstRun = false;
|
||||
var parent = $(".umb-panel-body");
|
||||
var winHeight = $(window).height();
|
||||
var calculate = function() {
|
||||
var calculate = function () {
|
||||
|
||||
console.log("calculating...");
|
||||
|
||||
if (el && el.is(":visible") && !el.hasClass("umb-bottom-bar")) {
|
||||
|
||||
//now that the element is visible, set the flag in a couple of seconds,
|
||||
// this will ensure that loading time of a current tab get's completed and that
|
||||
// we eventually stop watching to save on CPU time
|
||||
$timeout(function() {
|
||||
firstRun = true;
|
||||
}, 4000);
|
||||
|
||||
//var parent = el.parent();
|
||||
var hasOverflow = parent.innerHeight() < parent[0].scrollHeight;
|
||||
//var belowFold = (el.offset().top + el.height()) > winHeight;
|
||||
@@ -23,21 +33,42 @@ angular.module("umbraco.directives.html")
|
||||
el.addClass("umb-bottom-bar");
|
||||
}
|
||||
}
|
||||
return firstRun;
|
||||
};
|
||||
|
||||
var resizeCallback = function(size) {
|
||||
winHeight = size.height;
|
||||
el.removeClass("umb-bottom-bar");
|
||||
//state = false;
|
||||
calculate();
|
||||
};
|
||||
|
||||
windowResizeListener.register(resizeCallback);
|
||||
|
||||
//Only execute the watcher if this tab is the active (first) tab on load, otherwise there's no reason to execute
|
||||
// the watcher since it will be recalculated when the tab changes!
|
||||
if (el.closest(".umb-tab-pane").index() === 0) {
|
||||
//run a watcher to ensure that the calculation occurs until it's firstRun but ensure
|
||||
// the calculations are throttled to save a bit of CPU
|
||||
var listener = scope.$watch(_.throttle(calculate, 1000), function (newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
//cancel the watch
|
||||
console.log("WATCH CANCEL");
|
||||
listener();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//Required for backwards compat for bootstrap tabs
|
||||
$('a[data-toggle="tab"]').on('shown', calculate);
|
||||
|
||||
$('.nav-tabs a').on('shown', function (event) {
|
||||
console.log("TAB SHOWN 1");
|
||||
});
|
||||
|
||||
$('.nav-tabs a').on('shown.bs.tab', function (event) {
|
||||
console.log("TAB SHOWN");
|
||||
});
|
||||
|
||||
//ensure to unregister
|
||||
scope.$on('$destroy', function() {
|
||||
windowResizeListener.unregister(resizeCallback);
|
||||
|
||||
@@ -36,11 +36,9 @@ function windowResizeListener($rootScope) {
|
||||
}
|
||||
},
|
||||
unregister: function (fn) {
|
||||
for (var i = 0, cnt = registered.length; i < cnt; i++) {
|
||||
if (registered[i] === fn) {
|
||||
delete registered[i];
|
||||
break;
|
||||
}
|
||||
var index = registered.indexOf(fn);
|
||||
if (index > -1) {
|
||||
registered.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -330,8 +330,7 @@
|
||||
.tabbable {
|
||||
.clearfix();
|
||||
}
|
||||
.tab-content,
|
||||
.umb-tab-content {
|
||||
.tab-content {
|
||||
overflow: auto; // prevent content from running below tabs
|
||||
}
|
||||
|
||||
@@ -344,13 +343,11 @@
|
||||
|
||||
// Show/hide tabbable areas
|
||||
.tab-content > .tab-pane,
|
||||
.pill-content > .pill-pane,
|
||||
.umb-tab-content > .tab-pane {
|
||||
.pill-content > .pill-pane {
|
||||
display: none;
|
||||
}
|
||||
.tab-content > .active,
|
||||
.pill-content > .active,
|
||||
.umb-tab-content > .active {
|
||||
.pill-content > .active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<form ng-controller="Umbraco.DashboardController" class="umb-dashboard" val-form-manager>
|
||||
<umb-panel umb-tabs="dashboard.tabs">
|
||||
<umb-tab-header>
|
||||
<umb-panel>
|
||||
<umb-header tabs="dashboard.tabs">
|
||||
<div class="umb-headline-editor-wrapper span12">
|
||||
<h1>{{dashboard.name}}</h1>
|
||||
</div>
|
||||
</umb-tab-header>
|
||||
</umb-header>
|
||||
<umb-tab-view>
|
||||
<umb-tab id="tab{{tab.id}}" rel="{{tab.id}}" ng-repeat="tab in dashboard.tabs">
|
||||
<div class="umb-pane">
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
ng-submit="save()"
|
||||
val-form-manager>
|
||||
|
||||
<umb-panel umb-tabs="content.tabs" ng-class="{'editor-breadcrumb': ancestors && ancestors.length > 0}">
|
||||
<umb-tab-header>
|
||||
<umb-panel ng-class="{'editor-breadcrumb': ancestors && ancestors.length > 0}">
|
||||
<umb-header tabs="content.tabs">
|
||||
|
||||
<div class="span7">
|
||||
<umb-content-name placeholder="@placeholders_entername"
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
<umb-options-menu ng-show="currentNode"
|
||||
current-node="currentNode"
|
||||
current-section="{{currentSection}}">
|
||||
current-section="{{currentSection}}">
|
||||
</umb-options-menu>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</umb-tab-header>
|
||||
</umb-header>
|
||||
|
||||
<umb-tab-view>
|
||||
<umb-tab id="tab{{tab.id}}" rel="{{tab.id}}" ng-repeat="tab in content.tabs">
|
||||
@@ -34,8 +34,9 @@
|
||||
ng-repeat="property in tab.properties">
|
||||
<umb-editor model="property"></umb-editor>
|
||||
</umb-property>
|
||||
|
||||
<umb-editor-buttons>
|
||||
|
||||
|
||||
<div class="umb-tab-buttons" detect-fold ng-class="{'umb-dimmed': busy}">
|
||||
|
||||
<div class="btn-group" ng-show="listViewPath">
|
||||
<a class="btn" href="#{{listViewPath}}">
|
||||
@@ -71,13 +72,12 @@
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</umb-editor-buttons>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</umb-tab>
|
||||
</umb-tab-view>
|
||||
|
||||
|
||||
<ul class="umb-panel-footer-nav nav nav-pills" ng-if="ancestors && ancestors.length > 0">
|
||||
<li ng-repeat="ancestor in ancestors">
|
||||
<a href="#/content/content/edit/{{ancestor.id}}">{{ancestor.name}}</a>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<umb-panel ng-controller="Umbraco.Editors.Content.RecycleBinController" umb-tabs>
|
||||
<umb-tab-header>
|
||||
<umb-panel ng-controller="Umbraco.Editors.Content.RecycleBinController">
|
||||
<umb-header>
|
||||
<div class="umb-headline-editor-wrapper span12">
|
||||
<h1><localize key="general_recycleBin">Recycle Bin</localize></h1>
|
||||
</div>
|
||||
</umb-tab-header>
|
||||
</umb-header>
|
||||
<umb-tab-view>
|
||||
<umb-tab id="tabRecycleBin" rel="RecycleBin">
|
||||
<umb-pane>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
val-form-manager>
|
||||
<umb-panel>
|
||||
|
||||
<umb-tab-header>
|
||||
<umb-header>
|
||||
|
||||
<div class="span7">
|
||||
<umb-content-name
|
||||
@@ -22,7 +22,7 @@
|
||||
</umb-options-menu>
|
||||
</div>
|
||||
</div>
|
||||
</umb-tab-header>
|
||||
</umb-header>
|
||||
|
||||
<div class="umb-panel-body umb-scrollable row-fluid">
|
||||
<div class="tab-content form-horizontal" style="padding-bottom: 90px">
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<div class="umb-panel-header">
|
||||
<div class="row-fluid">
|
||||
|
||||
<div ng-transclude></div>
|
||||
|
||||
<ul ng-show="showTabs" class="nav nav-tabs umb-nav-tabs span12">
|
||||
|
||||
<li ng-class="{active: activeTabId == tab.id, 'tab-error': tabHasError}" ng-repeat="tab in tabs" val-tab>
|
||||
<a href="#tab{{tab.id}}" ng-click="changeTab(tab.id)" prevent-default>{{ tab.label }}</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="umb-panel-body umb-scrollable row-fluid">
|
||||
<div class="form-horizontal" ng-transclude>
|
||||
<div class="tab-content form-horizontal" ng-transclude>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
ng-show="loaded"
|
||||
ng-submit="save()"
|
||||
val-form-manager>
|
||||
<umb-panel umb-tabs="content.tabs" ng-class="{'editor-breadcrumb': ancestors && ancestors.length > 0}">
|
||||
<umb-tab-header>
|
||||
<umb-panel ng-class="{'editor-breadcrumb': ancestors && ancestors.length > 0}">
|
||||
<umb-header tabs="content.tabs">
|
||||
|
||||
<div class="span7">
|
||||
<umb-content-name placeholder="@placeholders_entername"
|
||||
@@ -23,7 +23,7 @@
|
||||
</umb-options-menu>
|
||||
</div>
|
||||
</div>
|
||||
</umb-tab-header>
|
||||
</umb-header>
|
||||
|
||||
<umb-tab-view>
|
||||
<umb-tab id="tab{{tab.id}}" rel="{{tab.id}}" ng-repeat="tab in content.tabs">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<umb-panel ng-controller="Umbraco.Editors.Media.RecycleBinController" umb-tabs>
|
||||
<umb-tab-header>
|
||||
<umb-panel ng-controller="Umbraco.Editors.Media.RecycleBinController">
|
||||
<umb-header>
|
||||
<div class="umb-headline-editor-wrapper span12">
|
||||
<h1><localize key="general_recycleBin">Recycle Bin</localize></h1>
|
||||
</div>
|
||||
</umb-tab-header>
|
||||
</umb-header>
|
||||
<umb-tab-view>
|
||||
<umb-tab id="tabRecycleBin" rel="RecycleBin">
|
||||
<umb-pane>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
ng-show="loaded"
|
||||
ng-submit="save()"
|
||||
val-form-manager>
|
||||
<umb-panel umb-tabs="content.tabs">
|
||||
<umb-tab-header>
|
||||
<umb-panel>
|
||||
<umb-header tabs="content.tabs">
|
||||
|
||||
<div class="span7" ng-if="content.membershipScenario == 0">
|
||||
<umb-content-name
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</umb-tab-header>
|
||||
</umb-header>
|
||||
|
||||
<umb-tab-view>
|
||||
<umb-tab id="tab{{tab.id}}" rel="{{tab.id}}" ng-repeat="tab in content.tabs">
|
||||
|
||||
Reference in New Issue
Block a user