History

Add Angular 2 documentation

Thibaut Courouble committed 10 years ago

Commit b78244f1 parent cd9f50c25 files · +436 −183Browse files

Unified · Split

25 files
  1. assets/images/icons.png +0 −0
  2. assets/images/icons@2x.png +0 −0
  3. assets/javascripts/app/app.coffee +1 −0
  4. assets/javascripts/news.json +4 −4
  5. assets/javascripts/templates/pages/about_tmpl.coffee +1 −1
  6. assets/javascripts/views/pages/simple.coffee +1 −0
  7. assets/stylesheets/application-dark.css.scss +1 −0
  8. assets/stylesheets/application.css.scss +1 −0
  9. assets/stylesheets/global/_icons.scss +2 −1
  10. assets/stylesheets/pages/_angular.scss +36 −37
  11. assets/stylesheets/pages/_angularjs.scss +54 −0
  12. lib/app.rb +6 −2
  13. lib/docs/filters/angular/clean_html.rb +49 −60
  14. lib/docs/filters/angular/entries.rb +25 −34
  15. lib/docs/filters/angularjs/clean_html.rb +98 −0
  16. lib/docs/filters/angularjs/clean_urls.rb +1 −1
  17. lib/docs/filters/angularjs/entries.rb +53 −0
  18. lib/docs/scrapers/angular.rb +39 −48
  19. lib/docs/scrapers/angularjs.rb +68 −0
  20. public/icons/docs/angular/16.png +0 −0
  21. public/icons/docs/angular/16@2x.png +0 −0
  22. public/icons/docs/angular/SOURCE +1 −1
  23. public/icons/docs/angularjs/16.png +0 −0
  24. public/icons/docs/angularjs/16@2x.png +0 −0
  25. public/icons/docs/angularjs/SOURCE +1 −0
assets/images/icons.png+0−0

Binary file not shown.

assets/images/icons@2x.png+0−0

Binary file not shown.

assets/javascripts/app/app.coffee+1−0
@@ -116,6 +116,7 @@ · 115 unmodified lines
116 needsSaving = true116 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 doc121 if doc
121 @disabledDocs.remove(doc)122 @disabledDocs.remove(doc)
assets/javascripts/news.json+4−4
@@ -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"
assets/javascripts/templates/pages/about_tmpl.coffee+1−1
@@ -86,7 +86,7 @@ app.templates.aboutPage = -> """ · 85 unmodified lines
86"""86"""
87 87
88credits = [88credits = [
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/'
assets/javascripts/views/pages/simple.coffee+1−0
@@ -7,6 +7,7 @@ class app.views.SimplePage extends app.views.BasePage · 6 unmodified lines
7 return7 return
8 8
9app.views.AngularPage =9app.views.AngularPage =
10app.views.AngularjsPage =
10app.views.CakephpPage =11app.views.CakephpPage =
11app.views.ElixirPage =12app.views.ElixirPage =
12app.views.EmberPage =13app.views.EmberPage =
assets/stylesheets/application-dark.css.scss+1−0
@@ -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',
assets/stylesheets/application.css.scss+1−0
@@ -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',
assets/stylesheets/global/_icons.scss+2−1
@@ -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; }
assets/stylesheets/pages/_angular.scss+36−37
@@ -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 // Other10 }
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}
assets/stylesheets/pages/_angularjs.scss+54−0
@@ -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}
lib/app.rb+6−2
@@ -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?
lib/docs/filters/angular/clean_html.rb+49−60
@@ -2,96 +2,85 @@ module Docs · 1 unmodified line
2 class Angular2 class Angular
3 class CleanHtmlFilter < Filter3 class CleanHtmlFilter < Filter
4 def call4 def call
5 root_page? ? root : other5 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-* attributes9 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 end11 end
13 12
14 doc13 css('.openParens').each do |node|
15 end14 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 end16 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.content19
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 end22 end
28 23
29 css('.toc-close', '.naked-list').remove24 css('span.badges').each do |node|
30 end25 node.name = 'div'
26 end
31 27
32 def other28 css('pre[language]').each do |node|
33 css('#example', '.example', '#description_source', '#description_demo', '[id$="example"]', 'hr').remove29 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).remove33 node.content = node.content.strip
37 end34 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 end38 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 end42 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 end46 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 end50 end unless at_css('h2')
57 51
58 # Remove examples52 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.remove54 node['style'] = node['style'].split(';').map(&:strip).select { |s| s =~ /\Awidth|height/ }.join(';')
61 end55 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 end60 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 end67 end
78 node.parent['data-language'] = lang if lang68 end
79 69
80 node.before(node.children).remove70 css('a.is-button > h3').each do |node|
71 node.parent.content = node.content
81 end72 end
82 73
83 # Remove some <code> elements74 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 end76 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 end81 end
82
83 doc
95 end84 end
96 end85 end
97 end86 end
lib/docs/filters/angular/entries.rb+25−34
@@ -2,51 +2,42 @@ module Docs · 1 unmodified line
2 class Angular2 class Angular
3 class EntriesFilter < Docs::EntriesFilter3 class EntriesFilter < Docs::EntriesFilter
4 def get_name4 def get_name
5 if slug.start_with?('api')5 name = at_css('header.hero h1').content.strip
6 name = URI.unescape(slug).split('/').last6 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 == type9 if name == 'Testing'
10 name10 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 end14 end
15
16 name << '()' if at_css('.status-badge').try(:content) == 'Function'
17 name
16 end18 end
17 19
18 def get_type20 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 end28 end
26 end29 end
27 30
28 def subtype31 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_entries33 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 entries39 def mod
40 @mod ||= slug[/api\/([\w\-]+)\//, 1]
50 end41 end
51 end42 end
52 end43 end
lib/docs/filters/angularjs/clean_html.rb+98−0
@@ -0,0 +1,98 @@
1module 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
98end
lib/docs/filters/angularjs/clean_urls.rbrenamed from lib/docs/filters/angular/clean_urls.rb+1−1
@@ -1,5 +1,5 @@
1module Docs1module Docs
2 class Angular2 class Angularjs
3 class CleanUrlsFilter < Filter3 class CleanUrlsFilter < Filter
4 def call4 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/'
lib/docs/filters/angularjs/entries.rb+53−0
@@ -0,0 +1,53 @@
1module 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
53end
lib/docs/scrapers/angular.rb+39−48
@@ -1,68 +1,59 @@
1module Docs1module Docs
2 class Angular < UrlScraper2 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] = false10 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] = true13 options[:skip] = %w(
16 options[:fix_urls_before_parse] = ->(str) do14 index.html
17 str.gsub!('[', '%5B')15 styleguide.html
18 str.gsub!(']', '%5D')16 quickstart.html
19 str17 guide/cheatsheet.html
20 end18 guide/style-guide.html)
21 19
22 options[:fix_urls] = ->(url) do20 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 end27 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 url29 url
31 end30 end
32 31
33 options[:only_patterns] = [%r{\Aapi/}, %r{\Aguide/}]
34 options[:skip] = %w(api/ng.html)
35
36 options[:attribution] = <<-HTML32 options[:attribution] = <<-HTML
37 &copy; 2010&ndash;2016 Google, Inc.<br>33 &copy; 2010&ndash;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 HTML35 HTML
40 36
41 stub '' do37 stub 'api/' do
42 capybara = load_capybara_selenium38 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 end42 end
52 43
53 version '1.4' do44 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 end47 end
57 48
58 version '1.3' do49 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' do51 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 end57 end
67 end58 end
68end59end
lib/docs/scrapers/angularjs.rb+68−0
@@ -0,0 +1,68 @@
1module 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 &copy; 2010&ndash;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
68end
public/icons/docs/angular/16.png+0−0

Binary file not shown.

public/icons/docs/angular/16@2x.png+0−0

Binary file not shown.

public/icons/docs/angular/SOURCE+1−1
@@ -1 +1 @@
1https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports1https://angular.io/presskit.html
public/icons/docs/angularjs/16.png+0−0

Binary file not shown.

public/icons/docs/angularjs/16@2x.png+0−0

Binary file not shown.

public/icons/docs/angularjs/SOURCE+1−0
@@ -0,0 +1 @@
1https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports