From cdde4c13556ec6a11a848b39ca8c5f6e3f03c0f2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 27 Nov 2012 11:36:33 +0200 Subject: [PATCH] Improve speed of loading class docs into view. Injecting of comment expanders is now deferred until member doc is expanded. This considerably cuts down the time of initial loading of class docs. Hovewer, clicking the expand-all button is now really-really slow as clicking it triggers the injection of all those expanders. But I think that's a good trade-off for now. --- template/app/controller/Classes.js | 12 ++--- template/app/view/cls/MemberWrap.js | 54 +++++++++++++++++++ template/app/view/cls/Overview.js | 62 ++++++++++++++++++++-- template/app/view/comments/MemberWrap.js | 67 +++++++++++++----------- 4 files changed, 152 insertions(+), 43 deletions(-) create mode 100644 template/app/view/cls/MemberWrap.js diff --git a/template/app/controller/Classes.js b/template/app/controller/Classes.js index ac87c8e1..80b5936b 100644 --- a/template/app/controller/Classes.js +++ b/template/app/controller/Classes.js @@ -86,9 +86,7 @@ Ext.define('Docs.controller.Classes', { 'toolbar': { toggleExpanded: function(expanded) { - Ext.Array.forEach(Ext.query('.side.expandable'), function(el) { - Ext.get(el).parent()[expanded ? "addCls" : "removeCls"]('open'); - }); + this.getOverview().setAllMembersExpanded(expanded); } }, @@ -101,14 +99,13 @@ Ext.define('Docs.controller.Classes', { clsName = docClass.getAttribute('rel'), memberName = member.getAttribute('id'); - if (member.hasCls('open')) { + if (this.getOverview().isMemberExpanded(memberName)) { this.setExpanded(memberName, false); } else { this.setExpanded(memberName, true); this.fireEvent('showMember', clsName, memberName); } - member.toggleCls('open'); }, this, { preventDefault: true, delegate: '.expandable' @@ -145,13 +142,16 @@ Ext.define('Docs.controller.Classes', { }); }, - // Remembers the expanded state of a member of current class + // Expands the member and remembers the expanded state of a member + // of current class setExpanded: function(member, expanded) { var cls = this.currentCls; if (!cls.expanded) { cls.expanded = {}; } + this.getOverview().setMemberExpanded(member, expanded); + if (expanded) { cls.expanded[member] = expanded; } diff --git a/template/app/view/cls/MemberWrap.js b/template/app/view/cls/MemberWrap.js new file mode 100644 index 00000000..07e6682e --- /dev/null +++ b/template/app/view/cls/MemberWrap.js @@ -0,0 +1,54 @@ +/** + * Wraps the element of class member documentation, providing methods + * to expand and collapse the member. + */ +Ext.define('Docs.view.cls.MemberWrap', { + /** + * @cfg {Ext.Element/HTMLElement} el + * The member element to wrap. + */ + + constructor: function(cfg) { + Ext.apply(this, cfg); + this.el = Ext.get(cfg.el); + }, + + /** + * Expands of collapses the member. + * @param {Boolean} expanded + */ + setExpanded: function(expanded) { + if (expanded) { + if (!this.isExpanded()) { + this.el.addCls('open'); + } + } + else { + this.el.removeCls('open'); + } + }, + + /** + * True when member is expanded. + * @return {Boolean} + */ + isExpanded: function() { + return this.el.hasCls("open"); + }, + + /** + * Returns the class the wrapped member is defined in. + * @return {String} + */ + getDefinedIn: function() { + return this.el.down('.meta .defined-in').getAttribute('rel'); + }, + + /** + * Returns the ID of the wrapped member. + * @return {String} + */ + getMemberId: function() { + return this.el.getAttribute('id'); + } +}); diff --git a/template/app/view/cls/Overview.js b/template/app/view/cls/Overview.js index 2c0b7dde..9c68633c 100644 --- a/template/app/view/cls/Overview.js +++ b/template/app/view/cls/Overview.js @@ -9,6 +9,7 @@ Ext.define('Docs.view.cls.Overview', { 'Docs.view.cls.Toolbar', 'Docs.view.examples.Inline', 'Docs.view.comments.LargeExpander', + 'Docs.view.cls.MemberWrap', 'Docs.view.comments.MemberWrap', 'Docs.Syntax', 'Docs.Settings', @@ -57,7 +58,7 @@ Ext.define('Docs.view.cls.Overview', { // expand the element if (isMember && el.down(".expandable")) { - el.addCls('open'); + this.setMemberExpanded(query.replace(/#/, ''), true); } var top = this.body.getBox().y; @@ -110,6 +111,9 @@ Ext.define('Docs.view.cls.Overview', { if (Docs.Comments.isEnabled()) { this.initComments(); } + else { + this.initBasicMemberWrappers(); + } this.fireEvent('afterload'); }, @@ -126,12 +130,24 @@ Ext.define('Docs.view.cls.Overview', { }); // Add a comment container to each class member - this.memberWrappers = Ext.Array.map(Ext.query('.member'), function(memberDoc) { - return new Docs.view.comments.MemberWrap({ + this.memberWrappers = {}; + Ext.Array.forEach(Ext.query('.member'), function(memberEl) { + var wrap = new Docs.view.comments.MemberWrap({ parent: this, className: this.docClass.name, - el: memberDoc + el: memberEl + }); + this.memberWrappers[wrap.getMemberId()] = wrap; + }, this); + }, + + initBasicMemberWrappers: function() { + this.memberWrappers = {}; + Ext.Array.forEach(Ext.query('.member'), function(memberEl) { + var wrap = new Docs.view.cls.MemberWrap({ + el: memberEl }); + this.memberWrappers[wrap.getMemberId()] = wrap; }, this); }, @@ -149,7 +165,7 @@ Ext.define('Docs.view.cls.Overview', { this.clsExpander.getExpander().setCount(clsCount); - Ext.Array.forEach(this.memberWrappers, function(wrap) { + Ext.Object.each(this.memberWrappers, function(name, wrap) { wrap.setCount(Docs.Comments.getCount(wrap.getTarget())); }, this); }, @@ -161,6 +177,42 @@ Ext.define('Docs.view.cls.Overview', { this.scrollToEl(expander.getEl(), -40); }, + /** + * Expands or collapses the given member. + * @param {String} memberName + * @param {Boolean} expanded + */ + setMemberExpanded: function(memberName, expanded) { + this.memberWrappers[memberName].setExpanded(expanded); + }, + + /** + * True when the given member is expanded. + * @param {String} memberName + * @return {Boolean} + */ + isMemberExpanded: function(memberName) { + return this.memberWrappers[memberName].isExpanded(); + }, + + /** + * Expands/collapses all members. + */ + setAllMembersExpanded: function(expanded) { + // When comments enabled, then first initialize all the + // expanders to make the next actual expanding phase much + // faster. + if (Docs.Comments.isEnabled()) { + Ext.Object.each(this.memberWrappers, function(name, wrap) { + wrap.getExpander().show(); + }, this); + } + + Ext.Object.each(this.memberWrappers, function(name, wrap) { + wrap.setExpanded(expanded); + }, this); + }, + /** * Filters members by search string and inheritance. * @param {String} search diff --git a/template/app/view/comments/MemberWrap.js b/template/app/view/comments/MemberWrap.js index ac5ea8c0..eb632b1b 100644 --- a/template/app/view/comments/MemberWrap.js +++ b/template/app/view/comments/MemberWrap.js @@ -3,6 +3,7 @@ * comments data inside it. */ Ext.define('Docs.view.comments.MemberWrap', { + extend: 'Docs.view.cls.MemberWrap', requires: [ "Docs.Comments", "Docs.view.comments.Expander" @@ -13,32 +14,18 @@ Ext.define('Docs.view.comments.MemberWrap', { * The parent class Overview component. */ - /** - * @cfg {Ext.Element/HTMLElement} el - * The member element to wrap. - */ - /** * @cfg {String} className * The name of the current class. */ constructor: function(cfg) { - Ext.apply(this, cfg); - this.el = Ext.get(cfg.el); + this.callParent([cfg]); - // The expander needs to reside inside some element. - var expanderWrap = Ext.DomHelper.append(this.el.down('.long'), "
"); var count = Docs.Comments.getCount(this.getTarget()); - - this.expander = new Docs.view.comments.Expander({ - count: count, - target: this.getTarget(), - newCommentTitle: this.getNewCommentTitle(), - renderTo: expanderWrap - }); - - this.updateSignatureCommentCount(count); + if (count > 0) { + this.updateSignatureCommentCount(count); + } }, /** @@ -52,12 +39,31 @@ Ext.define('Docs.view.comments.MemberWrap', { return this.target; }, + /** + * Returns the actual expander component, which it gets created + * when this function is called for the first time. + */ + getExpander: function() { + if (!this.expander) { + // The expander needs to reside inside some element. + var expanderWrap = Ext.DomHelper.append(this.el.down('.long'), "
"); + + this.expander = new Docs.view.comments.Expander({ + count: Docs.Comments.getCount(this.getTarget()), + target: this.getTarget(), + newCommentTitle: this.getNewCommentTitle(), + renderTo: expanderWrap + }); + } + return this.expander; + }, + /** * Updates the comment count. * @param {Number} count */ setCount: function(count) { - this.expander.setCount(count); + this.getExpander().setCount(count); this.updateSignatureCommentCount(count); }, @@ -74,8 +80,8 @@ Ext.define('Docs.view.comments.MemberWrap', { var el = Ext.DomHelper.append(titleEl, Docs.Comments.counterHtml(count), true); el.on("click", function() { this.el.addCls("open"); - this.expander.expand(); - this.parent.scrollToEl(this.expander.getEl()); + this.getExpander().expand(); + this.parent.scrollToEl(this.getExpander().getEl()); }, this); } } @@ -97,19 +103,16 @@ Ext.define('Docs.view.comments.MemberWrap', { }, /** - * Returns the class the wrapped member is defined in. - * @return {String} + * Expands of collapses the member. + * @param {Boolean} expanded */ - getDefinedIn: function() { - return this.el.down('.meta .defined-in').getAttribute('rel'); - }, + setExpanded: function(expanded) { + this.callParent([expanded]); - /** - * Returns the ID of the wrapped member. - * @return {String} - */ - getMemberId: function() { - return this.el.getAttribute('id'); + if (expanded) { + // Initialize the expander. + this.getExpander().show(); + } } }); -- GitLab