diff --git a/assets/javascripts/vendor/prism.js b/assets/javascripts/vendor/prism.js
index 81045e15..d4f82a15 100644
--- a/assets/javascripts/vendor/prism.js
+++ b/assets/javascripts/vendor/prism.js
@@ -1,4 +1,4 @@
-/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+elixir+go+json+kotlin+lua+nginx+perl+php+python+crystal+rust+scss+sql+typescript */
+/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+c+cpp+coffeescript+ruby+elixir+go+java+json+kotlin+lua+nginx+perl+php+python+crystal+rust+scss+sql+typescript */
var _self = (typeof window !== 'undefined')
? window // if in browser
: (
@@ -1054,6 +1054,23 @@ Prism.languages.go = Prism.languages.extend('clike', {
});
delete Prism.languages.go['class-name'];
+Prism.languages.java = Prism.languages.extend('clike', {
+ 'keyword': /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,
+ 'number': /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,
+ 'operator': {
+ pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,
+ lookbehind: true
+ }
+});
+
+Prism.languages.insertBefore('java','function', {
+ 'annotation': {
+ alias: 'punctuation',
+ pattern: /(^|[^.])@\w+/,
+ lookbehind: true
+ }
+});
+
Prism.languages.json = {
'property': /"(?:\\.|[^\\"])*"(?=\s*:)/ig,
'string': /"(?!:)(?:\\.|[^\\"])*"(?!:)/g,
diff --git a/assets/javascripts/views/pages/simple.coffee b/assets/javascripts/views/pages/simple.coffee
index 9f3ba6d1..d8909cf8 100644
--- a/assets/javascripts/views/pages/simple.coffee
+++ b/assets/javascripts/views/pages/simple.coffee
@@ -42,6 +42,7 @@ app.views.MomentPage =
app.views.MongoosePage =
app.views.NginxPage =
app.views.NodePage =
+app.views.OpenjdkPage =
app.views.PerlPage =
app.views.PhalconPage =
app.views.PhaserPage =
diff --git a/assets/stylesheets/application-dark.css.scss b/assets/stylesheets/application-dark.css.scss
index 16d96c6e..f9030ca5 100644
--- a/assets/stylesheets/application-dark.css.scss
+++ b/assets/stylesheets/application-dark.css.scss
@@ -66,6 +66,7 @@
'pages/nginx',
'pages/node',
'pages/npm',
+ 'pages/openjdk',
'pages/perl',
'pages/phalcon',
'pages/phaser',
diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss
index e391bfff..d83f9dd0 100644
--- a/assets/stylesheets/application.css.scss
+++ b/assets/stylesheets/application.css.scss
@@ -66,6 +66,7 @@
'pages/nginx',
'pages/node',
'pages/npm',
+ 'pages/openjdk',
'pages/perl',
'pages/phalcon',
'pages/phaser',
diff --git a/assets/stylesheets/pages/_openjdk.scss b/assets/stylesheets/pages/_openjdk.scss
new file mode 100644
index 00000000..a74d1e80
--- /dev/null
+++ b/assets/stylesheets/pages/_openjdk.scss
@@ -0,0 +1,22 @@
+._openjdk {
+ > ul.inheritance {
+ @extend %note, %note-blue;
+ li {
+ list-style: none;
+ }
+ }
+
+ ul.blockList, ul.blockListLast {
+ padding-left: 0;
+ li.blockList {
+ list-style: none;
+ }
+ }
+
+ h3 {
+ @extend %block-heading;
+ }
+ h4 {
+ @extend %block-label, %label-blue;
+ }
+}
diff --git a/lib/docs/filters/openjdk/clean_html.rb b/lib/docs/filters/openjdk/clean_html.rb
new file mode 100644
index 00000000..e605bbc3
--- /dev/null
+++ b/lib/docs/filters/openjdk/clean_html.rb
@@ -0,0 +1,88 @@
+module Docs
+ class Openjdk
+ class CleanHtmlFilter < Filter
+ def call
+ # Preserve internal fragment links
+ # Transform text
+ # into text
+ css('a[name]').each do |node|
+ if node.children.all?(&:blank?)
+ node.next_element['id'] = node['name'] if node.next_element
+ node.remove
+ end
+ end
+
+ # Find the main container
+ # Root page have three containers, we use the second one
+ container = at_css('.contentContainer' + (root_page? ? ':nth-of-type(2)' : ''))
+
+ # Move description to the container top
+ if description_link = at_css('a[href$=".description"]')
+ target = description_link['href'][1..-1]
+ description_nodes = xpath("//*[@id='#{target}'] | //*[@id='#{target}']/following-sibling::*")
+ container.prepend_child(description_nodes)
+ description_nodes.at_css('h2:contains("Description")')&.remove
+ description_link.parent.remove
+ end
+
+ # Remove superfluous and duplicated content
+ css('.subTitle', '.docSummary', '.summary caption', 'caption span.tabEnd').remove
+ css('table[class$="Summary"] > tr > th').each do |th|
+ th.parent.remove
+ end
+ css('h3[id$=".summary"]').each do |header|
+ # Keep only a minimal list of annotation required/optional elements
+ # as with "Methods inherited from class"
+ if header['id'].match? %r{\.element\.summary$}
+ table_summary = header.next_element
+ code_summary = header.document.create_element 'code'
+ table_summary.css('.memberNameLink a').each_with_index do |element, index|
+ code_summary << header.document.create_text_node(', ') if index > 0
+ code_summary << element
+ end
+ table_summary.replace(code_summary)
+ # Remove summary element if detail exists
+ elsif detail_header = at_css("h3[id='#{header['id'].sub('summary','detail')}']")
+ header.next_element.remove
+ header.replace(detail_header.parent.children)
+ end
+ end
+ at_css('.details')&.remove unless at_css('.details h3')
+ css('h3[id$=".summary"]', 'h3[id$=".detail"]', 'caption span').each do |header|
+ header.name = 'h3' if header.name == 'span'
+ content = header.content
+ content.remove! ' Summary'
+ content.remove! ' Detail'
+ header.content = content.pluralize
+ end
+ css('h4').each do |entry_header|
+ entry_pre = entry_header.next_element
+ entry_header.children = entry_pre.children
+ entry_pre.remove
+ end
+
+ # Keep only header and container
+ container.prepend_child(at_css('.header'))
+ @doc = container
+
+ # Remove packages not belonging to this version
+ if root_page?
+ at_css('.overviewSummary caption h3').content =
+ version + ' ' +
+ at_css('.overviewSummary caption h3').content
+ css('.overviewSummary td.colFirst a').each do |node|
+ unless context[:only_patterns].any? { |pattern| node['href'].match? pattern }
+ node.parent.parent.remove
+ end
+ end
+ end
+
+ # Syntax highlighter
+ css('pre').each do |node|
+ node['data-language'] = 'java'
+ end
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/openjdk/clean_urls.rb b/lib/docs/filters/openjdk/clean_urls.rb
new file mode 100644
index 00000000..ebd24c2e
--- /dev/null
+++ b/lib/docs/filters/openjdk/clean_urls.rb
@@ -0,0 +1,24 @@
+module Docs
+ class Openjdk
+ class CleanUrlsFilter < Filter
+ def call
+ # Interlink between versions
+ css('a[href^="http://localhost/"]').each do |node|
+ path = URI(node['href']).path[1..-1]
+
+ # The following code ignores most options that InternalUrlsFilter accepts,
+ # only the currently used options are considered here.
+ self.class.parent.versions.each do |v|
+ if v.options[:only_patterns].any? { |pattern| path.match? pattern } &&
+ v.options[:skip_patterns].none? { |pattern| path.match? pattern }
+ node['href'] = "/#{v.slug}/#{path}"
+ break
+ end
+ end
+ end
+
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/openjdk/entries.rb b/lib/docs/filters/openjdk/entries.rb
new file mode 100644
index 00000000..5ae8132d
--- /dev/null
+++ b/lib/docs/filters/openjdk/entries.rb
@@ -0,0 +1,39 @@
+module Docs
+ class Openjdk
+ class EntriesFilter < Docs::EntriesFilter
+ def get_name
+ name = at_css('.header > .title').content.strip
+ name.remove! 'Package '
+ name.remove! 'Class '
+ name.remove! 'Interface '
+ name.remove! 'Annotation Type '
+ name.remove! 'Enum '
+ name.remove! %r{<.*}
+ name
+ end
+
+ def get_type
+ if subtitle = at_css('.header > .subTitle:last-of-type')
+ subtitle.content.strip
+ else
+ at_css('.header > .title').content.strip.remove 'Package '
+ end
+ end
+
+ def additional_entries
+ # Only keep the first found entry with a unique name,
+ # i.e. overloaded methods are skipped in index
+ css('a[name$=".summary"]').each_with_object({}) do |summary, entries|
+ next if summary['name'] == 'nested.class.summary'
+ summary.parent.css('.memberNameLink a').each do |node|
+ entry_name = node.parent.parent.content.strip
+ entry_name.sub! %r{\(.+?\)}m, '()'
+ id = node['href']
+ id.remove! %r{.*#}
+ entries[entry_name] ||= [name + '.' + entry_name, id]
+ end
+ end.values
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/openjdk.rb b/lib/docs/scrapers/openjdk.rb
new file mode 100644
index 00000000..b8748e35
--- /dev/null
+++ b/lib/docs/scrapers/openjdk.rb
@@ -0,0 +1,88 @@
+module Docs
+ class Openjdk < FileScraper
+ self.name = 'OpenJDK'
+ self.type = 'openjdk'
+ self.root_path = 'overview-summary.html'
+ self.links = {
+ home: 'http://openjdk.java.net/',
+ code: 'http://hg.openjdk.java.net/jdk8u'
+ }
+ self.release = '8'
+ # Downloaded from packages.debian.org/sid/openjdk-8-doc
+ # extracting subdirectoy /usr/share/doc/openjdk-8-jre-headless/api
+ self.dir = '/Users/Thibaut/DevDocs/Docs/Java'
+
+ html_filters.push 'openjdk/entries', 'openjdk/clean_html'
+ html_filters.insert_after 'internal_urls', 'openjdk/clean_urls'
+
+ options[:skip_patterns] = [
+ /compact[123]-/,
+ /package-frame\.html/,
+ /package-tree\.html/,
+ /package-use\.html/,
+ /class-use\//,
+ /doc-files\//]
+
+ options[:attribution] = <<-HTML
+ © 1993–2017, Oracle and/or its affiliates. All rights reserved.
+ Use is subject to license terms.
+ We are not endorsed by or affiliated with Oracle.
+ HTML
+
+ version 'Core' do
+ options[:only_patterns] = [
+ /\Ajava\/beans\//,
+ /\Ajava\/io\//,
+ /\Ajava\/lang\//,
+ /\Ajava\/math\//,
+ /\Ajava\/net\//,
+ /\Ajava\/nio\//,
+ /\Ajava\/security\//,
+ /\Ajava\/text\//,
+ /\Ajava\/time\//,
+ /\Ajava\/util\//,
+ /\Ajavax\/annotation\//,
+ /\Ajavax\/crypto\//,
+ /\Ajavax\/imageio\//,
+ /\Ajavax\/lang\//,
+ /\Ajavax\/management\//,
+ /\Ajavax\/naming\//,
+ /\Ajavax\/net\//,
+ /\Ajavax\/print\//,
+ /\Ajavax\/script\//,
+ /\Ajavax\/security\//,
+ /\Ajavax\/sound\//,
+ /\Ajavax\/tools\//]
+ end
+
+ version 'GUI' do
+ options[:only_patterns] = [
+ /\Ajava\/awt\//,
+ /\Ajavax\/swing\//]
+ end
+
+ version 'Web' do
+ options[:only_patterns] = [
+ /\Ajava\/applet\//,
+ /\Ajava\/rmi\//,
+ /\Ajava\/sql\//,
+ /\Ajavax\/accessibility\//,
+ /\Ajavax\/activation\//,
+ /\Ajavax\/activity\//,
+ /\Ajavax\/jws\//,
+ /\Ajavax\/rmi\//,
+ /\Ajavax\/sql\//,
+ /\Ajavax\/transaction\//,
+ /\Ajavax\/xml\//,
+ /\Aorg\/ietf\//,
+ /\Aorg\/omg\//,
+ /\Aorg\/w3c\//,
+ /\Aorg\/xml\//]
+ end
+
+ # Monkey patch to properly read HTML files encoded in ISO-8859-1
+ def read_file(path)
+ File.read(path).force_encoding('iso-8859-1').encode('utf-8') rescue nil
+ end
+ end
+end