diff --git a/Rakefile b/Rakefile
index 72821117a6cab0795f899be4d288771a0433a447..fc185438b81d55810ce9583f08a2faee8fc0f229 100644
--- a/Rakefile
+++ b/Rakefile
@@ -60,7 +60,7 @@ desc "Run JSDuck on ExtJS SDK"
task :sdk do
load_sdk_vars
run_jsduck([
- "--extjs-path", "extjs/ext-all.js",
+ "--extjs-path", "extjs/ext-all-debug.js",
# to create symbolic links to template files instead of copying them over.
# Useful for development. Turn off for deployment.
"--template-links",
diff --git a/template/app/Application.js b/template/app/Application.js
index 12579613457797295eb9e7035a9e13e678aaaa27..63d0458829f2d5c70222299a8063c334cad8b37c 100644
--- a/template/app/Application.js
+++ b/template/app/Application.js
@@ -46,7 +46,7 @@ Ext.define('Docs.Application', {
// setInterval(function(){
// Ext.DomQuery.select('link')[4].href = "resources/css/viewport.css?" + Math.ceil(Math.random() * 100000000)
- // }, 1000)
+ // }, 1000);
}
});
diff --git a/template/app/controller/Tabs.js b/template/app/controller/Tabs.js
index 56feeee6612a5e88c86d05f2e3c80445a3baa44e..18082bd3c29caffa0968029db725d564e57f0e50 100644
--- a/template/app/controller/Tabs.js
+++ b/template/app/controller/Tabs.js
@@ -65,6 +65,15 @@ Ext.define('Docs.controller.Tabs', {
// }, this);
// }
},
+ resize: function() {
+ Ext.getCmp('doctabs').resizeTabs();
+ },
+ scope: this
+ },
+ '#tabOverflowMenu menuitem': {
+ click: function(cmp) {
+ this.activateTab(cmp.href, true);
+ },
scope: this
}
});
@@ -110,6 +119,7 @@ Ext.define('Docs.controller.Tabs', {
Ext.getCmp('doctabs').activateTab(next);
Docs.History.push(next);
}
+ docTab.dom.removed = true;
docTab.animate({
to: { top: 30 }
}).animate({
@@ -138,8 +148,7 @@ Ext.define('Docs.controller.Tabs', {
return;
}
var url = Ext.get(el).down('.tabUrl').getAttribute('href');
- Ext.getCmp('doctabs').activateTab(url);
- Docs.History.push(url);
+ this.activateTab(url);
}, this, {
delegate: '.doctab'
});
@@ -148,6 +157,11 @@ Ext.define('Docs.controller.Tabs', {
delegate: '.tabUrl',
preventDefault: true
});
+ },
+
+ activateTab: function(url, activateOverview) {
+ Ext.getCmp('doctabs').activateTab(url, activateOverview);
+ Docs.History.push(url);
}
});
diff --git a/template/app/view/Tabs.js b/template/app/view/Tabs.js
index 0a86f65ecca53646b38a740306f4f4fcf9bbf720..05ee0fb0b94c09774a99f162087b40cb251fc4ff 100644
--- a/template/app/view/Tabs.js
+++ b/template/app/view/Tabs.js
@@ -10,6 +10,11 @@ Ext.define('Docs.view.Tabs', {
componentCls: 'doctabs',
openTabs: [],
+ tabBarTabs: [],
+ overflowTabs: [],
+
+ tabWidth: 140,
+ minTabWidth: 80,
initComponent: function() {
var tpl = new Ext.XTemplate(
@@ -20,7 +25,8 @@ Ext.define('Docs.view.Tabs', {
'
',
'',
'',
- '
'
+ '
',
+ ''
);
this.html = tpl.applyTemplate([
@@ -34,6 +40,20 @@ Ext.define('Docs.view.Tabs', {
this.callParent();
},
+ listeners: {
+ afterrender: function() {
+ Ext.create('Ext.button.Button', {
+ baseCls: null,
+ renderTo: 'tabOverflow',
+ menu: {
+ id: 'tabOverflowMenu',
+ plain: true,
+ items: []
+ }
+ });
+ }
+ },
+
tabQueue: [],
/**
@@ -48,66 +68,134 @@ Ext.define('Docs.view.Tabs', {
* @param {Boolean} opts.activate True to activate the tab
*/
addTab: function(tab, opts) {
+
+ // If there is room add tab
+ // If no room, move last tab to overflow menu and update with current tab
+
if (!Ext.Array.contains(this.openTabs, tab.href)) {
- var tpl = Ext.create('Ext.XTemplate',
- ''
- );
- var docTab = Ext.get(tpl.append(this.el.dom, tab));
- docTab.dom.initialWidth = docTab.getWidth();
-
- if (opts.animate) {
- // Effect to 'slide' the tab out when it is created.
- docTab.setStyle('width', '10px');
- docTab.setStyle({ visibility: 'visible' });
- docTab.animate({
- to: { width: docTab.dom.initialWidth }
- });
- }
- else {
- docTab.setStyle({ visibility: 'visible' });
- }
this.openTabs.push(tab.href);
Docs.Settings.set('openTabs', this.openTabs);
+
+ if (this.overflowing()) {
+ Ext.get('tabOverflow').show();
+ } else {
+ this.addTabToBar(tab, opts);
+ }
+
+ Ext.getCmp('tabOverflowMenu').add({
+ text: tab.text,
+ iconCls: tab.iconCls,
+ origIcon: tab.iconCls,
+ href: tab.href,
+ cls: 'x-menu-item-checked' + (this.overflowing() ? ' overflow' : '')
+ });
}
if (opts.activate) {
this.activateTab(tab.href);
}
- this.recalculateWidths();
+ this.resizeTabs();
+ },
+
+ addTabToBar: function(tab, opts) {
+
+ this.tabBarTabs.push(tab.url);
+
+ var tpl = Ext.create('Ext.XTemplate',
+ ''
+ );
+ var docTab = Ext.get(tpl.append(this.el.dom, tab));
+
+ if (opts.animate) {
+ // Effect to 'slide' the tab out when it is created.
+ docTab.setStyle('width', '10px');
+ docTab.setStyle({ visibility: 'visible' });
+ docTab.animate({
+ to: { width: this.tabWidth - this.tabDelta() }
+ });
+ }
+ else {
+ docTab.setStyle({ visibility: 'visible' });
+ }
+ },
+
+ /**
+ * Returns the width of the Tab Bar
+ * @return {Number} Tab bar width
+ */
+ tabBarWidth: function() {
+ return Ext.getCmp('doctabs').getWidth() - 240;
+ },
+
+ /**
+ * Returns the cumulative width of all visible tabs
+ * @return {Number} Tabs width
+ */
+ totalTabsWidth: function() {
+ return this.openTabs.length * this.tabWidth;
+ },
+
+ /**
+ * Returns the cumulative width of all visible tabs
+ * @return {Number} Tabs width
+ */
+ minTabsWidth: function() {
+ return this.openTabs.length * this.minTabWidth;
+ },
+
+ maxVisibleTabs: function() {
+ return Math.ceil(this.tabBarWidth() / this.minTabWidth);
+ },
+
+ /**
+ * Returns the width delta to be applied to each tab for them to fit within the tab bar
+ * @return {Number} Number of pixels
+ */
+ tabDelta: function() {
+
+ var numTabs = this.maxVisibleTabs();
+ if (this.openTabs.length < numTabs) numTabs = this.openTabs.length;
+
+ var delta = Math.ceil((this.totalTabsWidth() - this.tabBarWidth()) / this.openTabs.length);
+ return (delta < 0) ? 0 : delta;
+ },
+
+ /**
+ * Returns true if the tab bar is overflowing
+ */
+ overflowing: function() {
+ return ((this.openTabs.length - 1) * this.minTabWidth) > this.tabBarWidth();
},
- recalculateWidths: function() {
+ /**
+ * Resizes the tabs
+ */
+ resizeTabs: function() {
- var maxWidth = Ext.getCmp('doctabs').getWidth() - 240;
- var numTabs = Ext.query('.doctab').length - 5;
+ clearTimeout(this.resizeTabsTimer);
- var tabsWidth = Ext.Array.sum(Ext.Array.map(Ext.query('.doctab'), function(t){
- var docTab = Ext.get(t);
- return docTab.dom.initialWidth - 5 || 0;
- }));
+ if (this.totalTabsWidth() > this.tabBarWidth()) {
- if (tabsWidth > maxWidth) {
- var tabDelta = Math.ceil((tabsWidth - maxWidth) / numTabs);
+ var tabDelta = this.tabDelta();
Ext.Array.each(Ext.query('.doctab'), function(t){
var docTab = Ext.get(t);
- if (!docTab.hasCls('overview')) {
- var width = docTab.dom.initialWidth;
- var newWidth = (width - tabDelta) > 60 ? (width - tabDelta) : 60;
+ if (!docTab.dom.removed && !docTab.hasCls('overview')) {
+ var newWidth = (this.tabWidth - tabDelta) > this.minTabWidth ? (this.tabWidth - tabDelta) : this.minTabWidth;
docTab.animate({
to: { width: newWidth }
});
}
- });
+ }, this);
}
},
@@ -116,7 +204,7 @@ Ext.define('Docs.view.Tabs', {
*
* @param {String} url URL of the tab to activate
*/
- activateTab: function(url) {
+ activateTab: function(url, activateOverview) {
this.activeTab = Ext.Array.indexOf(this.openTabs, url);
Ext.Array.each(Ext.query('.doctab a[class=tabUrl]'), function(d) {
Ext.get(d).up('.doctab').removeCls(['active', 'highlight']);
@@ -126,12 +214,19 @@ Ext.define('Docs.view.Tabs', {
var docTab = Ext.get(activeTab).up('.doctab');
docTab.addCls('active');
if (!docTab.hasCls('overview')) {
- var overviewTab = Ext.query('.doctab.' + this.getControllerName(url).toLowerCase());
- if (overviewTab && overviewTab[0]) {
- Ext.get(overviewTab[0]).addCls('highlight');
- }
+ activateOverview = true;
}
}
+ if (activateOverview) {
+ var overviewTab = Ext.query('.doctab.' + this.getControllerName(url).toLowerCase());
+ if (overviewTab && overviewTab[0]) {
+ Ext.get(overviewTab[0]).addCls('highlight');
+ }
+ }
+
+ Ext.Array.each(Ext.ComponentQuery.query('#tabOverflowMenu menuitem'), function(menuItem) {
+ menuItem.setIconCls(menuItem.href == url ? undefined : menuItem.origIcon);
+ });
},
/**
@@ -149,7 +244,21 @@ Ext.define('Docs.view.Tabs', {
if (this.activeTab > idx) {
this.activeTab -= 1;
}
+
+ Ext.Array.each(Ext.ComponentQuery.query('#tabOverflowMenu menuitem[href=' + url + ']'), function(menuItem) {
+ Ext.getCmp('tabOverflowMenu').remove(menuItem);
+ });
+ }
+
+ if (this.resizeTabsTimer) {
+ clearTimeout(this.resizeTabsTimer);
}
+
+ var self = this;
+ this.resizeTabsTimer = setTimeout(function(){
+ self.resizeTabs();
+ }, 1000);
+
if (idx === this.activeTab) {
if (this.openTabs.length === 0) {
Docs.App.getController(this.getControllerName(url)).loadIndex();
@@ -183,14 +292,3 @@ Ext.define('Docs.view.Tabs', {
}
}
});
-
-
-
-// Ext.Array.each(Ext.query('.doctab'), function(t){
-// var docTab = Ext.get(t);
-// if (!docTab.hasCls('overview')) {
-// docTab.animate({
-// to: { width: 60 }
-// });
-// }
-// });
diff --git a/template/app/view/cls/Header.js b/template/app/view/cls/Header.js
index 89eccf83983703021b83872a095282fe14627a9b..7f3f3900c8964705700337ab2a7fa35926c35d60 100644
--- a/template/app/view/cls/Header.js
+++ b/template/app/view/cls/Header.js
@@ -8,6 +8,7 @@ Ext.define('Docs.view.cls.Header', {
// will not be correct if not set explicitly
height: 55,
alias: 'widget.classheader',
+ cls: 'classheader',
initComponent: function() {
this.tpl = Ext.create('Ext.XTemplate',
@@ -20,6 +21,7 @@ Ext.define('Docs.view.cls.Header', {
'xtype: {[values.xtypes.join(", ")]}',
'',
'',
+ 'Print',
{
getClass: function(cls) {
if (cls.component) {
diff --git a/template/resources/images/print.png b/template/resources/images/print.png
new file mode 100644
index 0000000000000000000000000000000000000000..f19d9a607903b3683c314144720827c3c63a7691
Binary files /dev/null and b/template/resources/images/print.png differ
diff --git a/template/resources/images/tab-overflow.png b/template/resources/images/tab-overflow.png
new file mode 100644
index 0000000000000000000000000000000000000000..eec3d544d6827b827cb1339259fc834eadcf0d77
Binary files /dev/null and b/template/resources/images/tab-overflow.png differ
diff --git a/template/resources/sass/viewport.scss b/template/resources/sass/viewport.scss
index 12a3a823644077f3e6612301807171d341b7f467..91ab2b120cedf8b517168c233a92089af1f02a57 100644
--- a/template/resources/sass/viewport.scss
+++ b/template/resources/sass/viewport.scss
@@ -284,6 +284,16 @@ a {
color: #e7ba27;
letter-spacing: 0px; } }
+ .classheader .print {
+ background: url(../images/print.png) no-repeat;
+ position: absolute;
+ right: 0;
+ top: 5px;
+ display: block;
+ text-indent: -9999px;
+ width: 32px;
+ height: 32px; }
+
h1.class {
a {
background: url(../images/class-m.png) no-repeat 0 -5px;
@@ -843,8 +853,7 @@ a {
}
a.tabUrl {
padding: 0 14px 0 17px;
- max-width: 180px;
- text-overflow: ellipsis;
+ width: 140px;
overflow: hidden;
}
span.icn {
@@ -901,6 +910,9 @@ a {
.doctab.overview .m {
z-index: 6;
}
+ .doctab.overview .m a.tabUrl{
+ width: auto !important;
+ }
.doctab.index .m a {
background: url(../images/tab-icons.png) no-repeat 7px 1px;
padding-left: 16px; padding-right: 12px; padding-bottom: 20px;
@@ -921,6 +933,23 @@ a {
background: url(../images/tab-icons.png) no-repeat 7px -93px;
padding-left: 16px; padding-right: 12px;
}
+
+ #tabOverflow {
+ position: absolute;
+ right: 5px;
+ top: 8px;
+ button {
+ display: block;
+ width: 14px;
+ height: 20px;
+ background: url(../images/tab-overflow.png) no-repeat;
+ border: 0;
+ }
+ }
+}
+
+.overflow {
+ background: #e3e3e3;
}
.all-demos {