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
116116 needsSaving = true
117117 doc = @disabledDocs.findBy('slug', 'node~4_lts') if slug == 'node~4.2_lts'
118118 doc = @disabledDocs.findBy('slug', 'xslt_xpath') if slug == 'xpath'
119+ doc = @disabledDocs.findBy('slug', "angularjs~#{match[1]}") if match = /^angular~(1\.\d)$/.exec(slug)
119120 doc ||= @disabledDocs.findBy('slug_without_version', slug)
120121 if doc
121122 @disabledDocs.remove(doc)
assets/javascripts/news.json+4−4
@@ -1,5 +1,8 @@
11 [
22 [
3+ "2016-06-12",
4+ "New documentation: <a href=\"/angular/\">Angular 2</a>"
5+ ], [
36 "2016-06-05",
47 "New documentation: <a href=\"/kotlin/\">Kotlin</a> and <a href=\"/padrino/\">Padrino</a>"
58 ], [
@@ -154,9 +157,6 @@ · 148 unmodified lines
154157 ], [
155158 "2014-02-12",
156159 "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"
160160 ], [
161161 "2014-01-19",
162162 "New <a href=\"/d3/\">D3.js</a> and <a href=\"/knockout/\">Knockout.js</a> documentations"
@@ -210,7 +210,7 @@ · 47 unmodified lines
210210 "URL search now automatically opens the first result."
211211 ], [
212212 "2013-08-13",
213− "New <a href=\"/angular/\">Angular.js</a> documentation"
213+ "New <a href=\"/angularjs/\">Angular.js</a> documentation"
214214 ], [
215215 "2013-08-11",
216216 "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
8686 """
8787
8888 credits = [
89− [ 'Angular.js',
89+ [ 'Angular<br>Angular.js',
9090 '2010-2016 Google, Inc.',
9191 'CC BY',
9292 '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
77 return
88
99 app.views.AngularPage =
10+app.views.AngularjsPage =
1011 app.views.CakephpPage =
1112 app.views.ElixirPage =
1213 app.views.EmberPage =
assets/stylesheets/application-dark.css.scss+1−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030
3131 @import 'pages/simple',
3232 'pages/angular',
33+ 'pages/angularjs',
3334 'pages/apache',
3435 'pages/bower',
3536 'pages/c',
assets/stylesheets/application.css.scss+1−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030
3131 @import 'pages/simple',
3232 'pages/angular',
33+ 'pages/angularjs',
3334 'pages/apache',
3435 'pages/bower',
3536 'pages/c',
assets/stylesheets/global/_icons.scss+2−1
@@ -38,7 +38,7 @@ · 37 unmodified lines
3838 ._icon-node_lts:before { background-position: -6rem -1rem; }
3939 ._icon-sass:before { background-position: -7rem -1rem; }
4040 ._icon-less:before { background-position: -8rem -1rem; }
41−._icon-angular:before { background-position: -9rem -1rem; }
41+._icon-angularjs:before { background-position: -9rem -1rem; }
4242 ._icon-coffeescript:before { background-position: 0 -2rem; @extend %darkIconFix !optional; }
4343 ._icon-ember:before { background-position: -1rem -2rem; }
4444 %icon-menu { background-position: -2rem -2rem; }
@@ -141,3 +141,4 @@ · 96 unmodified lines
141141 ._icon-numpy:before { background-position: -5rem -11rem; }
142142 ._icon-kotlin:before { background-position: -6rem -11rem; }
143143 ._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 @@
11 ._angular {
2− h2 { @extend %block-heading; }
2+ padding-left: 1rem;
33
4− //
5− // Index
6− //
4+ h1, h2, > h3, .banner, .badges { margin-left: -1rem; }
75
8− .nav-index-section {
9− margin: 1.5em 0 1em -2em;
10− list-style: none;
11− font-weight: bold;
12− text-transform: capitalize;
13− }
6+ ._mobile & {
7+ padding-left: 0;
148
15− //
16− // Other
17− //
9+ h1, h2, > h3, .banner, .badges { margin-left: 0; }
10+ }
1811
19− h3, h4 { font-size: 1rem; }
12+ h2 { @extend %block-heading; }
13+ > h3 { @extend %block-label, %label-blue; }
2014
21− .alert { @extend %note; }
22− .alert-success { @extend %note-green; }
23− .alert-error { @extend %note-red; }
15+ p > code, .status-badge { @extend %label; }
2416
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; }
2621
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;
22+ td > h3, .l-sub-section > h3, .l-sub-section > h4, .alert > h3, .alert > h4 {
23+ margin-top: .25rem;
24+ font-size: 1em;
3425 }
3526
36− .defs {
37− padding-left: 1rem;
38− list-style: none;
27+ img {
28+ display: block;
29+ margin: 1em auto;
3930
40− > li > h3:first-child {
41− margin: 0 0 1em -1rem;
42− @extend %block-label, %label-blue;
31+ &[align="left"] {
32+ float: left;
33+ margin: 0 1em 0 0;
4334 }
4435
45− > li + li { margin-top: 2em; }
46−
47− h4 {
48− margin: 1em 0 .5em;
49− font-size: 1em;
36+ &[align="right"] {
37+ float: right;
38+ margin: 0 0 0 1em;
5039 }
40+ }
41+
42+ .location-badge {
43+ text-align: right;
44+ font-style: italic;
45+ }
46+
47+ .filetree {
48+ white-space: normal;
49+ @extend %pre;
5150
52− ul { list-style-type: disc; }
51+ .children { padding-left: 1em; }
5352 }
5453 }
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
280280 'iojs' => 'node',
281281 'yii1' => 'yii~1.1',
282282 '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'
284288 }
285289
286290 get %r{\A/([\w~\.]+)(\-[\w\-]+)?(/.*)?\z} do |doc, type, rest|
287291 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')
289293 return 404 unless @doc = find_doc(doc)
290294
291295 if rest.nil?
lib/docs/filters/angular/clean_html.rb+49−60
@@ -2,96 +2,85 @@ module Docs · 1 unmodified line
22 class Angular
33 class CleanHtmlFilter < Filter
44 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
68
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
9+ css('pre.no-bg-with-indent').each do |node|
10+ node.content = ' ' + node.content.gsub("\n", "\n ")
1211 end
1312
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)
13+ css('.openParens').each do |node|
14+ node.parent.name = 'pre'
15+ node.parent.content = node.parent.css('code, pre').map(&:content).join("\n")
2316 end
2417
25− css('.nav-index-section').each do |node|
26− node.content = node.content
18+ css('button.verbose', 'button.verbose + .l-verbose-section', 'a[id=top]', 'a[href="#top"]').remove
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
2722 end
2823
29− css('.toc-close', '.naked-list').remove
30− end
24+ css('span.badges').each do |node|
25+ node.name = 'div'
26+ end
3127
32− def other
33− css('#example', '.example', '#description_source', '#description_demo', '[id$="example"]', 'hr').remove
28+ css('pre[language]').each do |node|
29+ node['data-language'] = node['language'].sub(/\Ats/, 'typescript').strip
30+ end
3431
35− css('header').each do |node|
36− node.before(node.children).remove
32+ css('pre.prettyprint').each do |node|
33+ node.content = node.content.strip
3734 end
3835
39− if h1 = at_css('h1')
40− h1.prepend_child(css('.view-source', '.improve-docs'))
36+ css('a[id]:empty').each do |node|
37+ node.next_element['id'] = node['id'] if node.next_element
4138 end
4239
43− # Remove root-level <div>
44− while div = at_css('h1 + div')
45− div.before(div.children)
46− div.remove
40+ css('a[name]:empty').each do |node|
41+ node.next_element['id'] = node['name'] if node.next_element
4742 end
4843
49− css('.api-profile-header-structure > li').each do |node|
50− node.inner_html = node.inner_html.remove('- ')
44+ css('tr[style]').each do |node|
45+ node.remove_attribute 'style'
5146 end
5247
53− css('h1').each_with_index do |node, i|
54− next if i == 0
48+ css('h1:not(:first-child)').each do |node|
5549 node.name = 'h2'
56− end
50+ end unless at_css('h2')
5751
58− # Remove examples
59− css('.runnable-example').each do |node|
60− node.parent.remove
52+ css('img[style]').each do |node|
53+ node['align'] ||= node['style'][/float:\s*(left|right)/, 1]
54+ node['style'] = node['style'].split(';').map(&:strip).select { |s| s =~ /\Awidth|height/ }.join(';')
6155 end
6256
63− # Remove dead links (e.g. ngRepeat)
64− css('a.type-hint').each do |node|
65− node.name = 'code'
66− node.remove_attribute 'href'
57+ css('.example-title + pre').each do |node|
58+ node['name'] = node.previous_element.content.strip
59+ node.previous_element.remove
6760 end
6861
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'
62+ css('pre[name]').each do |node|
63+ case node['data-language']
64+ when 'html' then node.content = "<!-- #{node['name']} -->\n\n" + node.content
65+ when 'css' then node.content = "/* #{node['name']} */\n\n" + node.content
66+ else node.content = "// #{node['name']}\n\n" + node.content
7767 end
78− node.parent['data-language'] = lang if lang
68+ end
7969
80− node.before(node.children).remove
70+ css('a.is-button > h3').each do |node|
71+ node.parent.content = node.content
8172 end
8273
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
74+ css('#angular-2-glossary ~ .l-sub-section').each do |node|
75+ node.before(node.children).remove
8676 end
8777
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
78+ location_badge = at_css('.location-badge')
79+ if location_badge && doc.last_element_child != location_badge
80+ doc.last_element_child.after(location_badge)
9481 end
82+
83+ doc
9584 end
9685 end
9786 end
lib/docs/filters/angular/entries.rb+25−34
@@ -2,51 +2,42 @@ module Docs · 1 unmodified line
22 class Angular
33 class EntriesFilter < Docs::EntriesFilter
44 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
5+ name = at_css('header.hero h1').content.strip
6+ name = name.split(':').first
7+
8+ if mod
9+ if name == 'Testing'
10+ return "#{mod.capitalize} Testing"
11+ elsif name == 'Index' || name == 'Angular'
12+ return mod
13+ end
1514 end
15+
16+ name << '()' if at_css('.status-badge').try(:content) == 'Function'
17+ name
1618 end
1719
1820 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')
21+ if slug.start_with?('guide/')
2422 'Guide'
23+ else
24+ type = at_css('.is-nav-title-selected').content.strip
25+ type.remove! ' Reference'
26+ type << ": #{mod}" if mod
27+ type
2528 end
2629 end
2730
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
31+ INDEX = Set.new
3432
35− def additional_entries
36− return [] unless slug.start_with?('api')
37− entries = []
33+ def include_default_entry?
34+ INDEX.add?([name, type].join(';')) ? true : false # ¯\_(ツ)_/¯
35+ end
3836
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
37+ private
4838
49− entries
39+ def mod
40+ @mod ||= slug[/api\/([\w\-]+)\//, 1]
5041 end
5142 end
5243 end
lib/docs/filters/angularjs/clean_html.rb+98−0
@@ -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
lib/docs/filters/angularjs/clean_urls.rbrenamed from lib/docs/filters/angular/clean_urls.rb+1−1
@@ -1,5 +1,5 @@
11 module Docs
2− class Angular
2+ class Angularjs
33 class CleanUrlsFilter < Filter
44 def call
55 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 @@
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
lib/docs/scrapers/angular.rb+39−48
@@ -1,68 +1,59 @@
11 module Docs
22 class Angular < UrlScraper
3− self.name = 'Angular.js'
4− self.slug = 'angular'
53 self.type = 'angular'
6− self.root_path = 'api.html'
7− self.initial_paths = %w(guide.html)
8−
9− html_filters.push 'angular/clean_html', 'angular/entries', 'title'
10− text_filters.push 'angular/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
4+ self.root_path = 'api/'
5+ self.links = {
6+ home: 'https://angular.io/',
7+ code: 'https://github.com/angular/angular'
8+ }
9+
10+ html_filters.push 'angular/entries', 'angular/clean_html'
11+
12+ options[:skip_patterns] = [/deprecated/]
13+ options[:skip] = %w(
14+ index.html
15+ styleguide.html
16+ quickstart.html
17+ guide/cheatsheet.html
18+ guide/style-guide.html)
19+
20+ options[:replace_paths] = {
21+ 'testing/index.html' => 'guide/testing.html',
22+ 'glossary.html' => 'guide/glossary.html',
23+ 'tutorial' => 'tutorial/'
24+ }
25+
26+ options[:fix_urls] = -> (url) do
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'
3029 url
3130 end
3231
33− options[:only_patterns] = [%r{\Aapi/}, %r{\Aguide/}]
34− options[:skip] = %w(api/ng.html)
35−
3632 options[:attribution] = <<-HTML
3733 &copy; 2010&ndash;2016 Google, Inc.<br>
3834 Licensed under the Creative Commons Attribution License 4.0.
3935 HTML
4036
41− stub '' do
37+ stub 'api/' do
4238 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/"
39+ capybara.app_host = 'https://angular.io'
40+ capybara.visit('/docs/ts/latest/api/')
41+ capybara.execute_script('return document.body.innerHTML')
5142 end
5243
53− version '1.4' do
54− self.release = '1.4.11'
55− self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
44+ version '2.0 TypeScript' do
45+ self.release = '2.0.0rc1'
46+ self.base_url = "https://angular.io/docs/ts/latest/"
5647 end
5748
58− version '1.3' do
59− self.release = '1.3.20'
60− self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
61− end
49+ private
6250
63− version '1.2' do
64− self.release = '1.2.29'
65− self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
51+ def parse(string)
52+ string.gsub! '<code-example', '<pre'
53+ string.gsub! '</code-example', '</pre'
54+ string.gsub! '<code-pane', '<pre'
55+ string.gsub! '</code-pane', '</pre'
56+ super string
6657 end
6758 end
6859 end
lib/docs/scrapers/angularjs.rb+68−0
@@ -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+ &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
68+end
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 @@
1−https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports
1+https://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 @@
1+https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports