Update Angular documentation (4.3.2)

pull/656/merge
Thibaut Courouble 8 years ago
parent dd8c80060a
commit 3f43c03dbc

@ -119,6 +119,8 @@
for slug in @settings.getDocs() when not @docs.findBy('slug', slug) for slug in @settings.getDocs() when not @docs.findBy('slug', slug)
needsSaving = true needsSaving = true
doc = @disabledDocs.findBy('slug', 'webpack') if slug == 'webpack~2' doc = @disabledDocs.findBy('slug', 'webpack') if slug == 'webpack~2'
doc = @disabledDocs.findBy('slug', 'angular') if slug == 'angular~4_typescript'
doc = @disabledDocs.findBy('slug', 'angular~2') if slug == 'angular~2_typescript'
doc ||= @disabledDocs.findBy('slug_without_version', slug) doc ||= @disabledDocs.findBy('slug_without_version', slug)
if doc if doc
@disabledDocs.remove(doc) @disabledDocs.remove(doc)

@ -1,55 +1,22 @@
._angular { ._angular {
padding-left: 1rem; @extend %simple;
h1, h2, > h3, .banner, .badges, .breadcrumbs { margin-left: -1rem; } .pre-title { @extend %pre-heading; }
._mobile & { .breadcrumbs { @extend %note; }
padding-left: 0;
h1, h2, > h3, .banner, .badges, .breadcrumbs { margin-left: 0; }
}
h2 { @extend %block-heading; }
> h3 { @extend %block-label, %label-blue; }
.code-example > h4, .pre-title { @extend %pre-heading; }
p > code, dd > code, .status-badge { @extend %label; }
.l-sub-section, .alert, .banner, .breadcrumbs { @extend %note; }
.banner { @extend %note-green; } .banner { @extend %note-green; }
code.stable { @extend %label-green; }
code.experimental { @extend %label-orange; }
code.deprecated { @extend %label-red; }
.alert.is-important { @extend %note-red; } .alert.is-important { @extend %note-red; }
.alert.is-helpful, .breadcrumbs { @extend %note-blue; } .alert.is-helpful, .breadcrumbs { @extend %note-blue; }
.breadcrumbs { padding-left: 2em; }
td > h3, .l-sub-section > h3, .l-sub-section > h4, .alert > h3, .alert > h4, .row-margin > h3 {
margin-top: .25rem;
font-size: 1em;
}
img { .breadcrumbs { padding-left: 2em; }
display: block;
margin: 1em auto;
&[align="left"] {
float: left;
margin: 0 1em 0 0;
}
&[align="right"] { img { margin: 1em 0; }
float: right;
margin: 0 0 0 1em;
}
}
.location-badge { .location-badge {
text-align: right;
font-style: italic; font-style: italic;
} text-align: right;
.filetree {
white-space: normal;
@extend %pre;
.children { padding-left: 1em; }
} }
} }

@ -12,7 +12,7 @@
h1, h2, h3 { margin-left: 0; } h1, h2, h3 { margin-left: 0; }
} }
p > code, li > code, td > code, blockquote > code { @extend %label; } p > code, li > code, td > code, blockquote > code, dd > code { @extend %label; }
blockquote { @extend %note; } blockquote { @extend %note; }
blockquote > h4, blockquote > h5 { margin-top: .25rem; } blockquote > h4, blockquote > h5 { margin-top: .25rem; }
} }

@ -352,7 +352,9 @@ class App < Sinatra::Application
'yii1' => 'yii~1.1', 'yii1' => 'yii~1.1',
'python2' => 'python~2.7', 'python2' => 'python~2.7',
'xpath' => 'xslt_xpath', 'xpath' => 'xslt_xpath',
'angular~2.0_typescript' => 'angular~2_typescript', 'angular~4_typescript' => 'angular',
'angular~2_typescript' => 'angular~2',
'angular~2.0_typescript' => 'angular~2',
'angular~1.5' => 'angularjs~1.5', 'angular~1.5' => 'angularjs~1.5',
'angular~1.4' => 'angularjs~1.4', 'angular~1.4' => 'angularjs~1.4',
'angular~1.3' => 'angularjs~1.3', 'angular~1.3' => 'angularjs~1.3',

@ -13,7 +13,7 @@ module Docs
end end
def mime_type def mime_type
@mime_type ||= headers['Content-Type'] || 'text/plain' headers['Content-Type'] || 'text/plain'
end end
def html? def html?

@ -2,103 +2,86 @@ module Docs
class Angular class Angular
class CleanHtmlFilter < Filter class CleanHtmlFilter < Filter
def call def call
container = at_css('article.docs-content')
badges = css('header.hero .badge, header.hero .hero-subtitle').map do |node|
node.name = 'span'
node['class'] = 'status-badge'
node.to_html
end.join(' ')
badges = %(<div class="badges">#{badges}</div>)
container.child.before(at_css('header.hero h1')).before(badges).before(css('header.hero + .banner, header.hero .breadcrumbs'))
@doc = container
title = at_css('h1').content.strip
if root_page? if root_page?
css('.card-container').remove
at_css('h1').content = 'Angular Documentation' at_css('h1').content = 'Angular Documentation'
elsif title == 'Index'
at_css('h1').content = result[:entries].first.name
elsif title == 'Angular'
at_css('h1').content = slug.split('/').last.gsub('-', ' ')
elsif at_css('.breadcrumbs') && title != result[:entries].first.name
at_css('h1').content = result[:entries].first.name
end end
css('pre.no-bg-with-indent').each do |node| css('br', 'hr', '.material-icons', '.header-link').remove
node.content = ' ' + node.content.gsub("\n", "\n ")
end
css('.openParens').each do |node|
node.parent.name = 'pre'
node.parent.content = node.parent.css('code, pre').map(&:content).join("\n")
end
css('button.verbose', 'button.verbose + .l-verbose-section', 'a[id=top]', 'a[href="#top"]', '.sidebar').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', '.code-example header', 'section.desc', '.row', '.dart-api-entry-main', '.main-content', 'section.summary', 'span.signature').each do |node| css('.content', 'article', '.api-header', 'section', '.instance-member').each do |node|
node.before(node.children).remove node.before(node.children).remove
end end
css('span.badges').each do |node| css('label', 'h2 > em', 'h3 > em').each do |node|
node.name = 'div' node.name = 'code'
end end
css('pre[language]').each do |node| css('h1 + code').each do |node|
node['data-language'] = node['language'].sub(/\Ats/, 'typescript').strip node.before('<p></p>')
node['data-language'] = 'html' if node.content.start_with?('<') while node.next_element.name == 'code'
node.previous_element << ' '
node.previous_element << node.next_element
end
node.previous_element.prepend_child(node)
end end
css('pre.prettyprint').each do |node| css('td h3', '.l-sub-section > h3', '.alert h3', '.row-margin > h3', '.api-heading ~ h3', '.api-heading + h2', '.metadata-member h3').each do |node|
node.content = node.content.strip node.name = 'h4'
node['data-language'] = 'dart' if node['class'].include?('dart')
node['data-language'] = 'html' if node.content.start_with?('<')
end end
css('.multi-line-signature').each do |node| css('.l-sub-section', '.alert', '.banner').each do |node|
node.name = 'pre' node.name = 'blockquote'
node.content = node.content.strip
end end
css('a[id]:empty').each do |node| css('.file').each do |node|
node.next_element['id'] = node['id'] if node.next_element node.content = node.content.strip
end end
css('a[name]:empty').each do |node| css('.filetree .children').each do |node|
node.next_element['id'] = node['name'] if node.next_element node.css('.file').each do |n|
n.content = " #{n.content}"
end
end end
css('tr[style]').each do |node| css('.filetree').each do |node|
node.remove_attribute 'style' node.content = node.css('.file').map(&:inner_html).join("\n")
node.name = 'pre'
node.remove_attribute('class')
end end
css('h1:not(:first-child)').each do |node| css('pre').each do |node|
node.name = 'h2' node.content = node.content.strip
end unless at_css('h2')
css('img[style]').each do |node| node['data-language'] = 'typescript' if node['path'].try(:ends_with?, '.ts')
node['align'] ||= node['style'][/float:\s*(left|right)/, 1] node['data-language'] = 'html' if node['path'].try(:ends_with?, '.html')
node['style'] = node['style'].split(';').map(&:strip).select { |s| s =~ /\Awidth|height/ }.join(';') node['data-language'] = 'css' if node['path'].try(:ends_with?, '.css')
end node['data-language'] = node['language'].sub(/\Ats/, 'typescript').strip if node['language']
node['data-language'] ||= 'typescript' if node.content.start_with?('@')
css('.example-title + pre').each do |node| node.before(%(<div class="pre-title">#{node['title']}</div>)) if node['title']
node['name'] = node.previous_element.content.strip
node.previous_element.remove
end
css('pre[name]').each do |node| if node['class'] && node['class'].include?('api-heading')
node.before(%(<div class="pre-title">#{node['name']}</div>)) node.name = 'h3'
end node.inner_html = "<code>#{node.inner_html}</code>"
end
css('a.is-button > h3').each do |node| node.remove_attribute('path')
node.parent.content = node.content node.remove_attribute('region')
node.remove_attribute('linenums')
node.remove_attribute('title')
node.remove_attribute('language')
node.remove_attribute('hidecopy')
node.remove_attribute('class')
end end
css('#angular-2-glossary ~ .l-sub-section').each do |node| css('h1[class]').remove_attr('class')
node.before(node.children).remove css('table[class]').remove_attr('class')
end css('table[width]').remove_attr('width')
css('tr[style]').remove_attr('style')
location_badge = at_css('.location-badge') if at_css('.api-type-label.module')
if location_badge && doc.last_element_child != location_badge at_css('h1').content = subpath.remove('api/')
doc.last_element_child.after(location_badge)
end end
doc doc

@ -0,0 +1,157 @@
module Docs
class Angular
class CleanHtmlV2Filter < Filter
def call
container = at_css('article.docs-content')
badges = css('header.hero .badge, header.hero .hero-subtitle').map do |node|
node.name = 'span'
node['class'] = 'status-badge'
node.to_html
end.join(' ')
badges = %(<div class="badges">#{badges}</div>)
container.child.before(at_css('header.hero h1')).before(badges).before(css('header.hero + .banner, header.hero .breadcrumbs'))
@doc = container
title = at_css('h1').content.strip
if root_page?
at_css('h1').content = 'Angular 2 Documentation'
elsif title == 'Index'
at_css('h1').content = result[:entries].first.name
elsif title == 'Angular'
at_css('h1').content = slug.split('/').last.gsub('-', ' ')
elsif at_css('.breadcrumbs') && title != result[:entries].first.name
at_css('h1').content = result[:entries].first.name
end
css('pre.no-bg-with-indent').each do |node|
node.content = ' ' + node.content.gsub("\n", "\n ")
end
css('.openParens').each do |node|
node.parent.name = 'pre'
node.parent.content = node.parent.css('code, pre').map(&:content).join("\n")
end
css('button.verbose', 'button.verbose + .l-verbose-section', 'a[id=top]', 'a[href="#top"]', '.sidebar', 'br').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', '.code-example header', 'section.desc', '.row', '.dart-api-entry-main', '.main-content', 'section.summary', 'span.signature').each do |node|
node.before(node.children).remove
end
css('span.badges').each do |node|
node.name = 'div'
end
css('pre[language]').each do |node|
node['data-language'] = node['language'].sub(/\Ats/, 'typescript').strip
node['data-language'] = 'html' if node.content.start_with?('<')
node.remove_attribute('language')
node.remove_attribute('format')
end
css('pre.prettyprint').each do |node|
node.content = node.content.strip
node['data-language'] = 'dart' if node['class'].include?('dart')
node['data-language'] = 'html' if node.content.start_with?('<')
node.remove_attribute('class')
end
css('.multi-line-signature').each do |node|
node.name = 'pre'
node.content = node.content.strip
end
css('a[id]:empty').each do |node|
node.next_element['id'] = node['id'] if node.next_element
end
css('a[name]:empty').each do |node|
node.next_element['id'] = node['name'] if node.next_element
end
css('tr[style]').each do |node|
node.remove_attribute 'style'
end
css('h1:not(:first-child)').each do |node|
node.name = 'h2'
end unless at_css('h2')
css('img[style]').each do |node|
node['align'] ||= node['style'][/float:\s*(left|right)/, 1]
node['style'] = node['style'].split(';').map(&:strip).select { |s| s =~ /\Awidth|height/ }.join(';')
end
css('.example-title + pre').each do |node|
node['name'] = node.previous_element.content.strip
node.previous_element.remove
end
css('pre[name]').each do |node|
node.before(%(<div class="pre-title">#{node['name']}</div>))
end
css('a.is-button > h3').each do |node|
node.parent.content = node.content
end
css('#angular-2-glossary ~ .l-sub-section').each do |node|
node.before(node.children).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
css('.filetree .children').each do |node|
node.css('.file').each do |n|
n.content = " #{n.content}"
end
end
css('.filetree').each do |node|
node.content = node.css('.file').map(&:inner_html).join("\n")
node.name = 'pre'
node.remove_attribute('class')
end
css('.status-badge').each do |node|
node.name = 'code'
node.content = node.content.strip
node.remove_attribute('class')
end
css('div.badges').each do |node|
node.name = 'p'
end
css('td h3', '.l-sub-section > h3', '.alert h3', '.row-margin > h3').each do |node|
node.name = 'h4'
end
css('.l-sub-section', '.alert', '.banner').each do |node|
node.name = 'blockquote'
end
css('.code-example > h4').each do |node|
node['class'] = 'pre-title'
end
css('.row-margin', '.ng-cloak').each do |node|
node.before(node.children).remove
end
css('*[layout]').remove_attr('layout')
css('*[layout-xs]').remove_attr('layout-xs')
css('*[flex]').remove_attr('flex')
css('*[flex-xs]').remove_attr('flex-xs')
css('*[ng-class]').remove_attr('ng-class')
css('*[align]').remove_attr('align')
css('h1, h2, h3').remove_attr('class')
doc
end
end
end
end

@ -2,59 +2,24 @@ module Docs
class Angular class Angular
class EntriesFilter < Docs::EntriesFilter class EntriesFilter < Docs::EntriesFilter
def get_name def get_name
if slug.start_with?('tutorial') || slug.start_with?('guide') name = at_css('h1').content
name = at_css('.nav-list-item.is-selected, header.hero h1').content.strip name.prepend "#{$1}. " if subpath =~ /\-pt(\d+)/
else
name = at_css('header.hero h1').content.strip
end
name = name.split(':').first
if mod
if name == 'Index'
return slug.split('/')[1..-2].join('/')
elsif name == 'Angular'
return slug.split('/').last.split('-').first
end
end
subtitle = at_css('.hero-subtitle').try(:content)
breadcrumbs = css('.breadcrumbs li').map(&:content)[2..-2]
name.prepend "#{breadcrumbs.join('.')}#" if breadcrumbs.present? && breadcrumbs[0] != name
name << '()' if %w(Function Method Constructor).include?(subtitle)
name name
end end
def get_type def get_type
if slug.start_with?('guide/') if slug.start_with?('guide')
'Guide'
elsif slug.start_with?('cookbook/')
'Cookbook'
elsif slug == 'glossary'
'Guide' 'Guide'
elsif slug.start_with?('tutorial')
'Tutorial'
elsif node = at_css('th:contains("npm Package")')
node.next_element.content.remove('@angular/')
elsif at_css('.api-type-label.module')
name.split('/').first
else else
type = at_css('.nav-title.is-selected').content.strip 'Miscellaneous'
type.remove! ' Reference'
type << ": #{mod}" if mod
type
end end
end end
INDEX = Set.new
def include_default_entry?
INDEX.add?([name, type].join(';')) ? true : false # ¯\_(ツ)_/¯
end
private
def mod
return @mod if defined?(@mod)
@mod = slug[/api\/([\w\-\.]+)\//, 1]
@mod.remove! 'angular2.' if @mod
@mod
end
end end
end end
end end

@ -0,0 +1,60 @@
module Docs
class Angular
class EntriesV2Filter < Docs::EntriesFilter
def get_name
if slug.start_with?('tutorial') || slug.start_with?('guide')
name = at_css('.nav-list-item.is-selected, header.hero h1').content.strip
else
name = at_css('header.hero h1').content.strip
end
name = name.split(':').first
if mod
if name == 'Index'
return slug.split('/')[1..-2].join('/')
elsif name == 'Angular'
return slug.split('/').last.split('-').first
end
end
subtitle = at_css('.hero-subtitle').try(:content)
breadcrumbs = css('.breadcrumbs li').map(&:content)[2..-2]
name.prepend "#{breadcrumbs.join('.')}#" if breadcrumbs.present? && breadcrumbs[0] != name
name << '()' if %w(Function Method Constructor).include?(subtitle)
name
end
def get_type
if slug.start_with?('guide/')
'Guide'
elsif slug.start_with?('cookbook/')
'Cookbook'
elsif slug == 'glossary'
'Guide'
else
type = at_css('.nav-title.is-selected').content.strip
type.remove! ' Reference'
type << ": #{mod}" if mod
type
end
end
INDEX = Set.new
def include_default_entry?
INDEX.add?([name, type].join(';')) ? true : false # ¯\_(ツ)_/¯
end
private
def mod
return @mod if defined?(@mod)
@mod = slug[/api\/([\w\-\.]+)\//, 1]
@mod.remove! 'angular2.' if @mod
@mod
end
end
end
end

@ -1,56 +1,110 @@
require 'yajl/json_gem'
module Docs module Docs
class Angular < UrlScraper class Angular < UrlScraper
self.type = 'angular' self.type = 'angular'
self.root_path = 'api/'
self.links = { self.links = {
home: 'https://angular.io/', home: 'https://angular.io/',
code: 'https://github.com/angular/angular' code: 'https://github.com/angular/angular'
} }
html_filters.push 'angular/entries', 'angular/clean_html' options[:max_image_size] = 256_000
options[:skip_patterns] = [/deprecated/, /VERSION-let/]
options[:skip] = %w(
index.html
styleguide.html
quickstart.html
cheatsheet.html
guide/cheatsheet.html
guide/style-guide.html)
options[:replace_paths] = {
'testing/index.html' => 'guide/testing.html',
'guide/glossary.html' => 'glossary.html',
'tutorial' => 'tutorial/',
'api' => 'api/'
}
options[:fix_urls] = -> (url) do
url.sub! %r{\A(https://(?:v2\.)?angular\.io/docs/.+/)index\.html\z}, '\1'
url
end
options[:attribution] = <<-HTML options[:attribution] = <<-HTML
&copy; 2010&ndash;2017 Google, Inc.<br> &copy; 2010&ndash;2017 Google, Inc.<br>
Licensed under the Creative Commons Attribution License 4.0. Licensed under the Creative Commons Attribution License 4.0.
HTML HTML
stub 'api/' do version do
base_url = URL.parse(self.base_url) self.release = '4.3.2'
capybara = load_capybara_selenium self.base_url = 'https://angular.io/'
capybara.app_host = base_url.origin self.root_path = 'docs'
capybara.visit(base_url.path + 'api/')
capybara.execute_script('return document.body.innerHTML') html_filters.push 'angular/clean_html', 'angular/entries'
end
options[:follow_links] = false
options[:only_patterns] = [/\Aguide/, /\Atutorial/, /\Aapi/]
options[:fix_urls_before_parse] = ->(url) do
url.sub! %r{\Aguide/}, '/guide/'
url.sub! %r{\Atutorial/}, '/tutorial/'
url.sub! %r{\Aapi/}, '/api/'
url.sub! %r{\Agenerated/}, '/generated/'
url
end
private
def initial_urls
initial_urls = []
version '4 TypeScript' do Request.run 'https://angular.io/generated/navigation.json' do |response|
self.release = '4.0.3' data = JSON.parse(response.body)
self.base_url = 'https://angular.io/docs/ts/latest/' dig = ->(entry) do
initial_urls << url_for("generated/docs/#{entry['url']}.json") if entry['url'] && entry['url'] != 'api'
entry['children'].each(&dig) if entry['children']
end
data['SideNav'].each(&dig)
end
Request.run 'https://angular.io/generated/docs/api/api-list.json' do |response|
data = JSON.parse(response.body)
dig = ->(entry) do
initial_urls << url_for("generated/docs/#{entry['path']}.json") if entry['path']
initial_urls << url_for("generated/docs/api/#{entry['name']}.json") if entry['name'] && !entry['path']
entry['items'].each(&dig) if entry['items']
end
data.each(&dig)
end
initial_urls
end
def handle_response(response)
if response.mime_type.include?('json')
response.options[:response_body] = JSON.parse(response.body)['contents']
response.headers['Content-Type'] = 'text/html'
response.url.path = response.url.path.sub('/generated/docs/', '/').remove('.json')
response.effective_url.path = response.effective_url.path.sub('/generated/docs/', '/').remove('.json')
end
super
end
end end
version '2 TypeScript' do version '2' do
self.release = '2.4.10' self.release = '2.4.10'
self.base_url = 'https://v2.angular.io/docs/ts/latest/' self.base_url = 'https://v2.angular.io/docs/ts/latest/'
self.root_path = 'api/'
html_filters.push 'angular/entries_v2', 'angular/clean_html_v2'
stub 'api/' do
base_url = URL.parse(self.base_url)
capybara = load_capybara_selenium
capybara.app_host = base_url.origin
capybara.visit(base_url.path + 'api/')
capybara.execute_script('return document.body.innerHTML')
end
options[:skip_patterns] = [/deprecated/, /VERSION-let/]
options[:skip] = %w(
index.html
styleguide.html
quickstart.html
cheatsheet.html
guide/cheatsheet.html
guide/style-guide.html)
options[:replace_paths] = {
'testing/index.html' => 'guide/testing.html',
'guide/glossary.html' => 'glossary.html',
'tutorial' => 'tutorial/',
'api' => 'api/'
}
options[:fix_urls] = -> (url) do
url.sub! %r{\A(https://(?:v2\.)?angular\.io/docs/.+/)index\.html\z}, '\1'
url
end
end end
private private

Loading…
Cancel
Save