diff --git a/assets/images/icons.png b/assets/images/icons.png
index 6158f619..65c1434f 100644
Binary files a/assets/images/icons.png and b/assets/images/icons.png differ
diff --git a/assets/images/icons@2x.png b/assets/images/icons@2x.png
index 2b7bbcfa..1135557b 100644
Binary files a/assets/images/icons@2x.png and b/assets/images/icons@2x.png differ
diff --git a/assets/javascripts/app/app.coffee b/assets/javascripts/app/app.coffee
index f88937a1..a6dab394 100644
--- a/assets/javascripts/app/app.coffee
+++ b/assets/javascripts/app/app.coffee
@@ -116,6 +116,7 @@
needsSaving = true
doc = @disabledDocs.findBy('slug', 'node~4_lts') if slug == 'node~4.2_lts'
doc = @disabledDocs.findBy('slug', 'xslt_xpath') if slug == 'xpath'
+ doc = @disabledDocs.findBy('slug', "angularjs~#{match[1]}") if match = /^angular~(1\.\d)$/.exec(slug)
doc ||= @disabledDocs.findBy('slug_without_version', slug)
if doc
@disabledDocs.remove(doc)
diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json
index 8c18ccd0..f9bfb7a0 100644
--- a/assets/javascripts/news.json
+++ b/assets/javascripts/news.json
@@ -1,5 +1,8 @@
[
[
+ "2016-06-12",
+ "New documentation: Angular 2"
+ ], [
"2016-06-05",
"New documentation: Kotlin and Padrino"
], [
@@ -154,9 +157,6 @@
], [
"2014-02-12",
"The root/category pages are now included in the search index (e.g. CSS)"
- ], [
- "2014-01-26",
- "Updated Angular.js documentation"
], [
"2014-01-19",
"New D3.js and Knockout.js documentations"
@@ -210,7 +210,7 @@
"URL search now automatically opens the first result."
], [
"2013-08-13",
- "New Angular.js documentation"
+ "New Angular.js documentation"
], [
"2013-08-11",
"New Sass and Less documentations"
diff --git a/assets/javascripts/templates/pages/about_tmpl.coffee b/assets/javascripts/templates/pages/about_tmpl.coffee
index 79246985..41cf444e 100644
--- a/assets/javascripts/templates/pages/about_tmpl.coffee
+++ b/assets/javascripts/templates/pages/about_tmpl.coffee
@@ -86,7 +86,7 @@ app.templates.aboutPage = -> """
"""
credits = [
- [ 'Angular.js',
+ [ 'Angular
Angular.js',
'2010-2016 Google, Inc.',
'CC BY',
'https://creativecommons.org/licenses/by/4.0/'
diff --git a/assets/javascripts/views/pages/simple.coffee b/assets/javascripts/views/pages/simple.coffee
index 9d16896a..20e13fcd 100644
--- a/assets/javascripts/views/pages/simple.coffee
+++ b/assets/javascripts/views/pages/simple.coffee
@@ -7,6 +7,7 @@ class app.views.SimplePage extends app.views.BasePage
return
app.views.AngularPage =
+app.views.AngularjsPage =
app.views.CakephpPage =
app.views.ElixirPage =
app.views.EmberPage =
diff --git a/assets/stylesheets/application-dark.css.scss b/assets/stylesheets/application-dark.css.scss
index 46ba6202..7e90020b 100644
--- a/assets/stylesheets/application-dark.css.scss
+++ b/assets/stylesheets/application-dark.css.scss
@@ -30,6 +30,7 @@
@import 'pages/simple',
'pages/angular',
+ 'pages/angularjs',
'pages/apache',
'pages/bower',
'pages/c',
diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss
index d06c1120..6d44015d 100644
--- a/assets/stylesheets/application.css.scss
+++ b/assets/stylesheets/application.css.scss
@@ -30,6 +30,7 @@
@import 'pages/simple',
'pages/angular',
+ 'pages/angularjs',
'pages/apache',
'pages/bower',
'pages/c',
diff --git a/assets/stylesheets/global/_icons.scss b/assets/stylesheets/global/_icons.scss
index ee4ffa9e..6ae64ec9 100644
--- a/assets/stylesheets/global/_icons.scss
+++ b/assets/stylesheets/global/_icons.scss
@@ -38,7 +38,7 @@
._icon-node_lts:before { background-position: -6rem -1rem; }
._icon-sass:before { background-position: -7rem -1rem; }
._icon-less:before { background-position: -8rem -1rem; }
-._icon-angular:before { background-position: -9rem -1rem; }
+._icon-angularjs:before { background-position: -9rem -1rem; }
._icon-coffeescript:before { background-position: 0 -2rem; @extend %darkIconFix !optional; }
._icon-ember:before { background-position: -1rem -2rem; }
%icon-menu { background-position: -2rem -2rem; }
@@ -141,3 +141,4 @@
._icon-numpy:before { background-position: -5rem -11rem; }
._icon-kotlin:before { background-position: -6rem -11rem; }
._icon-padrino:before { background-position: -7rem -11rem; }
+._icon-angular:before { background-position: -8rem -11rem; }
diff --git a/assets/stylesheets/pages/_angular.scss b/assets/stylesheets/pages/_angular.scss
index c290d67c..c8260c5f 100644
--- a/assets/stylesheets/pages/_angular.scss
+++ b/assets/stylesheets/pages/_angular.scss
@@ -1,54 +1,53 @@
._angular {
- h2 { @extend %block-heading; }
+ padding-left: 1rem;
- //
- // Index
- //
+ h1, h2, > h3, .banner, .badges { margin-left: -1rem; }
- .nav-index-section {
- margin: 1.5em 0 1em -2em;
- list-style: none;
- font-weight: bold;
- text-transform: capitalize;
- }
+ ._mobile & {
+ padding-left: 0;
- //
- // Other
- //
+ h1, h2, > h3, .banner, .badges { margin-left: 0; }
+ }
- h3, h4 { font-size: 1rem; }
+ h2 { @extend %block-heading; }
+ > h3 { @extend %block-label, %label-blue; }
- .alert { @extend %note; }
- .alert-success { @extend %note-green; }
- .alert-error { @extend %note-red; }
+ p > code, .status-badge { @extend %label; }
- p > code, li > code, td > code { @extend %label; }
+ .l-sub-section, .alert, .banner { @extend %note; }
+ .banner { @extend %note-green; }
+ .alert.is-important { @extend %note-red; }
+ .alert.is-helpful { @extend %note-blue; }
- .view-source, .improve-docs {
- position: relative;
- float: right;
- line-height: 1.7rem;
- padding-left: 1em;
- font-size: .875rem;
- background: $contentBackground;
+ td > h3, .l-sub-section > h3, .l-sub-section > h4, .alert > h3, .alert > h4 {
+ margin-top: .25rem;
+ font-size: 1em;
}
- .defs {
- padding-left: 1rem;
- list-style: none;
+ img {
+ display: block;
+ margin: 1em auto;
- > li > h3:first-child {
- margin: 0 0 1em -1rem;
- @extend %block-label, %label-blue;
+ &[align="left"] {
+ float: left;
+ margin: 0 1em 0 0;
}
- > li + li { margin-top: 2em; }
-
- h4 {
- margin: 1em 0 .5em;
- font-size: 1em;
+ &[align="right"] {
+ float: right;
+ margin: 0 0 0 1em;
}
+ }
+
+ .location-badge {
+ text-align: right;
+ font-style: italic;
+ }
+
+ .filetree {
+ white-space: normal;
+ @extend %pre;
- ul { list-style-type: disc; }
+ .children { padding-left: 1em; }
}
}
diff --git a/assets/stylesheets/pages/_angularjs.scss b/assets/stylesheets/pages/_angularjs.scss
new file mode 100644
index 00000000..bbffd444
--- /dev/null
+++ b/assets/stylesheets/pages/_angularjs.scss
@@ -0,0 +1,54 @@
+._angularjs {
+ h2 { @extend %block-heading; }
+
+ //
+ // Index
+ //
+
+ .nav-index-section {
+ margin: 1.5em 0 1em -2em;
+ list-style: none;
+ font-weight: bold;
+ text-transform: capitalize;
+ }
+
+ //
+ // Other
+ //
+
+ h3, h4 { font-size: 1rem; }
+
+ .alert { @extend %note; }
+ .alert-success { @extend %note-green; }
+ .alert-error { @extend %note-red; }
+
+ p > code, li > code, td > code { @extend %label; }
+
+ .view-source, .improve-docs {
+ position: relative;
+ float: right;
+ line-height: 1.7rem;
+ padding-left: 1em;
+ font-size: .875rem;
+ background: $contentBackground;
+ }
+
+ .defs {
+ padding-left: 1rem;
+ list-style: none;
+
+ > li > h3:first-child {
+ margin: 0 0 1em -1rem;
+ @extend %block-label, %label-blue;
+ }
+
+ > li + li { margin-top: 2em; }
+
+ h4 {
+ margin: 1em 0 .5em;
+ font-size: 1em;
+ }
+
+ ul { list-style-type: disc; }
+ }
+}
diff --git a/lib/app.rb b/lib/app.rb
index 598229e3..0a81853c 100644
--- a/lib/app.rb
+++ b/lib/app.rb
@@ -280,12 +280,16 @@ class App < Sinatra::Application
'iojs' => 'node',
'yii1' => 'yii~1.1',
'python2' => 'python~2.7',
- 'xpath' => 'xslt_xpath'
+ 'xpath' => 'xslt_xpath',
+ 'angular~1.5' => 'angularjs~1.5',
+ 'angular~1.4' => 'angularjs~1.4',
+ 'angular~1.3' => 'angularjs~1.3',
+ 'angular~1.2' => 'angularjs~1.2'
}
get %r{\A/([\w~\.]+)(\-[\w\-]+)?(/.*)?\z} do |doc, type, rest|
return redirect "/#{DOC_REDIRECTS[doc]}#{type}#{rest}" if DOC_REDIRECTS.key?(doc)
- return redirect "/angular/api#{rest}", 301 if doc == 'angular' && rest.start_with?('/ng')
+ return redirect "/angularjs/api#{rest}", 301 if doc == 'angular' && rest.start_with?('/ng')
return 404 unless @doc = find_doc(doc)
if rest.nil?
diff --git a/lib/docs/filters/angular/clean_html.rb b/lib/docs/filters/angular/clean_html.rb
index cc35c4a9..607fd29d 100644
--- a/lib/docs/filters/angular/clean_html.rb
+++ b/lib/docs/filters/angular/clean_html.rb
@@ -2,96 +2,85 @@ module Docs
class Angular
class CleanHtmlFilter < Filter
def call
- root_page? ? root : other
+ container = at_css('article.docs-content')
+ container.child.before(at_css('header.hero h1')).before(css('header.hero .badges')).before(css('header.hero + .banner'))
+ @doc = container
- # Remove ng-* attributes
- css('*').each do |node|
- node.attributes.each_key do |attribute|
- node.remove_attribute(attribute) if attribute.start_with? 'ng-'
- end
+ css('pre.no-bg-with-indent').each do |node|
+ node.content = ' ' + node.content.gsub("\n", "\n ")
end
- doc
- end
-
- def root
- css('.nav-index-group').each do |node|
- if heading = node.at_css('.nav-index-group-heading')
- heading.name = 'h2'
- end
- node.parent.before(node.children)
+ css('.openParens').each do |node|
+ node.parent.name = 'pre'
+ node.parent.content = node.parent.css('code, pre').map(&:content).join("\n")
end
- css('.nav-index-section').each do |node|
- node.content = node.content
+ css('button.verbose', 'button.verbose + .l-verbose-section', 'a[id=top]', 'a[href="#top"]').remove
+
+ 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|
+ node.before(node.children).remove
end
- css('.toc-close', '.naked-list').remove
- end
+ css('span.badges').each do |node|
+ node.name = 'div'
+ end
- def other
- css('#example', '.example', '#description_source', '#description_demo', '[id$="example"]', 'hr').remove
+ css('pre[language]').each do |node|
+ node['data-language'] = node['language'].sub(/\Ats/, 'typescript').strip
+ end
- css('header').each do |node|
- node.before(node.children).remove
+ css('pre.prettyprint').each do |node|
+ node.content = node.content.strip
end
- if h1 = at_css('h1')
- h1.prepend_child(css('.view-source', '.improve-docs'))
+ css('a[id]:empty').each do |node|
+ node.next_element['id'] = node['id'] if node.next_element
end
- # Remove root-level
elements
- css('h1 > code', 'h2 > code', 'h3 > code', 'h4 > code', 'h6 > code').each do |node|
- node.before(node.content).remove
+ css('#angular-2-glossary ~ .l-sub-section').each do |node|
+ node.before(node.children).remove
end
- css('ul.methods', 'ul.properties', 'ul.events').add_class('defs').each do |node|
- node.css('> li > h3').each do |h3|
- next if h3.content.present?
- h3.content = h3.next_element.content
- h3.next_element.remove
- end
+ location_badge = at_css('.location-badge')
+ if location_badge && doc.last_element_child != location_badge
+ doc.last_element_child.after(location_badge)
end
+
+ doc
end
end
end
diff --git a/lib/docs/filters/angular/entries.rb b/lib/docs/filters/angular/entries.rb
index ce7a2975..53da36db 100644
--- a/lib/docs/filters/angular/entries.rb
+++ b/lib/docs/filters/angular/entries.rb
@@ -2,51 +2,42 @@ module Docs
class Angular
class EntriesFilter < Docs::EntriesFilter
def get_name
- if slug.start_with?('api')
- name = URI.unescape(slug).split('/').last
- name.remove! %r{\Ang\.}
- name << " (#{subtype})" if subtype == 'directive' || subtype == 'filter'
- name.prepend("#{type}.") unless type.starts_with?('ng ') || name == type
- name
- elsif slug.start_with?('guide')
- name = URI.decode(at_css('.improve-docs')['href'][/message=docs\(guide%2F(.+?)\)/, 1])
- name.prepend 'Guide: '
- name
+ name = at_css('header.hero h1').content.strip
+ name = name.split(':').first
+
+ if mod
+ if name == 'Testing'
+ return "#{mod.capitalize} Testing"
+ elsif name == 'Index' || name == 'Angular'
+ return mod
+ end
end
+
+ name << '()' if at_css('.status-badge').try(:content) == 'Function'
+ name
end
def get_type
- if slug.start_with?('api')
- type = slug.split('/').drop(1).first
- type << " #{subtype}s" if type == 'ng' && subtype
- type
- elsif slug.start_with?('guide')
+ if slug.start_with?('guide/')
'Guide'
+ else
+ type = at_css('.is-nav-title-selected').content.strip
+ type.remove! ' Reference'
+ type << ": #{mod}" if mod
+ type
end
end
- def subtype
- return @subtype if defined? @subtype
- node = at_css '.api-profile-header-structure'
- data = node.content.match %r{(\w+?) in module} if node
- @subtype = data && data[1]
- end
+ INDEX = Set.new
- def additional_entries
- return [] unless slug.start_with?('api')
- entries = []
+ def include_default_entry?
+ INDEX.add?([name, type].join(';')) ? true : false # ¯\_(ツ)_/¯
+ end
- css('ul.defs').each do |list|
- list.css('> li[id]').each do |node|
- next unless heading = node.at_css('h3')
- name = heading.content.strip
- name.sub! %r{\(.*\);}, '()'
- name.prepend "#{self.name.split.first}."
- entries << [name, node['id']]
- end
- end
+ private
- entries
+ def mod
+ @mod ||= slug[/api\/([\w\-]+)\//, 1]
end
end
end
diff --git a/lib/docs/filters/angularjs/clean_html.rb b/lib/docs/filters/angularjs/clean_html.rb
new file mode 100644
index 00000000..169417d2
--- /dev/null
+++ b/lib/docs/filters/angularjs/clean_html.rb
@@ -0,0 +1,98 @@
+module Docs
+ class Angularjs
+ class CleanHtmlFilter < Filter
+ def call
+ root_page? ? root : other
+
+ # Remove ng-* attributes
+ css('*').each do |node|
+ node.attributes.each_key do |attribute|
+ node.remove_attribute(attribute) if attribute.start_with? 'ng-'
+ end
+ end
+
+ doc
+ end
+
+ def root
+ css('.nav-index-group').each do |node|
+ if heading = node.at_css('.nav-index-group-heading')
+ heading.name = 'h2'
+ end
+ node.parent.before(node.children)
+ end
+
+ css('.nav-index-section').each do |node|
+ node.content = node.content
+ end
+
+ css('.toc-close', '.naked-list').remove
+ end
+
+ def other
+ css('#example', '.example', '#description_source', '#description_demo', '[id$="example"]', 'hr').remove
+
+ css('header').each do |node|
+ node.before(node.children).remove
+ end
+
+ if h1 = at_css('h1')
+ h1.prepend_child(css('.view-source', '.improve-docs'))
+ end
+
+ # Remove root-level
+ while div = at_css('h1 + div')
+ div.before(div.children)
+ div.remove
+ end
+
+ css('.api-profile-header-structure > li').each do |node|
+ node.inner_html = node.inner_html.remove('- ')
+ end
+
+ css('h1').each_with_index do |node, i|
+ next if i == 0
+ node.name = 'h2'
+ end
+
+ # Remove examples
+ css('.runnable-example').each do |node|
+ node.parent.remove
+ end
+
+ # Remove dead links (e.g. ngRepeat)
+ css('a.type-hint').each do |node|
+ node.name = 'code'
+ node.remove_attribute 'href'
+ end
+
+ css('pre > code').each do |node|
+ node['class'] ||= ''
+ lang = if node['class'].include?('lang-html') || node.content =~ /\A
+ 'html'
+ elsif node['class'].include?('lang-css')
+ 'css'
+ elsif node['class'].include?('lang-js') || node['class'].include?('lang-javascript')
+ 'javascript'
+ end
+ node.parent['data-language'] = lang if lang
+
+ node.before(node.children).remove
+ end
+
+ # Remove some elements
+ css('h1 > code', 'h2 > code', 'h3 > code', 'h4 > code', 'h6 > code').each do |node|
+ node.before(node.content).remove
+ end
+
+ css('ul.methods', 'ul.properties', 'ul.events').add_class('defs').each do |node|
+ node.css('> li > h3').each do |h3|
+ next if h3.content.present?
+ h3.content = h3.next_element.content
+ h3.next_element.remove
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/angular/clean_urls.rb b/lib/docs/filters/angularjs/clean_urls.rb
similarity index 94%
rename from lib/docs/filters/angular/clean_urls.rb
rename to lib/docs/filters/angularjs/clean_urls.rb
index 09e93a85..296b21fe 100644
--- a/lib/docs/filters/angular/clean_urls.rb
+++ b/lib/docs/filters/angularjs/clean_urls.rb
@@ -1,5 +1,5 @@
module Docs
- class Angular
+ class Angularjs
class CleanUrlsFilter < Filter
def call
html.gsub! %r{angularjs\.org/([\d\.]+)/docs/partials/(\w+)/}, 'angularjs.org/\1/docs/\2/'
diff --git a/lib/docs/filters/angularjs/entries.rb b/lib/docs/filters/angularjs/entries.rb
new file mode 100644
index 00000000..ded278ad
--- /dev/null
+++ b/lib/docs/filters/angularjs/entries.rb
@@ -0,0 +1,53 @@
+module Docs
+ class Angularjs
+ class EntriesFilter < Docs::EntriesFilter
+ def get_name
+ if slug.start_with?('api')
+ name = URI.unescape(slug).split('/').last
+ name.remove! %r{\Ang\.}
+ name << " (#{subtype})" if subtype == 'directive' || subtype == 'filter'
+ name.prepend("#{type}.") unless type.starts_with?('ng ') || name == type
+ name
+ elsif slug.start_with?('guide')
+ name = URI.decode(at_css('.improve-docs')['href'][/message=docs\(guide%2F(.+?)\)/, 1])
+ name.prepend 'Guide: '
+ name
+ end
+ end
+
+ def get_type
+ if slug.start_with?('api')
+ type = slug.split('/').drop(1).first
+ type << " #{subtype}s" if type == 'ng' && subtype
+ type
+ elsif slug.start_with?('guide')
+ 'Guide'
+ end
+ end
+
+ def subtype
+ return @subtype if defined? @subtype
+ node = at_css '.api-profile-header-structure'
+ data = node.content.match %r{(\w+?) in module} if node
+ @subtype = data && data[1]
+ end
+
+ def additional_entries
+ return [] unless slug.start_with?('api')
+ entries = []
+
+ css('ul.defs').each do |list|
+ list.css('> li[id]').each do |node|
+ next unless heading = node.at_css('h3')
+ name = heading.content.strip
+ name.sub! %r{\(.*\);}, '()'
+ name.prepend "#{self.name.split.first}."
+ entries << [name, node['id']]
+ end
+ end
+
+ entries
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/angular.rb b/lib/docs/scrapers/angular.rb
index 5b407738..c76e83c1 100644
--- a/lib/docs/scrapers/angular.rb
+++ b/lib/docs/scrapers/angular.rb
@@ -1,68 +1,59 @@
module Docs
class Angular < UrlScraper
- self.name = 'Angular.js'
- self.slug = 'angular'
self.type = 'angular'
- self.root_path = 'api.html'
- self.initial_paths = %w(guide.html)
-
- html_filters.push 'angular/clean_html', 'angular/entries', 'title'
- text_filters.push 'angular/clean_urls'
-
- options[:title] = false
- options[:root_title] = 'Angular.js'
-
- options[:decode_and_clean_paths] = true
- options[:fix_urls_before_parse] = ->(str) do
- str.gsub!('[', '%5B')
- str.gsub!(']', '%5D')
- str
- end
-
- options[:fix_urls] = ->(url) do
- %w(api guide).each do |str|
- url.sub! "/partials/#{str}/#{str}/", "/partials/#{str}/"
- url.sub! %r{/#{str}/img/}, "/img/"
- url.sub! %r{/#{str}/(.+?)/#{str}/}, "/#{str}/"
- url.sub! %r{/partials/#{str}/(.+?)(? 'guide/testing.html',
+ 'glossary.html' => 'guide/glossary.html',
+ 'tutorial' => 'tutorial/'
+ }
+
+ options[:fix_urls] = -> (url) do
+ url.sub! %r{\A(https://angular\.io/docs/.+/)index\.html\z}, '\1'
+ url.sub! %r{\A(https://angular\.io/docs/.+/index)/\z}, '\1'
url
end
- options[:only_patterns] = [%r{\Aapi/}, %r{\Aguide/}]
- options[:skip] = %w(api/ng.html)
-
options[:attribution] = <<-HTML
© 2010–2016 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
HTML
- stub '' do
+ stub 'api/' do
capybara = load_capybara_selenium
- capybara.app_host = 'https://code.angularjs.org'
- capybara.visit("/#{self.class.release}/docs/api")
- capybara.execute_script("return document.querySelector('.side-navigation').innerHTML")
- end
-
- version '1.5' do
- self.release = '1.5.6'
- self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
+ capybara.app_host = 'https://angular.io'
+ capybara.visit('/docs/ts/latest/api/')
+ capybara.execute_script('return document.body.innerHTML')
end
- version '1.4' do
- self.release = '1.4.11'
- self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
+ version '2.0 TypeScript' do
+ self.release = '2.0.0rc1'
+ self.base_url = "https://angular.io/docs/ts/latest/"
end
- version '1.3' do
- self.release = '1.3.20'
- self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
- end
+ private
- version '1.2' do
- self.release = '1.2.29'
- self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
+ def parse(string)
+ string.gsub! '(str) do
+ str.gsub!('[', '%5B')
+ str.gsub!(']', '%5D')
+ str
+ end
+
+ options[:fix_urls] = ->(url) do
+ %w(api guide).each do |str|
+ url.sub! "/partials/#{str}/#{str}/", "/partials/#{str}/"
+ url.sub! %r{/#{str}/img/}, "/img/"
+ url.sub! %r{/#{str}/(.+?)/#{str}/}, "/#{str}/"
+ url.sub! %r{/partials/#{str}/(.+?)(?
+ Licensed under the Creative Commons Attribution License 4.0.
+ HTML
+
+ stub '' do
+ capybara = load_capybara_selenium
+ capybara.app_host = 'https://code.angularjs.org'
+ capybara.visit("/#{self.class.release}/docs/api")
+ capybara.execute_script("return document.querySelector('.side-navigation').innerHTML")
+ end
+
+ version '1.5' do
+ self.release = '1.5.6'
+ self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
+ end
+
+ version '1.4' do
+ self.release = '1.4.11'
+ self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
+ end
+
+ version '1.3' do
+ self.release = '1.3.20'
+ self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
+ end
+
+ version '1.2' do
+ self.release = '1.2.29'
+ self.base_url = "https://code.angularjs.org/#{release}/docs/partials/"
+ end
+ end
+end
diff --git a/public/icons/docs/angular/16.png b/public/icons/docs/angular/16.png
index 65f79fc7..c2da47dd 100644
Binary files a/public/icons/docs/angular/16.png and b/public/icons/docs/angular/16.png differ
diff --git a/public/icons/docs/angular/16@2x.png b/public/icons/docs/angular/16@2x.png
index 62518f7d..10125c54 100644
Binary files a/public/icons/docs/angular/16@2x.png and b/public/icons/docs/angular/16@2x.png differ
diff --git a/public/icons/docs/angular/SOURCE b/public/icons/docs/angular/SOURCE
index e25f07fc..0358b69e 100644
--- a/public/icons/docs/angular/SOURCE
+++ b/public/icons/docs/angular/SOURCE
@@ -1 +1 @@
-https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports
+https://angular.io/presskit.html
diff --git a/public/icons/docs/angularjs/16.png b/public/icons/docs/angularjs/16.png
new file mode 100644
index 00000000..65f79fc7
Binary files /dev/null and b/public/icons/docs/angularjs/16.png differ
diff --git a/public/icons/docs/angularjs/16@2x.png b/public/icons/docs/angularjs/16@2x.png
new file mode 100644
index 00000000..62518f7d
Binary files /dev/null and b/public/icons/docs/angularjs/16@2x.png differ
diff --git a/public/icons/docs/angularjs/SOURCE b/public/icons/docs/angularjs/SOURCE
new file mode 100644
index 00000000..e25f07fc
--- /dev/null
+++ b/public/icons/docs/angularjs/SOURCE
@@ -0,0 +1 @@
+https://github.com/angular/angular.js/tree/master/images/logo/AngularJS-Shield.exports