From a2d9922d9c8b6f65a843bcf2fbaf3db495fa1f6d Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Thu, 24 Sep 2015 13:14:23 -0700 Subject: [PATCH] simplified Table of Contents js --- .../src/js/components/TocComponent.coffee | 40 +++++------ pub/tree/src/js/main.js | 72 +++++++++---------- 2 files changed, 54 insertions(+), 58 deletions(-) diff --git a/pub/tree/src/js/components/TocComponent.coffee b/pub/tree/src/js/components/TocComponent.coffee index d255fbe6a1..ee6b756162 100644 --- a/pub/tree/src/js/components/TocComponent.coffee +++ b/pub/tree/src/js/components/TocComponent.coffee @@ -9,17 +9,14 @@ module.exports = query {body:'r'}, recl hash:null displayName: "TableOfContents" - _click: (e) -> - document.location.hash = @urlsafe $(e.target).text() - - urlsafe: (str) -> - str.toLowerCase().replace(/\ /g, "-").replace(/[^a-z0-9~_.-]/g,"") + _click: (id)-> + -> if id then document.location.hash = id componentDidMount: -> @int = setInterval @checkHash,100 @st = $(window).scrollTop() - $(window).on 'scroll',@checkScroll - @$headers = $('#toc h1, #toc h2, #toc h3, #toc h4') + # $(window).on 'scroll',@checkScroll + @$headers = $('#toc').children('h1,h2,h3,h4').filter('[id]') checkScroll: -> st = $(window).scrollTop() @@ -31,7 +28,7 @@ module.exports = query {body:'r'}, recl $h = $ v hst = $h.offset().top-$h.outerHeight(true)+10 if hst < st - hash = @urlsafe $h.text() + hash = $h.attr('id') if hst > st and hash isnt @hash and hash isnt null @hash = "#"+hash document.location.hash = hash @@ -42,7 +39,7 @@ module.exports = query {body:'r'}, recl hash = document.location.hash.slice(1) for v in @$headers $h = $ v - if hash is @urlsafe $h.text() + if hash is $h.attr('id') @hash = document.location.hash offset = $h.offset().top - $h.outerHeight(true) setTimeout -> $(window).scrollTop offset @@ -52,20 +49,23 @@ module.exports = query {body:'r'}, recl componentWillUnmount: -> clearInterval @int - collectHeaders: (e) -> - hs = [{gn:"h1", ga:{className:"t"}, c:["Table of contents"]}] - for k,v of e - if not v.gn then continue - if v.gn[0] is 'h' and parseInt(v.gn[1]) isnt NaN - _v = _.clone v - delete _v.ga.id - hs.push v - return hs + collectHeader: ({gn,ga,c})-> + if gn and gn[0] is 'h' and parseInt(gn[1]) isnt NaN + ga = _.clone ga + ga.onClick = @_click ga.id + delete ga.id + {gn,ga,c} parseHeaders: -> if @props.body.c - for k,v of @props.body.c + for v in @props.body.c if v.gn is 'div' and v.ga?.id is "toc" - return {gn:"div", ga:{className:"toc",onClick:@_click}, c:@collectHeaders(v.c)} + return { + gn:"div" + ga:{className:"toc"} + c:[ + {gn:"h1", ga:{className:"t"}, c:["Table of contents"]} + (_.filter v.c.map @collectHeader)... + ]} render: -> reactify @parseHeaders() diff --git a/pub/tree/src/js/main.js b/pub/tree/src/js/main.js index 7d2af5e6e3..ad8c8aa38e 100644 --- a/pub/tree/src/js/main.js +++ b/pub/tree/src/js/main.js @@ -933,7 +933,8 @@ module.exports = query({ },{"./Async.coffee":3,"./Reactify.coffee":11}],13:[function(require,module,exports){ -var div, query, reactify, recl; +var div, query, reactify, recl, + slice = [].slice; query = require('./Async.coffee'); @@ -948,17 +949,17 @@ module.exports = query({ }, recl({ hash: null, displayName: "TableOfContents", - _click: function(e) { - return document.location.hash = this.urlsafe($(e.target).text()); - }, - urlsafe: function(str) { - return str.toLowerCase().replace(/\ /g, "-").replace(/[^a-z0-9~_.-]/g, ""); + _click: function(id) { + return function() { + if (id) { + return document.location.hash = id; + } + }; }, componentDidMount: function() { this.int = setInterval(this.checkHash, 100); this.st = $(window).scrollTop(); - $(window).on('scroll', this.checkScroll); - return this.$headers = $('#toc h1, #toc h2, #toc h3, #toc h4'); + return this.$headers = $('#toc').children('h1,h2,h3,h4').filter('[id]'); }, checkScroll: function() { var $h, hash, hst, i, len, ref, results, st, v; @@ -976,7 +977,7 @@ module.exports = query({ $h = $(v); hst = $h.offset().top - $h.outerHeight(true) + 10; if (hst < st) { - hash = this.urlsafe($h.text()); + hash = $h.attr('id'); } if (hst > st && hash !== this.hash && hash !== null) { this.hash = "#" + hash; @@ -998,7 +999,7 @@ module.exports = query({ for (i = 0, len = ref1.length; i < len; i++) { v = ref1[i]; $h = $(v); - if (hash === this.urlsafe($h.text())) { + if (hash === $h.attr('id')) { this.hash = document.location.hash; offset = $h.offset().top - $h.outerHeight(true); setTimeout(function() { @@ -1015,44 +1016,39 @@ module.exports = query({ componentWillUnmount: function() { return clearInterval(this.int); }, - collectHeaders: function(e) { - var _v, hs, k, v; - hs = [ - { - gn: "h1", - ga: { - className: "t" - }, - c: ["Table of contents"] - } - ]; - for (k in e) { - v = e[k]; - if (!v.gn) { - continue; - } - if (v.gn[0] === 'h' && parseInt(v.gn[1]) !== NaN) { - _v = _.clone(v); - delete _v.ga.id; - hs.push(v); - } + collectHeader: function(arg) { + var c, ga, gn; + gn = arg.gn, ga = arg.ga, c = arg.c; + if (gn && gn[0] === 'h' && parseInt(gn[1]) !== NaN) { + ga = _.clone(ga); + ga.onClick = this._click(ga.id); + delete ga.id; + return { + gn: gn, + ga: ga, + c: c + }; } - return hs; }, parseHeaders: function() { - var k, ref, ref1, v; + var i, len, ref, ref1, v; if (this.props.body.c) { ref = this.props.body.c; - for (k in ref) { - v = ref[k]; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; if (v.gn === 'div' && ((ref1 = v.ga) != null ? ref1.id : void 0) === "toc") { return { gn: "div", ga: { - className: "toc", - onClick: this._click + className: "toc" }, - c: this.collectHeaders(v.c) + c: [{ + gn: "h1", + ga: { + className: "t" + }, + c: ["Table of contents"] + }].concat(slice.call(_.filter(v.c.map(this.collectHeader)))) }; } }