From b78244fb536cc5fdbff311d0b9e81e327af2179b Mon Sep 17 00:00:00 2001 From: Thibaut Courouble Date: Sun, 12 Jun 2016 17:14:57 -0400 Subject: [PATCH] Add Angular 2 documentation --- assets/images/icons.png | Bin 46840 -> 47526 bytes assets/images/icons@2x.png | Bin 122157 -> 123407 bytes assets/javascripts/app/app.coffee | 1 + assets/javascripts/news.json | 8 +- .../templates/pages/about_tmpl.coffee | 2 +- assets/javascripts/views/pages/simple.coffee | 1 + assets/stylesheets/application-dark.css.scss | 1 + assets/stylesheets/application.css.scss | 1 + assets/stylesheets/global/_icons.scss | 3 +- assets/stylesheets/pages/_angular.scss | 73 ++++++------ assets/stylesheets/pages/_angularjs.scss | 54 +++++++++ lib/app.rb | 8 +- lib/docs/filters/angular/clean_html.rb | 109 ++++++++---------- lib/docs/filters/angular/entries.rb | 59 ++++------ lib/docs/filters/angularjs/clean_html.rb | 98 ++++++++++++++++ .../{angular => angularjs}/clean_urls.rb | 2 +- lib/docs/filters/angularjs/entries.rb | 53 +++++++++ lib/docs/scrapers/angular.rb | 87 +++++++------- lib/docs/scrapers/angularjs.rb | 68 +++++++++++ public/icons/docs/angular/16.png | Bin 791 -> 727 bytes public/icons/docs/angular/16@2x.png | Bin 1817 -> 1306 bytes public/icons/docs/angular/SOURCE | 2 +- public/icons/docs/angularjs/16.png | Bin 0 -> 791 bytes public/icons/docs/angularjs/16@2x.png | Bin 0 -> 1817 bytes public/icons/docs/angularjs/SOURCE | 1 + 25 files changed, 442 insertions(+), 189 deletions(-) create mode 100644 assets/stylesheets/pages/_angularjs.scss create mode 100644 lib/docs/filters/angularjs/clean_html.rb rename lib/docs/filters/{angular => angularjs}/clean_urls.rb (94%) create mode 100644 lib/docs/filters/angularjs/entries.rb create mode 100644 lib/docs/scrapers/angularjs.rb create mode 100644 public/icons/docs/angularjs/16.png create mode 100644 public/icons/docs/angularjs/16@2x.png create mode 100644 public/icons/docs/angularjs/SOURCE diff --git a/assets/images/icons.png b/assets/images/icons.png index 6158f619b3a017f7ca72a96d156fd8a38173c100..65c1434f3a2a73eb8afd17679aaccd3815ab5294 100644 GIT binary patch delta 8388 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 LMNUMnLSO-cQ&aC; diff --git a/assets/images/icons@2x.png b/assets/images/icons@2x.png index 2b7bbcfaf241859486a889b5bb35a192a380aaac..1135557b6f3d378ae64f8de07805403cf22e5fa3 100644 GIT binary patch delta 14285 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 delta 13025 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

{!Tw&wjn-(xn%u_D za7}{|!N+To@TuPv(V zMgXR0+CCNxBM83qh~mauaLq|OjRfY#XhQxw%-B(<*sXa zEWqIaNQK`Mq=M-xn6n2Uy9yQ_f{g->VfYJ=La>jP9)Eo{l;(03s!Hp8d=~!2WlwLE z;N_Q5F&kR`wOrnkvsBT%TdFu#u|m;eC@iV!a(15w&dfKYt6L1(e4`;Z^AIEOh)3KZ zj7+pbxJgv&Bl9~8?L9`0Dn1Y6^#DJ;&nEFl;yf{}^x*;E^8?Tog1k(h9x?$S7>Y0i zm$)9Angular 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

- while div = at_css('h1 + div') - div.before(div.children) - div.remove + css('a[name]:empty').each do |node| + node.next_element['id'] = node['name'] if node.next_element end - css('.api-profile-header-structure > li').each do |node| - node.inner_html = node.inner_html.remove('- ') + css('tr[style]').each do |node| + node.remove_attribute 'style' end - css('h1').each_with_index do |node, i| - next if i == 0 + css('h1:not(:first-child)').each do |node| node.name = 'h2' - end + end unless at_css('h2') - # Remove examples - css('.runnable-example').each do |node| - node.parent.remove + 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 - # Remove dead links (e.g. ngRepeat) - css('a.type-hint').each do |node| - node.name = 'code' - node.remove_attribute 'href' + css('.example-title + pre').each do |node| + node['name'] = node.previous_element.content.strip + node.previous_element.remove end - css('pre > code').each do |node| - node['class'] ||= '' - lang = if node['class'].include?('lang-html') || node.content =~ /\A\n\n" + node.content + when 'css' then node.content = "/* #{node['name']} */\n\n" + node.content + else node.content = "// #{node['name']}\n\n" + node.content end - node.parent['data-language'] = lang if lang + end - node.before(node.children).remove + css('a.is-button > h3').each do |node| + node.parent.content = node.content end - # Remove some 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 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 65f79fc738b9cc273316090d72c6fd53a0b1c5d3..c2da47ddac62d6fc78411ddb0385be40bd474b3a 100644 GIT binary patch delta 703 zcmV;w0zmzj2G<3UB!8YsL_t(|0d=olNf;J(Hwlh* zX?oyqd5=%xC&XtD&&)JlJb=$z`~?Acoh_qsm~I!E9tj*&kbhv+$T^xTEyJ&QkNof} zSsc>v**74MXJ(I-D$%^Hcq3JS#Y1=PvKGI(2*J5Ibk#T3=Ag7xiVRFNH=rhcI%^O~kLd*4ym*wJzW9-sxr{Dc*cos&N0DP6-cDu}_H!R|1kCqs} z6g((G`qaXN3Sln@u3WPbnp|E|6%xD l5r7ZaFz%Jni@i1eK?fEqG!HZM-KPKm002ovPDHLkV1nF8V7veT delta 767 zcmV%-I zSy^eCRs?2dpNyPQ8D2hE5~{{BM7IYX zcwcyb&+qb_!~CwA#>O_V9UYl`XJ>|)&dk4*VQ47esneNZF@LcJ=bgK=gN4Pg7ZyRF zvtTr~@!j27-00}WpFn1_d40RXam>Q9t%C+>k*cH@JH7GdQ|~lfZ@VDyizj(=+S}Vc&-E(eCDmcz7bBY7OCHUVVn{x!JsViF~dnochtYL+_3&ehe!W zNGLjb9U3AoFPc@3c8?zq^J@pwxYL^{kWmnM{oJyhN%iYp@10U|X7 z;dRl+)?(t#MkL;Dz**;NQ^0(LDWdaY_!WBJ)S~+LoN-q!Wp?Ou@I&KDC5DJNE{Nc=^cjqi)}c?a)A!uap8Zf^?XR&Q;pQfIDZ7DPJW9^jIu2#!}u59Kwx%s9MM%< z5p=D$2%vr-9B`cF0&T$&>U#f~{jaaQ3yD+;!w)@+i)(n^aZ z+ka#Qd8q0+w(^nAjMEu{4XY_cz&cER@+Blva~LEsy==7< zcJXf)1PaS=Hm{UOYmugV1TKHtgh0Vsvk8eVXneg~bFo|i4G}~f6%QrZc-GV)Jvj}5 zKU#l8EMFcJ?c<`5Gvb-F5cyU|;~YujABmfgYsz+XAJ?qd+1W03#=002ovPDHLkU;%<-VryXl delta 1803 zcmV+m2lV)w3YiX&BYy_qNkl0B8K1+5y1!u3~iat_r3QmGcX`=MN|+BYAt2j!M4*v7i6jE@x1TV zPR1$I&`6V;>9jN7IrrRq&wVcqK!?IGjJr(JoGpZyR#a4UXMabZb3-4NQr=C_eABXu zjbJcl2VK~~AcX5y3)?Q_|EK%?{(Jsc0_uU5W#yZWQyg&JS_K&1vlm~lT!kMVe+t&b zNsw#S!u9#!gn}?#w@z4AfMn)6j?=kA1o*{!_>dXQYQF~>3L(7Lhp$$x#;J+VpuFE8 zRCdcm`O}l(jDLI>vP(K-pZ*X}PJ~>(0?wzq;c8{-P209vrumEqQW9WI@8ySP@(X^$ zb?Ox8L1y*k>NPk?pz{8MQJL8b6+N;M>GdEgvT_i0Sc3I$Kz7fB?9mG{y@&oir!U0# zCm;)!!r8F{uInmgF7nw2iSbe(5J*o;OY7tj;G3b8xPQcOT0r;h!BXG+NePX3?XPXD&wF@ah3$m3yD}m10t!q2C&02qCp?7)0yq8f2Wlb_$bbEQ7^bOJ7_L;vN<~1Ed~P1tb2Y`q z#doCne7;))j{Vc;8{cNL^-i6AdQZf5>{Qu%5#9VQn`;pa+xEg-x~zQ_SY~_4Qq_p3 z6t*{l0m}+~_R+S~+4t;?$}x|jp{fdv%)YU@8fA}+gEeFrjKV?~Lh!Xn*EcgOWeFTM zJbx7kw)y~VYg^d2kF!4L`kmjs2Vz^c>g=yxMV+q@rBuXb#wIh0tMFR8Dg?J}Qv^P0 zB|!Eo4zP};tRW4i?d(U6Mngq~&Yt6UZfZVC*)z7vHaAbJAcglThvl`c0!LCgW{_TE zO1Zq1fLbtYMw}iu9u)*@EBl&Fn|1bAu79A;4I#p2E9GZB0$tP9Y{ylgB5kVBLe^!n z3bT~}$6>fh0zXcft_&!V02Qgo9fA6?GM)XUOQ>G87L_9&LfPoCu=zkaBo~s_t0qDB zLLq^YRM0-bB!!fUz_54;45KSY@yd7e7pPH8%D#I2n_l*fjg3lvHexjzYidw^_J1s- z->-mm324iF7VAqD3YH|Rpx#fP0mHJcD9ly@oX6W}MpfT%j7T6c`$0odfBLk}{^CUv zxr(Mgn{n~lHN;3rhC-^LROk{&seOTUmbt?dRp1C(FD^uYSPHY1KsX$}g#=D~vEePX zcoMR&TDe+vy$4=@rX00gwY9tVpnr~Mg6JnZVR2iUD_7~@DmJ%lQO&4TSX_{(0)Myp zd4pIAGhrRG1lExcw{i?Ua6OLw2I9i;6RPfB392`2#M%41dWIBX{Ms^x^55vv9dgX0 zx(q^S6^6!DP_NEA?;=1fg_%e|$`20h-HYUuBxhI8jo$$w22X_=A= zMk&K?qti{gD(kE#V$tHb3S7;>ox4Ee`yhz`85bNN^WSpwv=`*`!-b>YqVe)&FZ-JN$fi|TZ4sF4knzv7*9tbv?+ag6(tBOsc>cU+ zJY2=?5zvv<8|HiOYZY8qO@D;;ijfb&;olTiatTUGh6r}@iTqjKxga`v96@Jr_fPRQ zV5E0n4cjP=d|V#X|3B&4v~JQD^?GkTCCq{gw7OQy1GhUa(@ zJsIs0NG3s0`9L=aTC=rw9fB%*)BJ_^h`W;rv^ZjCp7}TO%zxn^O@HMmS8dtgTl7S`7 zOD-ya8!#Y3p_s6&*VRqxhA$>Uh)iMI+s&YR`4H~~-_M(`##En_NyH`Gu3b1jd#*R8Wh6o)(w7qM5qDpq0=`7x zt(3a^&A1y5r>k>vTxGmG#;GqJgQ+65FFjV t8Gc3XCf<&dgFl_r&4$3E)%%XdKbumc=5m&KM*si-07*qoLs 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 0000000000000000000000000000000000000000..65f79fc738b9cc273316090d72c6fd53a0b1c5d3 GIT binary patch literal 791 zcmV+y1L*vTP)q}E%7(ey3KOji#TNLV?IyEg3N=QqoM7mg}SXo(VnpOm6W}l3lQ5jx7SQ4qztuxPM zJ7=4hnJ^_&L_tW=ZKu4HF_WYS`}KH6Rz$Z49(Z4Pf6wpooWuOCn#RU9upJ$ld}n8d zna<3=lwoKn;HlG@VKK1==bgK=gN4Pg7ZyRFvtTr~@!j27-00}WpFn1_d40RXam>Q9 ztgrS#s{=?0f3bMEov=(Jh2pHZGL68xj_L;!O7u2AJN3I~z3`2UU@|coQd~Uv z`_MBKpq1m%L1s>YKyxjrc_&BD|=D~eB7t+DQ5Yi5)3iz5DRe_zh zz%?~BGvA8ixQfaBX_zL@i}-@M+j_V+1z~~)N-MrM2dV6w-L7WgNZAL@Y_9nJG1+YA zUs7%C+>k*cH@J0B8K1+5y1!u3~iat z_r3QmGcX`=MN|+BYAt2j!M4*v7i6jE@x1TVPR1$I&`6V;>9jN7IrrRq&wVcqK!?IG zjJr(JoGpZyR#a4UXGfoNLm!q>-c8Va)3S<d;V7f z>VcMJ<(rOE9B|!Q1sLA57hkVjg&!V&3f9C)kZab$_4(k0f-qgTPFPleWac`K)44+g z_{DqpkQvNszXuu$A-vazuU4(bsfo{^yx$;HcFRQh)05$hd>FDzI%J>z5Km5oT)qO% zr@P^5W$I1awpph6j0aK@U`_Akhi38%e#3R@6zD-__2ud{I7y)L{)17O*$WjtvJvU^ zAS$wQ5Or9B^>09S&xGvJ3o^Zj{ynEJ#P}y53zov!u>-E_DrGM6*$0X7QXmjWPfJVd z_x-wxMt6q!pD<_MD>uQHz>K71HQ-rA@^2Mi%-HY($wNpY40&I^fH zLjxqGHkU2;zzCicB%{f(WU^Nd#KU7CUR{jvfdgPeKc8kuIf}Ky$;nd@<%g~Vnvi{T z(o{6n*J}kV3r0~9WZuZQ3aO%72ITM&kfsSHKPrtZGD;k$`PhONl-#Mnb@mxqs4Xl) zQ*$$7wY46BfNjHkEv`a}(52zzF!5%u7ufN4l-PFc>t!q2C&02qCp?7)0yq8f2Wlb_ z$o+m8rm0mJu2jfMML?5$ZXVckHO0lnccl4zzFPy1{nO_g-)6J*PMv*vPsDcYRM~qG z-TW?_YY`0F_QG7ctbG+&W_!s})rhAQwl{(S%L;w=(YDmt_w0?zF^{34stS$FzOlL* zWsi)5HDnl!!a^8A@U=+SH!~|`2^=;&6$rNa0Bvhq*td_fKIr_bP|wwXFh2QaNUjUSmqRyp@1jFl!6b#0iomdV2@InvNAb#c^B1U5Ov=7` z{hMC)jg5^;el}t?8f$7$efBJ*->-mm324iF7VAqD3YH|Rpx#fP0mHJcD9ly@oX6W} zMpfT%j7T6c`$0odfBLk}{^CUvxr(Mgn{n~lHN;3rhC-^LROk{&seOTUmbt?dRp1C( zFD^uYSPHY1KsX$}g#=D~vEePXcoMR&TDe+vy$4=@rX00gwY9tVppIvP=qEd2aa)=z zSLxs?Hn(h1&8SsaT#%>&f4BL0gIEePVI8vs){zglatu9iJ&yeb;==J0s_tG1syA%J z+55YCh7@7^+A@an-{{gEa?GQ;3_@rXhQ?J;ug*K~B0wyKnMgp&4-W0!i}Jn$6}Sgd zwP=azdN2EibLUXWO%`dHk_tvC!)~L~O}Z-UtS4g8;l7S`7OD-ya8!#Y3p_s6&*VRqxhA$>Uh)iMI+s&YR`4H~~-_M(` z##En_NyH