Unified · Split
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | class app.models.Doc extends app.Model |
| 2 | − # Attributes: name, slug, type, version, index_path, db_path, db_size, mtime | |
| 2 | + # Attributes: name, slug, type, version, index_path, db_path, db_size, mtime, links | |
| 3 | 3 | |
| 4 | 4 | constructor: -> |
| 5 | 5 | super |
| @@ -36,6 +36,18 @@ class app.views.EntryPage extends app.View · 35 unmodified lines | ||
| 36 | 36 | @trigger 'loaded' |
| 37 | 37 | return |
| 38 | 38 | |
| 39 | + LINKS = | |
| 40 | + home: 'Homepage' | |
| 41 | + code: 'Source code' | |
| 42 | + | |
| 43 | + prepareContent: (content) -> | |
| 44 | + return content unless @entry.isIndex() and @entry.doc.links | |
| 45 | + | |
| 46 | + links = for link, url of @entry.doc.links | |
| 47 | + """<a href="#{url}" class="_links-link">#{LINKS[link]}</a>""" | |
| 48 | + | |
| 49 | + """<p class="_links">#{links.join('')}</p>#{content}""" | |
| 50 | + | |
| 39 | 51 | empty: -> |
| 40 | 52 | @subview?.deactivate() |
| 41 | 53 | @subview = null |
| @@ -78,7 +90,7 @@ class app.views.EntryPage extends app.View · 36 unmodified lines | ||
| 78 | 90 | |
| 79 | 91 | onSuccess: (response) => |
| 80 | 92 | @xhr = null |
| 81 | − @render response | |
| 93 | + @render @prepareContent(response) | |
| 82 | 94 | return |
| 83 | 95 | |
| 84 | 96 | onError: => |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | // |
| 4 | 4 | |
| 5 | 5 | ._page { |
| 6 | + position: relative; | |
| 7 | + | |
| 6 | 8 | > h1 { @extend ._lined-heading; } |
| 7 | 9 | > h1:first-child { margin-top: 0; } |
| 8 | 10 | |
| @@ -22,6 +24,35 @@ · 13 unmodified lines | ||
| 22 | 24 | } |
| 23 | 25 | } |
| 24 | 26 | |
| 27 | +// | |
| 28 | +// Links | |
| 29 | +// | |
| 30 | + | |
| 31 | +._links { | |
| 32 | + position: absolute; | |
| 33 | + top: 0; | |
| 34 | + right: 0; | |
| 35 | + margin: 0; | |
| 36 | + line-height: 2em; | |
| 37 | + text-align: right; | |
| 38 | + | |
| 39 | + + h1 { margin-top: 0; } | |
| 40 | + | |
| 41 | + @media (max-width: 1023px) { display: none; } | |
| 42 | +} | |
| 43 | + | |
| 44 | +._links-link { | |
| 45 | + display: inline-block; | |
| 46 | + vertical-align: top; | |
| 47 | + padding: 0 .5rem; | |
| 48 | + background: white; | |
| 49 | + @extend %internal-link; | |
| 50 | + | |
| 51 | + & + & { margin-left: .75rem; } | |
| 52 | + &:first-child { padding-left: 1rem; } | |
| 53 | + &:last-child { padding-right: 0; } | |
| 54 | +} | |
| 55 | + | |
| 25 | 56 | // |
| 26 | 57 | // Attribution box |
| 27 | 58 | // |
| @@ -38,7 +38,8 @@ module Docs · 37 unmodified lines | ||
| 38 | 38 | type: type, |
| 39 | 39 | version: version, |
| 40 | 40 | index_path: index_path, |
| 41 | − db_path: db_path } | |
| 41 | + db_path: db_path, | |
| 42 | + links: links } | |
| 42 | 43 | end |
| 43 | 44 | |
| 44 | 45 | def store_page(store, id) |
| @@ -34,7 +34,7 @@ module Docs · 33 unmodified lines | ||
| 34 | 34 | self.text_filters = FilterStack.new |
| 35 | 35 | |
| 36 | 36 | html_filters.push 'container', 'clean_html', 'normalize_urls', 'internal_urls', 'normalize_paths' |
| 37 | − text_filters.push 'inner_html', 'clean_text', 'links', 'attribution' | |
| 37 | + text_filters.push 'inner_html', 'clean_text', 'attribution' | |
| 38 | 38 | |
| 39 | 39 | def build_page(path) |
| 40 | 40 | response = request_one url_for(path) |
| @@ -65,10 +65,6 @@ module Docs · 24 unmodified lines | ||
| 65 | 65 | @root_url ||= root_path? ? URL.parse(File.join(base_url.to_s, root_path)) : base_url.normalize |
| 66 | 66 | end |
| 67 | 67 | |
| 68 | − def links | |
| 69 | − self.class.links | |
| 70 | − end | |
| 71 | − | |
| 72 | 68 | def root_path |
| 73 | 69 | self.class.root_path |
| 74 | 70 | end |
| @@ -93,7 +89,7 @@ module Docs · 18 unmodified lines | ||
| 93 | 89 | |
| 94 | 90 | def options |
| 95 | 91 | @options ||= self.class.options.deep_dup.tap do |options| |
| 96 | − options.merge! base_url: base_url, root_url: root_url, links: links, | |
| 92 | + options.merge! base_url: base_url, root_url: root_url, | |
| 97 | 93 | root_path: root_path, initial_paths: initial_paths |
| 98 | 94 | |
| 99 | 95 | if root_path? |
| @@ -1,26 +0,0 @@ | ||
| 1 | −module Docs | |
| 2 | − class LinksFilter < Filter | |
| 3 | − def call | |
| 4 | − html.prepend(links_html) if root_page? && links | |
| 5 | − html | |
| 6 | − end | |
| 7 | − | |
| 8 | − NAMES = { | |
| 9 | − home: 'Homepage', | |
| 10 | − code: 'Source code' | |
| 11 | − } | |
| 12 | − | |
| 13 | − def links_html | |
| 14 | − links = self.links.map do |name, link| | |
| 15 | − %(<li><a href="#{link}" class="_toc-link">#{NAMES[name]}</a></li>) | |
| 16 | − end | |
| 17 | − | |
| 18 | − <<-HTML.strip_heredoc | |
| 19 | − <div class="_toc"> | |
| 20 | − <div class="_toc-title">Resources</div> | |
| 21 | − <ul class="_toc-list">#{links.join}</ul> | |
| 22 | − </div> | |
| 23 | − HTML | |
| 24 | − end | |
| 25 | − end | |
| 26 | −end | |
| @@ -116,7 +116,7 @@ class DocsDocTest < MiniTest::Spec · 115 unmodified lines | ||
| 116 | 116 | end |
| 117 | 117 | |
| 118 | 118 | it "includes the doc's name, slug, type, version, index_path and db_path" do |
| 119 | − %w(name slug type version index_path db_path).each do |attribute| | |
| 119 | + %w(name slug type version index_path db_path links).each do |attribute| | |
| 120 | 120 | eval "stub(doc).#{attribute} { attribute }" |
| 121 | 121 | assert_equal attribute, doc.as_json[attribute.to_sym] |
| 122 | 122 | end |