Unified · Split
Binary file not shown.
Binary file not shown.
| @@ -116,6 +116,7 @@ · 115 unmodified lines | |||
| 116 | needsSaving = true | 116 | needsSaving = true |
| 117 | doc = @disabledDocs.findBy('slug', 'node~4_lts') if slug == 'node~4.2_lts' | 117 | doc = @disabledDocs.findBy('slug', 'node~4_lts') if slug == 'node~4.2_lts' |
| 118 | doc = @disabledDocs.findBy('slug', 'xslt_xpath') if slug == 'xpath' | 118 | doc = @disabledDocs.findBy('slug', 'xslt_xpath') if slug == 'xpath' |
| 119 | doc = @disabledDocs.findBy('slug', "angularjs~#{match[1]}") if match = /^angular~(1\.\d)$/.exec(slug) | ||
| 119 | doc ||= @disabledDocs.findBy('slug_without_version', slug) | 120 | doc ||= @disabledDocs.findBy('slug_without_version', slug) |
| 120 | if doc | 121 | if doc |
| 121 | @disabledDocs.remove(doc) | 122 | @disabledDocs.remove(doc) |
| @@ -1,5 +1,8 @@ | |||
| 1 | [ | 1 | [ |
| 2 | [ | 2 | [ |
| 3 | "2016-06-12", | ||
| 4 | "New documentation: <a href=\"/angular/\">Angular 2</a>" | ||
| 5 | ], [ | ||
| 3 | "2016-06-05", | 6 | "2016-06-05", |
| 4 | "New documentation: <a href=\"/kotlin/\">Kotlin</a> and <a href=\"/padrino/\">Padrino</a>" | 7 | "New documentation: <a href=\"/kotlin/\">Kotlin</a> and <a href=\"/padrino/\">Padrino</a>" |
| 5 | ], [ | 8 | ], [ |
| @@ -154,9 +157,6 @@ · 148 unmodified lines | |||
| 154 | ], [ | 157 | ], [ |
| 155 | "2014-02-12", | 158 | "2014-02-12", |
| 156 | "The root/category pages are now included in the search index (e.g. <a href=\"/#q=CSS\">CSS</a>)" | 159 | "The root/category pages are now included in the search index (e.g. <a href=\"/#q=CSS\">CSS</a>)" |
| 157 | ], [ | ||
| 158 | "2014-01-26", | ||
| 159 | "Updated <a href=\"/angular/\">Angular.js</a> documentation" | ||
| 160 | ], [ | 160 | ], [ |
| 161 | "2014-01-19", | 161 | "2014-01-19", |
| 162 | "New <a href=\"/d3/\">D3.js</a> and <a href=\"/knockout/\">Knockout.js</a> documentations" | 162 | "New <a href=\"/d3/\">D3.js</a> and <a href=\"/knockout/\">Knockout.js</a> documentations" |
| @@ -210,7 +210,7 @@ · 47 unmodified lines | |||
| 210 | "URL search now automatically opens the first result." | 210 | "URL search now automatically opens the first result." |
| 211 | ], [ | 211 | ], [ |
| 212 | "2013-08-13", | 212 | "2013-08-13", |
| 213 | "New <a href=\"/angular/\">Angular.js</a> documentation" | 213 | "New <a href=\"/angularjs/\">Angular.js</a> documentation" |
| 214 | ], [ | 214 | ], [ |
| 215 | "2013-08-11", | 215 | "2013-08-11", |
| 216 | "New <a href=\"/sass/\">Sass</a> and <a href=\"/less/\">Less</a> documentations" | 216 | "New <a href=\"/sass/\">Sass</a> and <a href=\"/less/\">Less</a> documentations" |
| @@ -86,7 +86,7 @@ app.templates.aboutPage = -> """ · 85 unmodified lines | |||
| 86 | """ | 86 | """ |
| 87 | 87 | ||
| 88 | credits = [ | 88 | credits = [ |
| 89 | [ 'Angular.js', | 89 | [ 'Angular<br>Angular.js', |
| 90 | '2010-2016 Google, Inc.', | 90 | '2010-2016 Google, Inc.', |
| 91 | 'CC BY', | 91 | 'CC BY', |
| 92 | 'https://creativecommons.org/licenses/by/4.0/' | 92 | 'https://creativecommons.org/licenses/by/4.0/' |
| @@ -7,6 +7,7 @@ class app.views.SimplePage extends app.views.BasePage · 6 unmodified lines | |||
| 7 | return | 7 | return |
| 8 | 8 | ||
| 9 | app.views.AngularPage = | 9 | app.views.AngularPage = |
| 10 | app.views.AngularjsPage = | ||
| 10 | app.views.CakephpPage = | 11 | app.views.CakephpPage = |
| 11 | app.views.ElixirPage = | 12 | app.views.ElixirPage = |
| 12 | app.views.EmberPage = | 13 | app.views.EmberPage = |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | @import 'pages/simple', | 31 | @import 'pages/simple', |
| 32 | 'pages/angular', | 32 | 'pages/angular', |
| 33 | 'pages/angularjs', | ||
| 33 | 'pages/apache', | 34 | 'pages/apache', |
| 34 | 'pages/bower', | 35 | 'pages/bower', |
| 35 | 'pages/c', | 36 | 'pages/c', |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | @import 'pages/simple', | 31 | @import 'pages/simple', |
| 32 | 'pages/angular', | 32 | 'pages/angular', |
| 33 | 'pages/angularjs', | ||
| 33 | 'pages/apache', | 34 | 'pages/apache', |
| 34 | 'pages/bower', | 35 | 'pages/bower', |
| 35 | 'pages/c', | 36 | 'pages/c', |
| @@ -38,7 +38,7 @@ · 37 unmodified lines | |||
| 38 | ._icon-node_lts:before { background-position: -6rem -1rem; } | 38 | ._icon-node_lts:before { background-position: -6rem -1rem; } |
| 39 | ._icon-sass:before { background-position: -7rem -1rem; } | 39 | ._icon-sass:before { background-position: -7rem -1rem; } |
| 40 | ._icon-less:before { background-position: -8rem -1rem; } | 40 | ._icon-less:before { background-position: -8rem -1rem; } |
| 41 | ._icon-angular:before { background-position: -9rem -1rem; } | 41 | ._icon-angularjs:before { background-position: -9rem -1rem; } |
| 42 | ._icon-coffeescript:before { background-position: 0 -2rem; @extend %darkIconFix !optional; } | 42 | ._icon-coffeescript:before { background-position: 0 -2rem; @extend %darkIconFix !optional; } |
| 43 | ._icon-ember:before { background-position: -1rem -2rem; } | 43 | ._icon-ember:before { background-position: -1rem -2rem; } |
| 44 | %icon-menu { background-position: -2rem -2rem; } | 44 | %icon-menu { background-position: -2rem -2rem; } |
| @@ -141,3 +141,4 @@ · 96 unmodified lines | |||
| 141 | ._icon-numpy:before { background-position: -5rem -11rem; } | 141 | ._icon-numpy:before { background-position: -5rem -11rem; } |
| 142 | ._icon-kotlin:before { background-position: -6rem -11rem; } | 142 | ._icon-kotlin:before { background-position: -6rem -11rem; } |
| 143 | ._icon-padrino:before { background-position: -7rem -11rem; } | 143 | ._icon-padrino:before { background-position: -7rem -11rem; } |
| 144 | ._icon-angular:before { background-position: -8rem -11rem; } | ||
| @@ -1,54 +1,53 @@ | |||
| 1 | ._angular { | 1 | ._angular { |
| 2 | h2 { @extend %block-heading; } | 2 | padding-left: 1rem; |
| 3 | 3 | ||
| 4 | // | 4 | h1, h2, > h3, .banner, .badges { margin-left: -1rem; } |
| 5 | // Index | ||
| 6 | // | ||
| 7 | 5 | ||
| 8 | .nav-index-section { | 6 | ._mobile & { |
| 9 | margin: 1.5em 0 1em -2em; | 7 | padding-left: 0; |
| 10 | list-style: none; | ||
| 11 | font-weight: bold; | ||
| 12 | text-transform: capitalize; | ||
| 13 | } | ||
| 14 | 8 | ||
| 15 | // | 9 | h1, h2, > h3, .banner, .badges { margin-left: 0; } |
| 16 | // Other | 10 | } |
| 17 | // | ||
| 18 | 11 | ||
| 19 | h3, h4 { font-size: 1rem; } | 12 | h2 { @extend %block-heading; } |
| 13 | > h3 { @extend %block-label, %label-blue; } | ||
| 20 | 14 | ||
| 21 | .alert { @extend %note; } | 15 | p > code, .status-badge { @extend %label; } |
| 22 | .alert-success { @extend %note-green; } | ||
| 23 | .alert-error { @extend %note-red; } | ||
| 24 | 16 | ||
| 25 | p > code, li > code, td > code { @extend %label; } | 17 | .l-sub-section, .alert, .banner { @extend %note; } |
| 18 | .banner { @extend %note-green; } | ||
| 19 | .alert.is-important { @extend %note-red; } | ||
| 20 | .alert.is-helpful { @extend %note-blue; } | ||
| 26 | 21 | ||
| 27 | .view-source, .improve-docs { | 22 | td > h3, .l-sub-section > h3, .l-sub-section > h4, .alert > h3, .alert > h4 { |
| 28 | position: relative; | 23 | margin-top: .25rem; |
| 29 | float: right; | 24 | font-size: 1em; |
| 30 | line-height: 1.7rem; | ||
| 31 | padding-left: 1em; | ||
| 32 | font-size: .875rem; | ||
| 33 | background: $contentBackground; | ||
| 34 | } | 25 | } |
| 35 | 26 | ||
| 36 | .defs { | 27 | img { |
| 37 | padding-left: 1rem; | 28 | display: block; |
| 38 | list-style: none; | 29 | margin: 1em auto; |
| 39 | 30 | ||
| 40 | > li > h3:first-child { | 31 | &[align="left"] { |
| 41 | margin: 0 0 1em -1rem; | 32 | float: left; |
| 42 | @extend %block-label, %label-blue; | 33 | margin: 0 1em 0 0; |
| 43 | } | 34 | } |
| 44 | 35 | ||
| 45 | > li + li { margin-top: 2em; } | 36 | &[align="right"] { |
| 46 | 37 | float: right; | |
| 47 | h4 { | 38 | margin: 0 0 0 1em; |
| 48 | margin: 1em 0 .5em; | ||
| 49 | font-size: 1em; | ||
| 50 | } | 39 | } |
| 40 | } | ||
| 41 | |||
| 42 | .location-badge { | ||
| 43 | text-align: right; | ||
| 44 | font-style: italic; | ||
| 45 | } | ||
| 46 | |||
| 47 | .filetree { | ||
| 48 | white-space: normal; | ||
| 49 | @extend %pre; | ||
| 51 | 50 | ||
| 52 | ul { list-style-type: disc; } | 51 | .children { padding-left: 1em; } |
| 53 | } | 52 | } |
| 54 | } | 53 | } |
| @@ -0,0 +1,54 @@ | |||
| 1 | ._angularjs { | ||
| 2 | h2 { @extend %block-heading; } | ||
| 3 | |||
| 4 | // | ||
| 5 | // Index | ||
| 6 | // | ||
| 7 | |||
| 8 | .nav-index-section { | ||
| 9 | margin: 1.5em 0 1em -2em; | ||
| 10 | list-style: none; | ||
| 11 | font-weight: bold; | ||
| 12 | text-transform: capitalize; | ||
| 13 | } | ||
| 14 | |||
| 15 | // | ||
| 16 | // Other | ||
| 17 | // | ||
| 18 | |||
| 19 | h3, h4 { font-size: 1rem; } | ||
| 20 | |||
| 21 | .alert { @extend %note; } | ||
| 22 | .alert-success { @extend %note-green; } | ||
| 23 | .alert-error { @extend %note-red; } | ||
| 24 | |||
| 25 | p > code, li > code, td > code { @extend %label; } | ||
| 26 | |||
| 27 | .view-source, .improve-docs { | ||
| 28 | position: relative; | ||
| 29 | float: right; | ||
| 30 | line-height: 1.7rem; | ||
| 31 | padding-left: 1em; | ||
| 32 | font-size: .875rem; | ||
| 33 | background: $contentBackground; | ||
| 34 | } | ||
| 35 | |||
| 36 | .defs { | ||
| 37 | padding-left: 1rem; | ||
| 38 | list-style: none; | ||
| 39 | |||
| 40 | > li > h3:first-child { | ||
| 41 | margin: 0 0 1em -1rem; | ||
| 42 | @extend %block-label, %label-blue; | ||
| 43 | } | ||
| 44 | |||
| 45 | > li + li { margin-top: 2em; } | ||
| 46 | |||
| 47 | h4 { | ||
| 48 | margin: 1em 0 .5em; | ||
| 49 | font-size: 1em; | ||
| 50 | } | ||
| 51 | |||
| 52 | ul { list-style-type: disc; } | ||
| 53 | } | ||
| 54 | } | ||
| @@ -280,12 +280,16 @@ class App < Sinatra::Application · 279 unmodified lines | |||
| 280 | 'iojs' => 'node', | 280 | 'iojs' => 'node', |
| 281 | 'yii1' => 'yii~1.1', | 281 | 'yii1' => 'yii~1.1', |
| 282 | 'python2' => 'python~2.7', | 282 | 'python2' => 'python~2.7', |
| 283 | 'xpath' => 'xslt_xpath' | 283 | 'xpath' => 'xslt_xpath', |
| 284 | 'angular~1.5' => 'angularjs~1.5', | ||
| 285 | 'angular~1.4' => 'angularjs~1.4', | ||
| 286 | 'angular~1.3' => 'angularjs~1.3', | ||
| 287 | 'angular~1.2' => 'angularjs~1.2' | ||
| 284 | } | 288 | } |
| 285 | 289 | ||
| 286 | get %r{\A/([\w~\.]+)(\-[\w\-]+)?(/.*)?\z} do |doc, type, rest| | 290 | get %r{\A/([\w~\.]+)(\-[\w\-]+)?(/.*)?\z} do |doc, type, rest| |
| 287 | return redirect "/#{DOC_REDIRECTS[doc]}#{type}#{rest}" if DOC_REDIRECTS.key?(doc) | 291 | return redirect "/#{DOC_REDIRECTS[doc]}#{type}#{rest}" if DOC_REDIRECTS.key?(doc) |
| 288 | return redirect "/angular/api#{rest}", 301 if doc == 'angular' && rest.start_with?('/ng') | 292 | return redirect "/angularjs/api#{rest}", 301 if doc == 'angular' && rest.start_with?('/ng') |
| 289 | return 404 unless @doc = find_doc(doc) | 293 | return 404 unless @doc = find_doc(doc) |
| 290 | 294 | ||
| 291 | if rest.nil? | 295 | if rest.nil? |
| @@ -2,96 +2,85 @@ module Docs · 1 unmodified line | |||
| 2 | class Angular | 2 | class Angular |
| 3 | class CleanHtmlFilter < Filter | 3 | class CleanHtmlFilter < Filter |
| 4 | def call | 4 | def call |
| 5 | root_page? ? root : other | 5 | container = at_css('article.docs-content') |
| 6 | container.child.before(at_css('header.hero h1')).before(css('header.hero .badges')).before(css('header.hero + .banner')) | ||
| 7 | @doc = container | ||
| 6 | 8 | ||
| 7 | # Remove ng-* attributes | 9 | css('pre.no-bg-with-indent').each do |node| |
| 8 | css('*').each do |node| | 10 | node.content = ' ' + node.content.gsub("\n", "\n ") |
| 9 | node.attributes.each_key do |attribute| | ||
| 10 | node.remove_attribute(attribute) if attribute.start_with? 'ng-' | ||
| 11 | end | ||
| 12 | end | 11 | end |
| 13 | 12 | ||
| 14 | doc | 13 | css('.openParens').each do |node| |
| 15 | end | 14 | node.parent.name = 'pre' |
| 16 | 15 | node.parent.content = node.parent.css('code, pre').map(&:content).join("\n") | |
| 17 | def root | ||
| 18 | css('.nav-index-group').each do |node| | ||
| 19 | if heading = node.at_css('.nav-index-group-heading') | ||
| 20 | heading.name = 'h2' | ||
| 21 | end | ||
| 22 | node.parent.before(node.children) | ||
| 23 | end | 16 | end |
| 24 | 17 | ||
| 25 | css('.nav-index-section').each do |node| | 18 | css('button.verbose', 'button.verbose + .l-verbose-section', 'a[id=top]', 'a[href="#top"]').remove |
| 26 | node.content = node.content | 19 | |
| 20 | css('.c10', '.showcase', '.showcase-content', '.l-main-section', 'div.div', 'div[flex]', 'code-tabs', 'md-card', 'md-card-content', 'div:not([class])', 'footer', '.card-row', '.card-row-container', 'figure', 'blockquote', 'exported', 'defined', 'div.ng-scope').each do |node| | ||
| 21 | node.before(node.children).remove | ||
| 27 | end | 22 | end |
| 28 | 23 | ||
| 29 | css('.toc-close', '.naked-list').remove | 24 | css('span.badges').each do |node| |
| 30 | end | 25 | node.name = 'div' |
| 26 | end | ||
| 31 | 27 | ||
| 32 | def other | 28 | css('pre[language]').each do |node| |
| 33 | css('#example', '.example', '#description_source', '#description_demo', '[id$="example"]', 'hr').remove | 29 | node['data-language'] = node['language'].sub(/\Ats/, 'typescript').strip |
| 30 | end | ||
| 34 | 31 | ||
| 35 | css('header').each do |node| | 32 | css('pre.prettyprint').each do |node| |
| 36 | node.before(node.children).remove | 33 | node.content = node.content.strip |
| 37 | end | 34 | end |
| 38 | 35 | ||
| 39 | if h1 = at_css('h1') | 36 | css('a[id]:empty').each do |node| |
| 40 | h1.prepend_child(css('.view-source', '.improve-docs')) | 37 | node.next_element['id'] = node['id'] if node.next_element |
| 41 | end | 38 | end |
| 42 | 39 | ||
| 43 | # Remove root-level <div> | 40 | css('a[name]:empty').each do |node| |
| 44 | while div = at_css('h1 + div') | 41 | node.next_element['id'] = node['name'] if node.next_element |
| 45 | div.before(div.children) | ||
| 46 | div.remove | ||
| 47 | end | 42 | end |
| 48 | 43 | ||
| 49 | css('.api-profile-header-structure > li').each do |node| | 44 | css('tr[style]').each do |node| |
| 50 | node.inner_html = node.inner_html.remove('- ') | 45 | node.remove_attribute 'style' |
| 51 | end | 46 | end |
| 52 | 47 | ||
| 53 | css('h1').each_with_index do |node, i| | 48 | css('h1:not(:first-child)').each do |node| |
| 54 | next if i == 0 | ||
| 55 | node.name = 'h2' | 49 | node.name = 'h2' |
| 56 | end | 50 | end unless at_css('h2') |
| 57 | 51 | ||
| 58 | # Remove examples | 52 | css('img[style]').each do |node| |
| 59 | css('.runnable-example').each do |node| | 53 | node['align'] ||= node['style'][/float:\s*(left|right)/, 1] |
| 60 | node.parent.remove | 54 | node['style'] = node['style'].split(';').map(&:strip).select { |s| s =~ /\Awidth|height/ }.join(';') |
| 61 | end | 55 | end |
| 62 | 56 | ||
| 63 | # Remove dead links (e.g. ngRepeat) | 57 | css('.example-title + pre').each do |node| |
| 64 | css('a.type-hint').each do |node| | 58 | node['name'] = node.previous_element.content.strip |
| 65 | node.name = 'code' | 59 | node.previous_element.remove |
| 66 | node.remove_attribute 'href' | ||
| 67 | end | 60 | end |
| 68 | 61 | ||
| 69 | css('pre > code').each do |node| | 62 | css('pre[name]').each do |node| |
| 70 | node['class'] ||= '' | 63 | case node['data-language'] |
| 71 | lang = if node['class'].include?('lang-html') || node.content =~ /\A</ | 64 | when 'html' then node.content = "<!-- #{node['name']} -->\n\n" + node.content |
| 72 | 'html' | 65 | when 'css' then node.content = "/* #{node['name']} */\n\n" + node.content |
| 73 | elsif node['class'].include?('lang-css') | 66 | else node.content = "// #{node['name']}\n\n" + node.content |
| 74 | 'css' | ||
| 75 | elsif node['class'].include?('lang-js') || node['class'].include?('lang-javascript') | ||
| 76 | 'javascript' | ||
| 77 | end | 67 | end |
| 78 | node.parent['data-language'] = lang if lang | 68 | end |
| 79 | 69 | ||
| 80 | node.before(node.children).remove | 70 | css('a.is-button > h3').each do |node| |
| 71 | node.parent.content = node.content | ||
| 81 | end | 72 | end |
| 82 | 73 | ||
| 83 | # Remove some <code> elements | 74 | css('#angular-2-glossary ~ .l-sub-section').each do |node| |
| 84 | css('h1 > code', 'h2 > code', 'h3 > code', 'h4 > code', 'h6 > code').each do |node| | 75 | node.before(node.children).remove |
| 85 | node.before(node.content).remove | ||
| 86 | end | 76 | end |
| 87 | 77 | ||
| 88 | css('ul.methods', 'ul.properties', 'ul.events').add_class('defs').each do |node| | 78 | location_badge = at_css('.location-badge') |
| 89 | node.css('> li > h3').each do |h3| | 79 | if location_badge && doc.last_element_child != location_badge |
| 90 | next if h3.content.present? | 80 | doc.last_element_child.after(location_badge) |
| 91 | h3.content = h3.next_element.content | ||
| 92 | h3.next_element.remove | ||
| 93 | end | ||
| 94 | end | 81 | end |
| 82 | |||
| 83 | doc | ||
| 95 | end | 84 | end |
| 96 | end | 85 | end |
| 97 | end | 86 | end |
| @@ -2,51 +2,42 @@ module Docs · 1 unmodified line | |||
| 2 | class Angular | 2 | class Angular |
| 3 | class EntriesFilter < Docs::EntriesFilter | 3 | class EntriesFilter < Docs::EntriesFilter |
| 4 | def get_name | 4 | def get_name |
| 5 | if slug.start_with?('api') | 5 | name = at_css('header.hero h1').content.strip |
| 6 | name = URI.unescape(slug).split('/').last | 6 | name = name.split(':').first |
| 7 | name.remove! %r{\Ang\.} | 7 | |
| 8 | name << " (#{subtype})" if subtype == 'directive' || subtype == 'filter' | 8 | if mod |
| 9 | name.prepend("#{type}.") unless type.starts_with?('ng ') || name == type | 9 | if name == 'Testing' |
| 10 | name | 10 | return "#{mod.capitalize} Testing" |
| 11 | elsif slug.start_with?('guide') | 11 | elsif name == 'Index' || name == 'Angular' |
| 12 | name = URI.decode(at_css('.improve-docs')['href'][/message=docs\(guide%2F(.+?)\)/, 1]) | 12 | return mod |
| 13 | name.prepend 'Guide: ' | 13 | end |
| 14 | name | ||
| 15 | end | 14 | end |
| 15 | |||
| 16 | name << '()' if at_css('.status-badge').try(:content) == 'Function' | ||
| 17 | name | ||
| 16 | end | 18 | end |
| 17 | 19 | ||
| 18 | def get_type | 20 | def get_type |
| 19 | if slug.start_with?('api') | 21 | if slug.start_with?('guide/') |
| 20 | type = slug.split('/').drop(1).first | ||
| 21 | type << " #{subtype}s" if type == 'ng' && subtype | ||
| 22 | type | ||
| 23 | elsif slug.start_with?('guide') | ||
| 24 | 'Guide' | 22 | 'Guide' |
| 23 | else | ||
| 24 | type = at_css('.is-nav-title-selected').content.strip | ||
| 25 | type.remove! ' Reference' | ||
| 26 | type << ": #{mod}" if mod | ||
| 27 | type | ||
| 25 | end | 28 | end |
| 26 | end | 29 | end |
| 27 | 30 | ||
| 28 | def subtype | 31 | INDEX = Set.new |
| 29 | return @subtype if defined? @subtype | ||
| 30 | node = at_css '.api-profile-header-structure' | ||
| 31 | data = node.content.match %r{(\w+?) in module} if node | ||
| 32 | @subtype = data && data[1] | ||
| 33 | end | ||
| 34 | 32 | ||
| 35 | def additional_entries | 33 | def include_default_entry? |
| 36 | return [] unless slug.start_with?('api') | 34 | INDEX.add?([name, type].join(';')) ? true : false # ¯\_(ツ)_/¯ |
| 37 | entries = [] | 35 | end |
| 38 | 36 | ||
| 39 | css('ul.defs').each do |list| | 37 | private |
| 40 | list.css('> li[id]').each do |node| | ||
| 41 | next unless heading = node.at_css('h3') | ||
| 42 | name = heading.content.strip | ||
| 43 | name.sub! %r{\(.*\);}, '()' | ||
| 44 | name.prepend "#{self.name.split.first}." | ||
| 45 | entries << [name, node['id']] | ||
| 46 | end | ||
| 47 | end | ||
| 48 | 38 | ||
| 49 | entries | 39 | def mod |
| 40 | @mod ||= slug[/api\/([\w\-]+)\//, 1] | ||
| 50 | end | 41 | end |
| 51 | end | 42 | end |
| 52 | end | 43 | end |
| @@ -0,0 +1,98 @@ | |||
| 1 | module Docs | ||
| 2 | class Angularjs | ||
| 3 | class CleanHtmlFilter < Filter | ||
| 4 | def call | ||
| 5 | root_page? ? root : other | ||
| 6 | |||
| 7 | # Remove ng-* attributes | ||
| 8 | css('*').each do |node| | ||
| 9 | node.attributes.each_key do |attribute| | ||
| 10 | node.remove_attribute(attribute) if attribute.start_with? 'ng-' | ||
| 11 | end | ||
| 12 | end | ||
| 13 | |||
| 14 | doc | ||
| 15 | end | ||
| 16 | |||
| 17 | def root | ||
| 18 | css('.nav-index-group').each do |node| | ||
| 19 | if heading = node.at_css('.nav-index-group-heading') | ||
| 20 | heading.name = 'h2' | ||
| 21 | end | ||
| 22 | node.parent.before(node.children) | ||
| 23 | end | ||
| 24 | |||
| 25 | css('.nav-index-section').each do |node| | ||
| 26 | node.content = node.content | ||
| 27 | end | ||
| 28 | |||
| 29 | css('.toc-close', '.naked-list').remove | ||
| 30 | end | ||
| 31 | |||
| 32 | def other | ||
| 33 | css('#example', '.example', '#description_source', '#description_demo', '[id$="example"]', 'hr').remove | ||
| 34 | |||
| 35 | css('header').each do |node| | ||
| 36 | node.before(node.children).remove | ||
| 37 | end | ||
| 38 | |||
| 39 | if h1 = at_css('h1') | ||
| 40 | h1.prepend_child(css('.view-source', '.improve-docs')) | ||
| 41 | end | ||
| 42 | |||
| 43 | # Remove root-level <div> | ||
| 44 | while div = at_css('h1 + div') | ||
| 45 | div.before(div.children) | ||
| 46 | div.remove | ||
| 47 | end | ||
| 48 | |||
| 49 | css('.api-profile-header-structure > li').each do |node| | ||
| 50 | node.inner_html = node.inner_html.remove('- ') | ||
| 51 | end | ||
| 52 | |||
| 53 | css('h1').each_with_index do |node, i| | ||
| 54 | next if i == 0 | ||
| 55 | node.name = 'h2' | ||
| 56 | end | ||
| 57 | |||
| 58 | # Remove examples | ||
| 59 | css('.runnable-example').each do |node| | ||
| 60 | node.parent.remove | ||
| 61 | end | ||
| 62 | |||
| 63 | # Remove dead links (e.g. ngRepeat) | ||
| 64 | css('a.type-hint').each do |node| | ||
| 65 | node.name = 'code' | ||
| 66 | node.remove_attribute 'href' | ||
| 67 | end | ||
| 68 | |||
| 69 | css('pre > code').each do |node| | ||
| 70 | node['class'] ||= '' | ||
| 71 | lang = if node['class'].include?('lang-html') || node.content =~ /\A</ | ||
| 72 | 'html' | ||
| 73 | elsif node['class'].include?('lang-css') | ||
| 74 | 'css' | ||
| 75 | elsif node['class'].include?('lang-js') || node['class'].include?('lang-javascript') | ||
| 76 | 'javascript' | ||
| 77 | end | ||
| 78 | node.parent['data-language'] = lang if lang | ||
| 79 | |||
| 80 | node.before(node.children).remove | ||
| 81 | end | ||
| 82 | |||
| 83 | # Remove some <code> elements | ||
| 84 | css('h1 > code', 'h2 > code', 'h3 > code', 'h4 > code', 'h6 > code').each do |node| | ||
| 85 | node.before(node.content).remove | ||
| 86 | end | ||
| 87 | |||
| 88 | css('ul.methods', 'ul.properties', 'ul.events').add_class('defs').each do |node| | ||
| 89 | node.css('> li > h3').each do |h3| | ||
| 90 | next if h3.content.present? | ||
| 91 | h3.content = h3.next_element.content | ||
| 92 | h3.next_element.remove | ||
| 93 | end | ||
| 94 | end | ||
| 95 | end | ||
| 96 | end | ||
| 97 | end | ||
| 98 | end | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Angular | 2 | class Angularjs |
| 3 | class CleanUrlsFilter < Filter | 3 | class CleanUrlsFilter < Filter |
| 4 | def call | 4 | def call |
| 5 | html.gsub! %r{angularjs\.org/([\d\.]+)/docs/partials/(\w+)/}, 'angularjs.org/\1/docs/\2/' | 5 | html.gsub! %r{angularjs\.org/([\d\.]+)/docs/partials/(\w+)/}, 'angularjs.org/\1/docs/\2/' |
| @@ -0,0 +1,53 @@ | |||
| 1 | module Docs | ||
| 2 | class Angularjs | ||
| 3 | class EntriesFilter < Docs::EntriesFilter | ||
| 4 | def get_name | ||
| 5 | if slug.start_with?('api') | ||
| 6 | name = URI.unescape(slug).split('/').last | ||
| 7 | name.remove! %r{\Ang\.} | ||
| 8 | name << " (#{subtype})" if subtype == 'directive' || subtype == 'filter' | ||
| 9 | name.prepend("#{type}.") unless type.starts_with?('ng ') || name == type | ||
| 10 | name | ||
| 11 | elsif slug.start_with?('guide') | ||
| 12 | name = URI.decode(at_css('.improve-docs')['href'][/message=docs\(guide%2F(.+?)\)/, 1]) | ||
| 13 | name.prepend 'Guide: ' | ||
| 14 | name | ||
| 15 | end | ||
| 16 | end | ||
| 17 | |||
| 18 | def get_type | ||
| 19 | if slug.start_with?('api') | ||
| 20 | type = slug.split('/').drop(1).first | ||
| 21 | type << " #{subtype}s" if type == 'ng' && subtype | ||
| 22 | type | ||
| 23 | elsif slug.start_with?('guide') | ||
| 24 | 'Guide' | ||
| 25 | end | ||
| 26 | end | ||
| 27 | |||
| 28 | def subtype | ||
| 29 | return @subtype if defined? @subtype | ||
| 30 | node = at_css '.api-profile-header-structure' | ||
| 31 | data = node.content.match %r{(\w+?) in module} if node | ||
| 32 | @subtype = data && data[1] | ||
| 33 | end | ||
| 34 | |||
| 35 | def additional_entries | ||
| 36 | return [] unless slug.start_with?('api') | ||
| 37 | entries = [] | ||
| 38 | |||
| 39 | css('ul.defs').each do |list| | ||
| 40 | list.css('> li[id]').each do |node| | ||
| 41 | next unless heading = node.at_css('h3') | ||
| 42 | name = heading.content.strip | ||
| 43 | name.sub! %r{\(.*\);}, '()' | ||
| 44 | name.prepend "#{self.name.split.first}." | ||
| 45 | entries << [name, node['id']] | ||
| 46 | end | ||
| 47 | end | ||
| 48 | |||
| 49 | entries | ||
| 50 | end | ||
| 51 | end | ||
| 52 | end | ||
| 53 | end | ||
| @@ -1,68 +1,59 @@ | |||
| 1 | module Docs | 1 | module Docs |
| 2 | class Angular < UrlScraper | 2 | class Angular < UrlScraper |
| 3 | self.name = 'Angular.js' | ||
| 4 | self.slug = 'angular' | ||
| 5 | self.type = 'angular' | 3 | self.type = 'angular' |
| 6 | self.root_path = 'api.html' | 4 | self.root_path = 'api/' |
| 7 | self.initial_paths = %w(guide.html) | 5 | self.links = { |
| 8 | 6 | home: 'https://angular.io/', | |
| 9 | html_filters.push 'angular/clean_html', 'angular/entries', 'title' | 7 | code: 'https://github.com/angular/angular' |
| 10 | text_filters.push 'angular/clean_urls' | 8 | } |
| 11 | 9 | ||
| 12 | options[:title] = false | 10 | html_filters.push 'angular/entries', 'angular/clean_html' |
| 13 | options[:root_title] = 'Angular.js' | 11 | |
| 14 | 12 | options[:skip_patterns] = [/deprecated/] | |
| 15 | options[:decode_and_clean_paths] = true | 13 | options[:skip] = %w( |
| 16 | options[:fix_urls_before_parse] = ->(str) do | 14 | index.html |
| 17 | str.gsub!('[', '%5B') | 15 | styleguide.html |
| 18 | str.gsub!(']', '%5D') | 16 | quickstart.html |
| 19 | str | 17 | guide/cheatsheet.html |
| 20 | end | 18 | guide/style-guide.html) |
| 21 | 19 | ||
| 22 | options[:fix_urls] = ->(url) do | 20 | options[:replace_paths] = { |
| 23 | %w(api guide).each do |str| | 21 | 'testing/index.html' => 'guide/testing.html', |
| 24 | url.sub! "/partials/#{str}/#{str}/", "/partials/#{str}/" | 22 | 'glossary.html' => 'guide/glossary.html', |
| 25 | url.sub! %r{/#{str}/img/}, "/img/" | 23 | 'tutorial' => 'tutorial/' |
| 26 | url.sub! %r{/#{str}/(.+?)/#{str}/}, "/#{str}/" | 24 | } |
| 27 | url.sub! %r{/partials/#{str}/(.+?)(?<!\.html)(?:\z|(#.*))}, "/partials/#{str}/\\1.html\\2" | 25 | |
| 28 | url.sub! %r{/partials/.+/#{str}/}, "/partials/#{str}/" | 26 | options[:fix_urls] = -> (url) do |
| 29 | end | 27 | url.sub! %r{\A(https://angular\.io/docs/.+/)index\.html\z}, '\1' |
| 28 | url.sub! %r{\A(https://angular\.io/docs/.+/index)/\z}, '\1' | ||
| 30 | url | 29 | url |
| 31 | end | 30 | end |
| 32 | 31 | ||
| 33 | options[:only_patterns] = [%r{\Aapi/}, %r{\Aguide/}] | ||
| 34 | options[:skip] = %w(api/ng.html) | ||
| 35 | |||
| 36 | options[:attribution] = <<-HTML | 32 | options[:attribution] = <<-HTML |
| 37 | © 2010–2016 Google, Inc.<br> | 33 | © 2010–2016 Google, Inc.<br> |
| 38 | Licensed under the Creative Commons Attribution License 4.0. | 34 | Licensed under the Creative Commons Attribution License 4.0. |
| 39 | HTML | 35 | HTML |
| 40 | 36 | ||
| 41 | stub '' do | 37 | stub 'api/' do |
| 42 | capybara = load_capybara_selenium | 38 | capybara = load_capybara_selenium |
| 43 | capybara.app_host = 'https://code.angularjs.org' | 39 | capybara.app_host = 'https://angular.io' |
| 44 | capybara.visit("/#{self.class.release}/docs/api") | 40 | capybara.visit('/docs/ts/latest/api/') |
| 45 | capybara.execute_script("return document.querySelector('.side-navigation').innerHTML") | 41 | capybara.execute_script('return document.body.innerHTML') |
| 46 | end | ||
| 47 | |||
| 48 | version '1.5' do | ||
| 49 | self.release = '1.5.6' | ||
| 50 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | ||
| 51 | end | 42 | end |
| 52 | 43 | ||
| 53 | version '1.4' do | 44 | version '2.0 TypeScript' do |
| 54 | self.release = '1.4.11' | 45 | self.release = '2.0.0rc1' |
| 55 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | 46 | self.base_url = "https://angular.io/docs/ts/latest/" |
| 56 | end | 47 | end |
| 57 | 48 | ||
| 58 | version '1.3' do | 49 | private |
| 59 | self.release = '1.3.20' | ||
| 60 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | ||
| 61 | end | ||
| 62 | 50 | ||
| 63 | version '1.2' do | 51 | def parse(string) |
| 64 | self.release = '1.2.29' | 52 | string.gsub! '<code-example', '<pre' |
| 65 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | 53 | string.gsub! '</code-example', '</pre' |
| 54 | string.gsub! '<code-pane', '<pre' | ||
| 55 | string.gsub! '</code-pane', '</pre' | ||
| 56 | super string | ||
| 66 | end | 57 | end |
| 67 | end | 58 | end |
| 68 | end | 59 | end |
| @@ -0,0 +1,68 @@ | |||
| 1 | module Docs | ||
| 2 | class Angularjs < UrlScraper | ||
| 3 | self.name = 'Angular.js' | ||
| 4 | self.slug = 'angularjs' | ||
| 5 | self.type = 'angularjs' | ||
| 6 | self.root_path = 'api.html' | ||
| 7 | self.initial_paths = %w(guide.html) | ||
| 8 | |||
| 9 | html_filters.push 'angularjs/clean_html', 'angularjs/entries', 'title' | ||
| 10 | text_filters.push 'angularjs/clean_urls' | ||
| 11 | |||
| 12 | options[:title] = false | ||
| 13 | options[:root_title] = 'Angular.js' | ||
| 14 | |||
| 15 | options[:decode_and_clean_paths] = true | ||
| 16 | options[:fix_urls_before_parse] = ->(str) do | ||
| 17 | str.gsub!('[', '%5B') | ||
| 18 | str.gsub!(']', '%5D') | ||
| 19 | str | ||
| 20 | end | ||
| 21 | |||
| 22 | options[:fix_urls] = ->(url) do | ||
| 23 | %w(api guide).each do |str| | ||
| 24 | url.sub! "/partials/#{str}/#{str}/", "/partials/#{str}/" | ||
| 25 | url.sub! %r{/#{str}/img/}, "/img/" | ||
| 26 | url.sub! %r{/#{str}/(.+?)/#{str}/}, "/#{str}/" | ||
| 27 | url.sub! %r{/partials/#{str}/(.+?)(?<!\.html)(?:\z|(#.*))}, "/partials/#{str}/\\1.html\\2" | ||
| 28 | url.sub! %r{/partials/.+/#{str}/}, "/partials/#{str}/" | ||
| 29 | end | ||
| 30 | url | ||
| 31 | end | ||
| 32 | |||
| 33 | options[:only_patterns] = [%r{\Aapi/}, %r{\Aguide/}] | ||
| 34 | options[:skip] = %w(api/ng.html) | ||
| 35 | |||
| 36 | options[:attribution] = <<-HTML | ||
| 37 | © 2010–2016 Google, Inc.<br> | ||
| 38 | Licensed under the Creative Commons Attribution License 4.0. | ||
| 39 | HTML | ||
| 40 | |||
| 41 | stub '' do | ||
| 42 | capybara = load_capybara_selenium | ||
| 43 | capybara.app_host = 'https://code.angularjs.org' | ||
| 44 | capybara.visit("/#{self.class.release}/docs/api") | ||
| 45 | capybara.execute_script("return document.querySelector('.side-navigation').innerHTML") | ||
| 46 | end | ||
| 47 | |||
| 48 | version '1.5' do | ||
| 49 | self.release = '1.5.6' | ||
| 50 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | ||
| 51 | end | ||
| 52 | |||
| 53 | version '1.4' do | ||
| 54 | self.release = '1.4.11' | ||
| 55 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | ||
| 56 | end | ||
| 57 | |||
| 58 | version '1.3' do | ||
| 59 | self.release = '1.3.20' | ||
| 60 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | ||
| 61 | end | ||
| 62 | |||
| 63 | version '1.2' do | ||
| 64 | self.release = '1.2.29' | ||
| 65 | self.base_url = "https://code.angularjs.org/#{release}/docs/partials/" | ||
| 66 | end | ||
| 67 | end | ||
| 68 | end | ||
Binary file not shown.
Binary file not shown.
| @@ -1 +1 @@ | |||
| 1 | https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports | 1 | https://angular.io/presskit.html |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1 @@ | |||
| 1 | https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports | ||