angular.rb 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. require 'yajl/json_gem'
  2. module Docs
  3. class Angular < UrlScraper
  4. self.type = 'angular'
  5. self.links = {
  6. home: 'https://angular.io/',
  7. code: 'https://github.com/angular/angular'
  8. }
  9. self.base_url = 'https://angular.io/'
  10. self.root_path = 'docs'
  11. html_filters.push 'angular/clean_html', 'angular/entries'
  12. options[:max_image_size] = 256_000
  13. options[:attribution] = <<-HTML
  14. &copy; 2010&ndash;2022 Google, Inc.<br>
  15. Licensed under the Creative Commons Attribution License 4.0.
  16. HTML
  17. options[:follow_links] = false
  18. options[:only_patterns] = [/\Aguide/, /\Atutorial/, /\Aapi/]
  19. options[:fix_urls_before_parse] = ->(url) do
  20. url.sub! %r{\Aguide/}, '/guide/'
  21. url.sub! %r{\Atutorial/}, '/tutorial/'
  22. url.sub! %r{\Aapi/}, '/api/'
  23. url.sub! %r{\Agenerated/}, '/generated/'
  24. url
  25. end
  26. module Common
  27. private
  28. def initial_urls
  29. initial_urls = []
  30. Request.run "#{self.class.base_url}generated/navigation.json" do |response|
  31. data = JSON.parse(response.body)
  32. dig = ->(entry) do
  33. initial_urls << url_for("generated/docs/#{entry['url']}.json") if entry['url'] && entry['url'] != 'api'
  34. entry['children'].each(&dig) if entry['children']
  35. end
  36. data['SideNav'].each(&dig)
  37. end
  38. Request.run "#{self.class.base_url}generated/docs/api/api-list.json" do |response|
  39. data = JSON.parse(response.body)
  40. dig = ->(entry) do
  41. initial_urls << url_for("generated/docs/#{entry['path']}.json") if entry['path']
  42. initial_urls << url_for("generated/docs/api/#{entry['name']}.json") if entry['name'] && !entry['path']
  43. entry['items'].each(&dig) if entry['items']
  44. end
  45. data.each(&dig)
  46. end
  47. initial_urls
  48. end
  49. def handle_response(response)
  50. if response.mime_type.include?('json')
  51. begin
  52. json = JSON.parse(response.body)
  53. response.options[:response_body] = json['contents']
  54. response.url.path = response.url.path.gsub(/generated\/docs\/.*/, json['id'])
  55. response.effective_url.path = response.effective_url.path.gsub(/generated\/docs\/.*/, json['id'])
  56. rescue JSON::ParserError
  57. response.options[:response_body] = ''
  58. end
  59. response.headers['Content-Type'] = 'text/html'
  60. end
  61. super
  62. end
  63. end
  64. module Since12
  65. def url_for(path)
  66. # See encodeToLowercase im aio/tools/transforms/angular-base-package/processors/disambiguateDocPaths.js
  67. path = path.gsub(/[A-Z_]/) {|s| s.downcase + '_'}
  68. super
  69. end
  70. include Docs::Angular::Common
  71. end
  72. version do
  73. self.release = '15.0.0'
  74. self.base_url = 'https://angular.io/'
  75. include Docs::Angular::Since12
  76. end
  77. version '14' do
  78. self.release = '14.2.11'
  79. self.base_url = 'https://angular.io/'
  80. include Docs::Angular::Since12
  81. end
  82. version '13' do
  83. self.release = '13.3.8'
  84. self.base_url = 'https://v13.angular.io/'
  85. include Docs::Angular::Since12
  86. end
  87. version '12' do
  88. self.release = '12.2.13'
  89. self.base_url = 'https://v12.angular.io/'
  90. include Docs::Angular::Since12
  91. end
  92. version '11' do
  93. self.release = '11.2.14'
  94. self.base_url = 'https://v11.angular.io/'
  95. include Docs::Angular::Common
  96. end
  97. version '10' do
  98. self.release = '10.2.3'
  99. self.base_url = 'https://v10.angular.io/'
  100. include Docs::Angular::Common
  101. end
  102. version '9' do
  103. self.release = '9.1.12'
  104. self.base_url = 'https://v9.angular.io/'
  105. include Docs::Angular::Common
  106. end
  107. version '8' do
  108. self.release = '8.2.14'
  109. self.base_url = 'https://v8.angular.io/'
  110. include Docs::Angular::Common
  111. end
  112. version '7' do
  113. self.release = '7.2.15'
  114. self.base_url = 'https://v7.angular.io/'
  115. include Docs::Angular::Common
  116. end
  117. version '6' do
  118. self.release = '6.1.10'
  119. self.base_url = 'https://v6.angular.io/'
  120. include Docs::Angular::Common
  121. end
  122. version '5' do
  123. self.release = '5.2.11'
  124. self.base_url = 'https://v5.angular.io/'
  125. include Docs::Angular::Common
  126. end
  127. version '4' do
  128. self.release = '4.4.6'
  129. self.base_url = 'https://v4.angular.io/'
  130. include Docs::Angular::Common
  131. end
  132. version '2' do
  133. self.release = '2.4.10'
  134. self.base_url = 'https://v2.angular.io/docs/ts/latest/'
  135. self.root_path = 'api/'
  136. html_filters.push 'angular/entries_v2', 'angular/clean_html_v2'
  137. stub 'api/' do
  138. base_url = URL.parse(self.base_url)
  139. capybara = load_capybara_selenium
  140. capybara.app_host = base_url.origin
  141. capybara.visit(base_url.path + 'api/')
  142. capybara.execute_script('return document.body.innerHTML')
  143. end
  144. options[:skip_patterns] = [/deprecated/, /VERSION-let/]
  145. options[:skip] = %w(
  146. index.html
  147. styleguide.html
  148. quickstart.html
  149. cheatsheet.html
  150. guide/cheatsheet.html
  151. guide/style-guide.html)
  152. options[:replace_paths] = {
  153. 'testing/index.html' => 'guide/testing.html',
  154. 'guide/glossary.html' => 'glossary.html',
  155. 'tutorial' => 'tutorial/',
  156. 'api' => 'api/'
  157. }
  158. options[:fix_urls] = -> (url) do
  159. url.sub! %r{\A(https://(?:v2\.)?angular\.io/docs/.+/)index\.html\z}, '\1'
  160. url
  161. end
  162. end
  163. def get_latest_version(opts)
  164. get_npm_version('@angular/core', opts)
  165. end
  166. private
  167. def parse(response)
  168. response.body.gsub! '<code-example', '<pre'
  169. response.body.gsub! '</code-example', '</pre'
  170. response.body.gsub! '<code-pane', '<pre'
  171. response.body.gsub! '</code-pane', '</pre'
  172. response.body.gsub! '<live-example></live-example>', 'live example'
  173. response.body.gsub! '<live-example', '<span'
  174. response.body.gsub! '</live-example', '</span'
  175. super
  176. end
  177. end
  178. end