From a7a5ccec3fc44f3f2deab9ba32a5b9fe95aa9f6c Mon Sep 17 00:00:00 2001 From: Alec Theriault Date: Sun, 11 Nov 2018 20:00:30 -0800 Subject: Rename 'NewOcean' theme to 'Linuwial' --- .../resources/html/Linuwial.std-theme/linuwial.css | 891 +++++++++++++++++++++ .../resources/html/Linuwial.std-theme/synopsis.png | Bin 0 -> 11327 bytes 2 files changed, 891 insertions(+) create mode 100644 haddock-api/resources/html/Linuwial.std-theme/linuwial.css create mode 100644 haddock-api/resources/html/Linuwial.std-theme/synopsis.png (limited to 'haddock-api/resources/html/Linuwial.std-theme') diff --git a/haddock-api/resources/html/Linuwial.std-theme/linuwial.css b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css new file mode 100644 index 00000000..5450ae2e --- /dev/null +++ b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css @@ -0,0 +1,891 @@ +/* @group Fundamentals */ + +* { margin: 0; padding: 0 } + +/* Is this portable? */ +html { + background-color: white; + width: 100%; + height: 100%; +} + +body { + background: #fefefe; + color: #333; + text-align: left; + min-height: 100vh; + position: relative; + -webkit-text-size-adjust: 100%; + -webkit-font-feature-settings: "kern" 1, "liga" 0; + -moz-font-feature-settings: "kern" 1, "liga" 0; + -o-font-feature-settings: "kern" 1, "liga" 0; + font-feature-settings: "kern" 1, "liga" 0; + letter-spacing: 0.0015rem; +} + +#content a { + overflow-wrap: break-word; +} + +p { + margin: 0.8em 0; +} + +ul, ol { + margin: 0.8em 0 0.8em 2em; +} + +dl { + margin: 0.8em 0; +} + +dt { + font-weight: bold; +} +dd { + margin-left: 2em; +} + +a { text-decoration: none; } +a[href]:link { color: #9E358F; } +a[href]:visited {color: #6F5F9C; } +a[href]:hover { text-decoration:underline; } + +a[href].def:link, a[href].def:visited { color: rgba(69, 59, 97, 0.8); } +a[href].def:hover { color: rgb(78, 98, 114); } + +/* @end */ + +/* @group Show and hide with JS */ + +body.js-enabled .hide-when-js-enabled { + display: none; +} + +/* @end */ + + +/* @group responsive */ + +#package-header .caption { + margin: 0px 1em 0 2em; +} + +@media only screen and (min-width: 1280px) { + #content { + width: 63vw; + max-width: 1450px; + } + + #table-of-contents { + position: fixed; + max-width: 10vw; + top: 10.2em; + left: 2em; + bottom: 1em; + overflow-y: auto; + } + + #synopsis { + display: block; + position: fixed; + float: left; + top: 5em; + bottom: 1em; + right: 0; + max-width: 65vw; + overflow-y: auto; + /* Ensure that synopsis covers everything (including MathJAX markup) */ + z-index: 1; + } + + #synopsis .show { + border: 1px solid #5E5184; + padding: 0.7em; + max-height: 65vh; + } + +} + +@media only screen and (max-width: 1279px) { + #content { + width: 80vw; + } + + #synopsis { + display: block; + padding: 0; + position: relative; + margin: 0; + width: 100%; + } +} + +@media only screen and (max-width: 999px) { + #content { + width: 93vw; + } +} + + +/* menu for wider screens + + Display the package name at the left and the menu links at the right, + inline with each other: + The package name Source . Contents . Index +*/ +@media only screen and (min-width: 1000px) { + #package-header { + text-align: left; + white-space: nowrap; + height: 40px; + padding: 4px 1.5em 0px 1.5em; + overflow: visible; + + display: flex; + justify-content: space-between; + align-items: center; + } + + #package-header .caption { + display: inline-block; + margin: 0; + } + + #package-header ul.links { + margin: 0; + display: inline-table; + } + + #package-header .caption + ul.links { + margin-left: 1em; + } +} + +/* menu for smaller screens + +Display the package name on top of the menu links and center both elements: + The package name + Source . Contents . Index +*/ +@media only screen and (max-width: 999px) { + #package-header { + text-align: center; + padding: 6px 0 4px 0; + overflow: hidden; + } + + #package-header ul.links { + display: block; + text-align: center; + margin: 0; + + /* Hide scrollbar but allow scrolling menu links horizontally */ + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; + margin-bottom: -17px; + height: 50px; + } + + #package-header .caption { + display: block; + margin: 4px 0; + text-align: center; + } + + #package-header ul.links::-webkit-scrollbar { + display: none; + } + + #package-header ul.links li:first-of-type { + padding-left: 1em; + } + + #package-header ul.links li:last-of-type { + /* + The last link of the menu should offer the same distance to the right + as the #package-header enforces at the left. + */ + padding-right: 1em; + } + + #package-header .caption + ul.links { + padding-top: 9px; + } + + #module-header table.info { + float: none; + top: 0; + margin: 0 auto; + overflow: hidden; + max-width: 80vw; + } +} + +/* @end */ + + +/* @group Fonts & Sizes */ + +/* Basic technique & IE workarounds from YUI 3 + For reasons, see: + http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css + */ + + body, button { + font: 400 15px/1.4 'PT Sans', + /* Fallback Font Stack */ + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Oxygen-Sans, + Cantarell, + 'Helvetica Neue', + sans-serif; + *font-size: medium; /* for IE */ + *font:x-small; /* for IE in quirks mode */ + } + +h1 { font-size: 146.5%; /* 19pt */ } +h2 { font-size: 131%; /* 17pt */ } +h3 { font-size: 116%; /* 15pt */ } +h4 { font-size: 100%; /* 13pt */ } +h5 { font-size: 100%; /* 13pt */ } + +table { + font-size:inherit; + font:100%; +} + +pre, code, kbd, samp, tt, .src { + font-family:monospace; +} + +.links, .link { + font-size: 85%; /* 11pt */ +} + +#module-header .caption { + font-size: 182%; /* 24pt */ +} + +#module-header .caption sup { + font-size: 80%; + font-weight: normal; +} + +#package-header #page-menu a:link, #package-header #page-menu a:visited { color: white; } + + +.info { + font-size: 90%; +} + + +/* @end */ + +/* @group Common */ + +.caption, h1, h2, h3, h4, h5, h6, summary { + font-weight: bold; + color: #5E5184; + margin: 1.5em 0 1em 0; +} + + +* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 { + margin-top: 2em; +} + +h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 { + margin-top: inherit; +} + +ul li + li { + margin-top: 0.2rem; +} + +ul + p { + margin-top: 0.93em; +} + +p + ul { + margin-top: 0.5em; +} + +p { + margin-top: 0.7rem; +} + +ul, ol { + margin: 0.8em 0 0.8em 2em; +} + +ul.links { + list-style: none; + text-align: left; + font-size: 0.95em; +} + +#package-header ul.links, #package-header ul.links button { + font-size: 1rem; +} + +ul.links li { + display: inline; + white-space: nowrap; + padding: 0; +} + +ul.links > li + li:before { + content: '\00B7'; +} + +ul.links li a { + padding: 0.2em 0.5em; +} + +.hide { display: none; } +.show { display: inherit; } +.clear { clear: both; } + +.collapser:before, .expander:before, .noexpander:before { + font-size: 1.2em; + color: #9C5791; + display: inline-block; + padding-right: 7px; +} + +.collapser:before { + content: '▿'; +} +.expander:before { + content: '▹'; +} +.noexpander:before { + content: '▿'; + visibility: hidden; +} + +.collapser, .expander { + cursor: pointer; +} + +.instance.collapser, .instance.expander { + margin-left: 0px; + background-position: left center; + min-width: 9px; + min-height: 9px; +} + +summary { + cursor: pointer; + outline: none; +} + +pre { + padding: 0.5rem 1rem; + margin: 1em 0 0 0; + background-color: #f7f7f7; + overflow: auto; +} + +pre + p { + margin-top: 1em; +} + +pre + pre { + margin-top: 0.5em; +} + +.src { + background: #f4f4f4; + padding: 0.2em 0.5em; +} + +.keyword { font-weight: normal; } +.def { font-weight: bold; } + +@media print { + #footer { display: none; } +} + +/* @end */ + +/* @group Page Structure */ + +#content { + margin: 3em auto 6em auto; + padding: 0; +} + +#package-header { + background: #5E5184; + border-bottom: 5px solid rgba(69, 59, 97, 0.5); + color: #ddd; + position: relative; + font-size: 1.2em; + text-align: left; + margin: 0 auto; +} + +#package-header .caption { + color: white; + font-style: normal; + font-size: 1rem; + font-weight: bold; +} + +#module-header .caption { + font-weight: bold; + border-bottom: 1px solid #ddd; +} + +table.info { + float: right; + padding: 0.5em 1em; + border: 1px solid #ddd; + color: rgb(78,98,114); + background-color: #fff; + max-width: 60%; + border-spacing: 0; + position: relative; + top: -0.78em; + margin: 0 0 0 2em; +} + +.info th { + padding: 0 1em 0 0; + text-align: right; +} + +div#style-menu-holder { + position: relative; + z-index: 2; + display: inline; +} + +#style-menu { + position: absolute; + z-index: 1; + overflow: visible; + background: #374c5e; + margin: 0; + text-align: center; + right: 0; + padding: 0; + top: 1.25em; +} + +#style-menu li { + display: inline-block; + border-style: none; + margin: 0; + padding: 0; + color: #000; + list-style-type: none; + border-top: 1px solid #919191 +} + +#style-menu li + li { + border-left: 1px solid #919191; +} + +#style-menu a { + width: 6em; + padding: 3px; + display: block; +} + +#footer { + background: #ededed; + border-top: 1px solid #aaa; + padding: 0.5em 0; + color: #222; + text-align: center; + width: 100%; + height: 3em; + margin-top: 3em; + position: relative; + clear: both; +} + +/* @end */ + +/* @group Front Matter */ + +#synopsis .caption, +#contents-list .caption { + font-size: 1rem; +} + +#synopsis, #table-of-contents { + font-size: 16px; +} + +#contents-list { + background: #f7f7f7; + padding: 1em; + margin: 0; +} + +#contents-list .caption { + text-align: left; + margin: 0; +} + +#contents-list ul { + list-style: none; + margin: 0; + margin-top: 10px; + font-size: 14px; +} + +#contents-list ul ul { + margin-left: 1.5em; +} + +#description .caption { + display: none; +} + +#synopsis summary { + display: block; + float: right; + width: 29px; + color: rgba(255,255,255,0); + height: 110px; + margin: 0; + font-size: 1px; + padding: 0; + background: url(synopsis.png) no-repeat 0px -8px; +} + +#synopsis details[open] > summary { + background: url(synopsis.png) no-repeat -75px -8px; +} + +#synopsis ul { + height: 100%; + overflow: auto; + padding: 0.5em; + margin: 0; +} + +#synopsis ul ul { + overflow: hidden; +} + +#synopsis ul, +#synopsis ul li.src { + background-color: rgb(250,247,224); + white-space: nowrap; + list-style: none; + margin-left: 0; +} + +#interface td.src { + white-space: nowrap; +} + +/* @end */ + +/* @group Main Content */ + +#interface div.top + div.top { + margin-top: 1.5em; +} + +#interface p + div.top, +#interface h1 + div.top, +#interface h2 + div.top, +#interface h3 + div.top, +#interface h4 + div.top, +#interface h5 + div.top { + margin-top: 1em; +} +#interface .src .selflink, +#interface .src .link { + float: right; + color: #888; + padding: 0 7px; + -moz-user-select: none; + font-weight: bold; + line-height: 30px; +} +#interface .src .selflink { + margin: 0 -0.5em 0 0.5em; +} + +#interface span.fixity { + color: #919191; + border-left: 1px solid #919191; + padding: 0.2em 0.5em 0.2em 0.5em; + margin: 0 -1em 0 1em; +} + +#interface span.rightedge { + border-left: 1px solid #919191; + padding: 0.2em 0 0.2em 0; + margin: 0 0 0 1em; +} + +#interface table { border-spacing: 2px; } +#interface td { + vertical-align: top; + padding-left: 0.5em; +} + +#interface td.doc p { + margin: 0; +} +#interface td.doc p + p { + margin-top: 0.8em; +} + +.doc table { + border-collapse: collapse; + border-spacing: 0px; +} + +.doc th, +.doc td { + padding: 5px; + border: 1px solid #ddd; +} + +.doc th { + background-color: #f0f0f0; +} + +.clearfix:after { + clear: both; + content: " "; + display: block; + height: 0; + visibility: hidden; +} + +.subs, .top > .doc, .subs > .doc { + padding-left: 1em; + border-left: 1px solid gainsboro; + margin-bottom: 1em; +} + +.top .subs { + margin-bottom: 0.6em; +} + +.subs.fields ul { + list-style: none; + display: table; + margin: 0; +} + +.subs.fields ul li { + display: table-row; +} + +.subs ul li dfn { + display: table-cell; + font-style: normal; + font-weight: bold; + margin: 1px 0; + white-space: nowrap; +} + +.subs ul li > .doc { + display: table-cell; + padding-left: 0.5em; + margin-bottom: 0.5em; +} + +.subs ul li > .doc p { + margin: 0; +} + +.subs .subs p.src { + border: none; + background-color: #f8f8f8; +} + +.subs .subs .caption { + margin-top: 1em ; + margin-bottom: 0px; +} + +.subs p.caption { + margin-top: 0; +} + +.subs .subs .caption + .src { + margin: 0px; + margin-top: 8px; +} + +.subs .subs .src + .src { + margin: 7px 0 0 0; +} + +/* Render short-style data instances */ +.inst ul { + height: 100%; + padding: 0.5em; + margin: 0; +} + +.inst, .inst li { + list-style: none; + margin-left: 1em; +} + +/* Workaround for bug in Firefox (issue #384) */ +.inst-left { + float: left; +} + +.top p.src { + border-bottom: 3px solid #e5e5e5; + line-height: 2rem; + margin-bottom: 1em; +} + +.warning { + color: red; +} + +.arguments { + margin-top: -0.4em; +} +.arguments .caption { + display: none; +} + +.fields { padding-left: 1em; } + +.fields .caption { display: none; } + +.fields p { margin: 0 0; } + +/* this seems bulky to me +.methods, .constructors { + background: #f8f8f8; + border: 1px solid #eee; +} +*/ + +/* @end */ + +/* @group Auxillary Pages */ + + +.extension-list { + list-style-type: none; + margin-left: 0; +} + +#mini { + margin: 0 auto; + padding: 0 1em 1em; +} + +#mini > * { + font-size: 93%; /* 12pt */ +} + +#mini #module-list .caption, +#mini #module-header .caption { + font-size: 125%; /* 15pt */ +} + +#mini #interface h1, +#mini #interface h2, +#mini #interface h3, +#mini #interface h4 { + font-size: 109%; /* 13pt */ + margin: 1em 0 0; +} + +#mini #interface .top, +#mini #interface .src { + margin: 0; +} + +#mini #module-list ul { + list-style: none; + margin: 0; +} + +#alphabet ul { + list-style: none; + padding: 0; + margin: 0.5em 0 0; + text-align: center; +} + +#alphabet li { + display: inline; + margin: 0 0.25em; +} + +#alphabet a { + font-weight: bold; +} + +#index .caption, +#module-list .caption { font-size: 131%; /* 17pt */ } + +#index table { + margin-left: 2em; +} + +#index .src { + font-weight: bold; +} +#index .alt { + font-size: 77%; /* 10pt */ + font-style: italic; + padding-left: 2em; +} + +#index td + td { + padding-left: 1em; +} + +#module-list ul { + list-style: none; + margin: 0 0 0 2em; +} + +#module-list li { + clear: right; +} + +#module-list span.collapser, +#module-list span.expander { + background-position: 0 0.3em; +} + +#module-list .package { + float: right; +} + +:target { + background: -webkit-linear-gradient(top, transparent 0%, transparent 65%, #fbf36d 60%, #fbf36d 100%); + background: -moz-linear-gradient(top, transparent 0%, transparent 65%, #fbf36d 60%, #fbf36d 100%); + background: -o-linear-gradient(top, transparent 0%, transparent 65%, #fbf36d 60%, #fbf36d 100%); + background: -ms-linear-gradient(top, transparent 0%, transparent 65%, #fbf36d 60%, #fbf36d 100%); + background: linear-gradient(to bottom, transparent 0%, transparent 65%, #fbf36d 60%, #fbf36d 100%); +} + +:target:hover { + background: -webkit-linear-gradient(top, transparent 0%, transparent 0%, #fbf36d 0%, #fbf36d 100%); + background: -moz-linear-gradient(top, transparent 0%, transparent 0%, #fbf36d 0%, #fbf36d 100%); + background: -o-linear-gradient(top, transparent 0%, transparent 0%, #fbf36d 0%, #fbf36d 100%); + background: -ms-linear-gradient(top, transparent 0%, transparent 0%, #fbf36d 0%, #fbf36d 100%); + background: linear-gradient(to bottom, transparent 0%, transparent 0%, #fbf36d 0%, #fbf36d 100%); +} + +/* @end */ diff --git a/haddock-api/resources/html/Linuwial.std-theme/synopsis.png b/haddock-api/resources/html/Linuwial.std-theme/synopsis.png new file mode 100644 index 00000000..85fb86ec Binary files /dev/null and b/haddock-api/resources/html/Linuwial.std-theme/synopsis.png differ -- cgit v1.2.3 From 8c785e2c46d3e37d14ab7888d96005ea2c69f37f Mon Sep 17 00:00:00 2001 From: Alec Theriault Date: Mon, 12 Nov 2018 08:30:53 -0800 Subject: Add blockquote styling Matches b71da1feabf33efbbc517ac376bb690b5a604c2f from hackage-server. Fixes #967. --- haddock-api/resources/html/Linuwial.std-theme/linuwial.css | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'haddock-api/resources/html/Linuwial.std-theme') diff --git a/haddock-api/resources/html/Linuwial.std-theme/linuwial.css b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css index 5450ae2e..7ae19a93 100644 --- a/haddock-api/resources/html/Linuwial.std-theme/linuwial.css +++ b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css @@ -400,6 +400,13 @@ pre + pre { margin-top: 0.5em; } +blockquote { + border-left: 3px solid #c7a5d3; + background-color: #eee4f1; + margin: 0.5em; + padding: 0.0005em 0.3em 0.5em 0.5em; +} + .src { background: #f4f4f4; padding: 0.2em 0.5em; -- cgit v1.2.3 From 59843f9e3d222901421a92fff793a1e031f38f65 Mon Sep 17 00:00:00 2001 From: Xia Li-yao Date: Wed, 27 Feb 2019 21:53:27 -0500 Subject: Menu item controlling which instances are expanded/collapsed (#1007) Adds a menu item (like "Quick Jump") for options related to displaying instances. This provides functionality for: * expanding/collapsing all instances on the currently opened page * controlling whether instances are expanded/collapsed by default * controlling whether the state of instances should be "remembered" This new functionality is implemented in Typescript in `details-helper`. The built-in-themes style switcher also got a revamp so that all three of QuickJump, the style switcher, and instance preferences now have the same style and implementation structure. See also: https://mail.haskell.org/pipermail/haskell-cafe/2019-January/130495.html Fixes #698. Co-authored-by: Lysxia Co-authored-by: Nathan Collins --- .../resources/html/Linuwial.std-theme/linuwial.css | 43 +- haddock-api/resources/html/README.md | 8 +- haddock-api/resources/html/haddock-bundle.min.js | 2 +- .../resources/html/js-src/details-helper.ts | 106 ----- .../resources/html/js-src/details-helper.tsx | 464 +++++++++++++++++++++ haddock-api/resources/html/js-src/init.ts | 4 +- haddock-api/resources/html/js-src/style-menu.tsx | 177 ++++---- haddock-api/resources/html/quick-jump.css | 60 ++- 8 files changed, 635 insertions(+), 229 deletions(-) delete mode 100644 haddock-api/resources/html/js-src/details-helper.ts create mode 100644 haddock-api/resources/html/js-src/details-helper.tsx (limited to 'haddock-api/resources/html/Linuwial.std-theme') diff --git a/haddock-api/resources/html/Linuwial.std-theme/linuwial.css b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css index 7ae19a93..330c605a 100644 --- a/haddock-api/resources/html/Linuwial.std-theme/linuwial.css +++ b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css @@ -468,42 +468,10 @@ table.info { text-align: right; } -div#style-menu-holder { - position: relative; - z-index: 2; - display: inline; -} - -#style-menu { - position: absolute; - z-index: 1; - overflow: visible; - background: #374c5e; - margin: 0; - text-align: center; - right: 0; - padding: 0; - top: 1.25em; -} - #style-menu li { - display: inline-block; + display: block; border-style: none; - margin: 0; - padding: 0; - color: #000; list-style-type: none; - border-top: 1px solid #919191 -} - -#style-menu li + li { - border-left: 1px solid #919191; -} - -#style-menu a { - width: 6em; - padding: 3px; - display: block; } #footer { @@ -896,3 +864,12 @@ div#style-menu-holder { } /* @end */ + +/* @group Dropdown menus */ + +#preferences-menu, #style-menu { + width: 25em; + overflow-y: auto; +} + +/* @end */ diff --git a/haddock-api/resources/html/README.md b/haddock-api/resources/html/README.md index 0552f6fd..d555989d 100644 --- a/haddock-api/resources/html/README.md +++ b/haddock-api/resources/html/README.md @@ -13,4 +13,10 @@ After each change to the TypeScript sources, compile and copy the generated file ``` gulp && cp *.min.js path-to/generated-haddock-docs && cp *.js.map path-to/generated-haddock-docs -``` \ No newline at end of file +``` + +If you are editing the CSS, you'll also need to copy the edited CSS files. E.g. if you are editing the global/default quick-jump.css and the Linuwial theme's CSS, then + +``` +cp quick-jump.css Linuwial.std-theme/linuwial.css path-to/generated-haddock-docs +``` diff --git a/haddock-api/resources/html/haddock-bundle.min.js b/haddock-api/resources/html/haddock-bundle.min.js index 7881dc10..45adda98 100644 --- a/haddock-api/resources/html/haddock-bundle.min.js +++ b/haddock-api/resources/html/haddock-bundle.min.js @@ -1,2 +1,2 @@ -!function i(s,a,l){function c(t,e){if(!a[t]){if(!s[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(u)return u(t,!0);var o=new Error("Cannot find module '"+t+"'");throw o.code="MODULE_NOT_FOUND",o}var r=a[t]={exports:{}};s[t][0].call(r.exports,function(e){return c(s[t][1][e]||e)},r,r.exports,i,s,a,l)}return a[t].exports}for(var u="function"==typeof require&&require,e=0;e element with id '"+e+"'");return t}function o(e){for(var t,n=e.target,o=n.id,r=u(o),i=r.element.open,s=0,a=r.toggles;swindow.innerHeight?this.searchResults.scrollTop+=e.bottom-window.innerHeight+80:e.topn)return u(e,this.pattern,o);var r=this.options,i=r.location,s=r.distance,a=r.threshold,l=r.findAllMatches,c=r.minMatchCharLength;return h(e,this.pattern,this.patternAlphabet,{location:i,distance:s,threshold:a,findAllMatches:l,minMatchCharLength:c})}}]),y}();e.exports=r},function(e,t,n){"use strict";var u=n(0);e.exports=function(e,t){return function e(t,n,o){if(n){var r=n.indexOf("."),i=n,s=null;-1!==r&&(i=n.slice(0,r),s=n.slice(r+1));var a=t[i];if(null!=a)if(s||"string"!=typeof a&&"number"!=typeof a)if(u(a))for(var l=0,c=a.length;l 0 and <= 1");p=p.name}else a[p]={weight:1};this._analyze({key:p,value:this.options.getFn(u,p),record:u,index:l},{resultMap:o,results:r,tokenSearchers:e,fullSearcher:t})}return{weights:a,results:r}}},{key:"_analyze",value:function(e,t){var n=e.key,o=e.arrayIndex,r=void 0===o?-1:o,i=e.value,s=e.record,a=e.index,l=t.tokenSearchers,c=void 0===l?[]:l,u=t.fullSearcher,h=void 0===u?[]:u,d=t.resultMap,p=void 0===d?{}:d,f=t.results,v=void 0===f?[]:f;if(null!=i){var g=!1,m=-1,y=0;if("string"==typeof i){this._log("\nKey: "+(""===n?"-":n));var _=h.search(i);if(this._log('Full text: "'+i+'", score: '+_.score),this.options.tokenize){for(var k=i.split(this.options.tokenSeparator),b=[],x=0;x=c.length;if(this._log("\nCheck Matches: "+j),(g||_.isMatch)&&j){var E=p[a];E?E.output.push({key:n,arrayIndex:r,value:i,score:I,matchedIndices:_.matchedIndices}):(p[a]={item:s,output:[{key:n,arrayIndex:r,value:i,score:I,matchedIndices:_.matchedIndices}]},v.push(p[a]))}}else if(U(i))for(var T=0,P=i.length;T element with id '"+e+"'");return t}function x(){return u.defaultInstanceState==i.Open}function w(e){for(var t=S(e.target.id),n=t.element.open,o=0,r=t.toggles;owindow.innerHeight?this.searchResults.scrollTop+=e.bottom-window.innerHeight+80:e.topn)return u(e,this.pattern,o);var r=this.options,i=r.location,s=r.distance,a=r.threshold,l=r.findAllMatches,c=r.minMatchCharLength;return d(e,this.pattern,this.patternAlphabet,{location:i,distance:s,threshold:a,findAllMatches:l,minMatchCharLength:c})}}]),y}();e.exports=r},function(e,t,n){"use strict";var u=n(0);e.exports=function(e,t){return function e(t,n,o){if(n){var r=n.indexOf("."),i=n,s=null;-1!==r&&(i=n.slice(0,r),s=n.slice(r+1));var a=t[i];if(null!=a)if(s||"string"!=typeof a&&"number"!=typeof a)if(u(a))for(var l=0,c=a.length;l 0 and <= 1");p=p.name}else a[p]={weight:1};this._analyze({key:p,value:this.options.getFn(u,p),record:u,index:l},{resultMap:o,results:r,tokenSearchers:e,fullSearcher:t})}return{weights:a,results:r}}},{key:"_analyze",value:function(e,t){var n=e.key,o=e.arrayIndex,r=void 0===o?-1:o,i=e.value,s=e.record,a=e.index,l=t.tokenSearchers,c=void 0===l?[]:l,u=t.fullSearcher,d=void 0===u?[]:u,h=t.resultMap,p=void 0===h?{}:h,f=t.results,v=void 0===f?[]:f;if(null!=i){var g=!1,m=-1,y=0;if("string"==typeof i){this._log("\nKey: "+(""===n?"-":n));var _=d.search(i);if(this._log('Full text: "'+i+'", score: '+_.score),this.options.tokenize){for(var b=i.split(this.options.tokenSeparator),k=[],S=0;S=c.length;if(this._log("\nCheck Matches: "+T),(g||_.isMatch)&&T){var N=p[a];N?N.output.push({key:n,arrayIndex:r,value:i,score:A,matchedIndices:_.matchedIndices}):(p[a]={item:s,output:[{key:n,arrayIndex:r,value:i,score:A,matchedIndices:_.matchedIndices}]},v.push(p[a]))}}else if(V(i))for(var P=0,j=i.length;P are not in their default state */ - -function lookupDetailsRegistry(id: string): DetailsInfo { - const info = detailsRegistry[id]; - if (info == undefined) { throw new Error(`could not find
element with id '${id}'`); } - return info; -} - -function onDetailsToggle(ev: Event) { - const element = ev.target as HTMLDetailsElement; - const id = element.id; - const info = lookupDetailsRegistry(id); - const isOpen = info.element.open; - for (const toggle of info.toggles) { - if (toggle.classList.contains('details-toggle-control')) { - toggle.classList.add(isOpen ? 'collapser' : 'expander'); - toggle.classList.remove(isOpen ? 'expander' : 'collapser'); - } - } - if (element.open == info.openByDefault) { - delete toggled[id]; - } else { - toggled[id] = true; - } - rememberToggled(); -} - -function gatherDetailsElements() { - const els: HTMLDetailsElement[] = Array.prototype.slice.call(document.getElementsByTagName('details')); - for (const el of els) { - if (typeof el.id == "string" && el.id.length > 0) { - detailsRegistry[el.id] = { - element: el, - openByDefault: !!el.open, - toggles: [] // added later - }; - el.addEventListener('toggle', onDetailsToggle); - } - } -} - -function toggleDetails(id: string) { - const {element} = lookupDetailsRegistry(id); - element.open = !element.open; -} - -function rememberToggled() { - const sections: string[] = Object.keys(toggled); - // cookie specific to this page; don't use setCookie which sets path=/ - document.cookie = "toggled=" + encodeURIComponent(sections.join('+')); -} - -function restoreToggled() { - const cookie = getCookie("toggled"); - if (!cookie) { return; } - const ids = cookie.split('+'); - for (const id of ids) { - const info = detailsRegistry[id]; - toggled[id] = true; - if (info) { - info.element.open = !info.element.open; - } - } -} - -function onToggleClick(ev: MouseEvent) { - ev.preventDefault(); - const toggle = ev.currentTarget as HTMLElement; - const id = toggle.getAttribute('data-details-id'); - if (!id) { throw new Error("element with class 'details-toggle' has no 'data-details-id' attribute!"); } - toggleDetails(id); -} - -function initCollapseToggles() { - const toggles: HTMLElement[] = Array.prototype.slice.call(document.getElementsByClassName('details-toggle')); - toggles.forEach(toggle => { - const id = toggle.getAttribute('data-details-id'); - if (!id) { throw new Error("element with class 'details-toggle' has no 'data-details-id' attribute!"); } - const info = lookupDetailsRegistry(id); - info.toggles.push(toggle); - toggle.addEventListener('click', onToggleClick); - if (toggle.classList.contains('details-toggle-control')) { - toggle.classList.add(info.element.open ? 'collapser' : 'expander'); - } - }); -} - -export function init() { - gatherDetailsElements(); - restoreToggled(); - initCollapseToggles(); -} \ No newline at end of file diff --git a/haddock-api/resources/html/js-src/details-helper.tsx b/haddock-api/resources/html/js-src/details-helper.tsx new file mode 100644 index 00000000..871b5417 --- /dev/null +++ b/haddock-api/resources/html/js-src/details-helper.tsx @@ -0,0 +1,464 @@ +// This file implements the UI and logic for collapsing and expanding +// instance lists ("details"). +// +// A configuration ('GlobalConfig') controlled by the UI is persisted +// in local storage in the user's browser. The configuration includes: +// +// * a global default state ('defaultInstanceState') for all instance +// lists. The possible values for the global default are "collapsed" +// and "expanded". +// +// * a global boolean option ('rememberToggles') to remember which +// specific instance lists are not in the default state (e.g. which +// instance lists are expanded when the default is "collapsed"). +// +// * a local / per-page record of which specific instance lists are +// not in the default state, when the global option +// ('rememberToggles') to remember this info is enabled. +// +// The UI consists of an Instances menu with buttons for expanding and +// collapsing all instance lists in the current module, a checkbox for +// setting the global default state, and a checkbox to enable +// remembering which instance lists are not in the global default +// state. Also, each instance list on each module page has buttons for +// collapsing and expanding. +// +// The logic of the UI is as follows: +// +// * setting the global default state erases any record of which +// specific instances are in the non-default state, and collapses or +// expands all instance lists on the current page to be in the +// global default state. +// +// * changing boolean option for remembering which specific instance +// lists are not in the default state erases any existing record of +// which instances are not in the default state across all pages, +// and updates the record for the current page when the option is +// set to true. No collapsing or expanding is done. +// +// * toggling the collapse/expand state of a specific instance list +// causes the state of that specific instance list to be recorded in +// the persisted configuration iff the new state of that specific +// instance list is different from the global default state, and the +// option to remember instance list states is enabled. There are two +// ways to toggle the collapse/expand state of a specific instance, +// by clicking its collapse/expand button, and by clicking the +// "collapse all" or "expand all" button in the Instances menu. +// +// This file also implements an association between elements (with +// class "details-toggle" and "details-toggle-control") that can be +// clicked to expand/collapse
elements, and the details +// elements themselves. Note that this covers both
elements +// that list instances -- what the above explained UI and logic is +// concerned with -- and details about individual instances themselves +// -- which the above is not concerend with. The association includes +// adding event listeners that change CSS classes back and forth +// between "expander" and "collapser"; these classes determine whether +// an element is adorned with a right arrow ("expander") or a down +// arrow ("collapser"). I don't understand why we don't directly use +// the the HTML element type to allow the
elements +// to be directly clickable. +import preact = require("preact"); + +const { h, Component } = preact; + +enum DefaultState { Closed, Open } + +interface GlobalConfig { + defaultInstanceState: DefaultState + rememberToggles: boolean +} + +// Hackage domain-wide config +const globalConfig: GlobalConfig = { + defaultInstanceState: DefaultState.Open, + rememberToggles: true, +}; + +class PreferencesButton extends Component { + render(props: { title: string, onClick: () => void }) { + function onClick(e: Event) { + e.preventDefault(); + props.onClick(); + } + return
  • {props.title}
  • ; + } +} + +function addPreferencesButton(action: () => void) { + const pageMenu = document.querySelector('#page-menu') as HTMLUListElement; + const dummy = document.createElement('li'); + pageMenu.insertBefore(dummy, pageMenu.firstChild); + preact.render(, pageMenu, dummy); +} + +type PreferencesProps = { + showHideTrigger: (action: () => void) => void +} + +type PreferencesState = { + isVisible: boolean +} + +class Preferences extends Component { + componentWillMount() { + document.addEventListener('mousedown', this.hide.bind(this)); + + document.addEventListener('keydown', (e) => { + if (this.state.isVisible) { + if (e.key === 'Escape') { + this.hide(); + } + } + }) + } + + hide() { + this.setState({ isVisible: false }); + } + + show() { + if (!this.state.isVisible) { + this.setState({ isVisible: true }); + } + } + + toggleVisibility() { + if (this.state.isVisible) { + this.hide(); + } else { + this.show(); + } + } + + componentDidMount() { + this.props.showHideTrigger(this.toggleVisibility.bind(this)); + } + + render(props: PreferencesProps, state: PreferencesState) { + const stopPropagation = (e: Event) => { e.stopPropagation(); }; + + return
    + +
    ; + } +} + +function storeGlobalConfig() { + const json = JSON.stringify(globalConfig); + try { + // https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem#Exceptions. + localStorage.setItem('global', json); + } catch (e) {} +} + +var globalConfigLoaded: boolean = false; + +function loadGlobalConfig() { + if (globalConfigLoaded) { return; } + globalConfigLoaded = true; + const global = localStorage.getItem('global'); + if (!global) { return; } + try { + const globalConfig_ = JSON.parse(global); + globalConfig.defaultInstanceState = globalConfig_.defaultInstanceState; + globalConfig.rememberToggles = globalConfig_.rememberToggles; + } catch(e) { + // Gracefully handle errors related to changed config format. + if (e instanceof SyntaxError || e instanceof TypeError) { + localStorage.removeItem('global'); + } else { + throw e; + } + } +} + +function setDefaultInstanceState(s: DefaultState) { + return (e: Event) => { + globalConfig.defaultInstanceState = s; + putInstanceListsInDefaultState(); + storeGlobalConfig(); + clearLocalStorage(); + storeLocalConfig(); + } +} + +function setRememberToggles(e: Event) { + const checked: boolean = (e as any).target.checked; + globalConfig.rememberToggles = checked; + storeGlobalConfig(); + clearLocalStorage(); + storeLocalConfig(); +} + +// Click event consumer for "default collapse" instance menu check box. +function defaultCollapseOnClick(e: Event) { + const us = document.getElementById('default-collapse-instances') as HTMLInputElement; + if (us !== null) { + if (us.checked) { + setDefaultInstanceState(DefaultState.Closed)(e); + } else { + setDefaultInstanceState(DefaultState.Open)(e); + } + } +} + +// Instances menu. +function PreferencesMenu() { + loadGlobalConfig(); + return
    +
    + + +
    +
    + + + Collapse All Instances By Default +
    +
    + + +
    +
    ; +} + +interface HTMLDetailsElement extends HTMLElement { + open: boolean +} + +interface DetailsInfo { + element: HTMLDetailsElement + // Here 'toggles' is the list of all elements of class + // 'details-toggle-control' that control toggling 'element'. I + // believe this list is always length zero or one. + toggles: HTMLElement[] +} + +// Mapping from
    elements to their info. +const detailsRegistry: { [id: string]: DetailsInfo } = {}; + +function lookupDetailsRegistry(id: string): DetailsInfo { + const info = detailsRegistry[id]; + if (info == undefined) { throw new Error(`could not find
    element with id '${id}'`); } + return info; +} + +// Return true iff instance lists are open by default. +function getDefaultOpenSetting(): boolean { + return globalConfig.defaultInstanceState == DefaultState.Open; +} + +// Event handler for "toggle" events, which are triggered when a +//
    element's "open" property changes. We don't deal with +// any config stuff here, because we only change configs in response +// to mouse clicks. In contrast, for example, this event is triggred +// automatically once for every
    element when the user clicks +// the "collapse all elements" button. +function onToggleEvent(ev: Event) { + const element = ev.target as HTMLDetailsElement; + const id = element.id; + const info = lookupDetailsRegistry(id); + const isOpen = info.element.open; + // Update the CSS of the toggle element users can click on to toggle + // 'element'. The "collapser" and "expander" classes control what + // kind of arrow appears next to the 'toggle' element. + for (const toggle of info.toggles) { + if (toggle.classList.contains('details-toggle-control')) { + toggle.classList.add(isOpen ? 'collapser' : 'expander'); + toggle.classList.remove(isOpen ? 'expander' : 'collapser'); + } + } +} + +function gatherDetailsElements() { + const els: HTMLDetailsElement[] = Array.prototype.slice.call(document.getElementsByTagName('details')); + for (const el of els) { + if (typeof el.id == "string" && el.id.length > 0) { + detailsRegistry[el.id] = { + element: el, + toggles: [] // Populated later by 'initCollapseToggles'. + }; + el.addEventListener('toggle', onToggleEvent); + } + } +} + +// Return the id of the
    element that the given 'toggle' +// element toggles. +function getDataDetailsId(toggle: Element): string { + const id = toggle.getAttribute('data-details-id'); + if (!id) { throw new Error("element with class " + toggle + " has no 'data-details-id' attribute!"); } + return id; +} + +// Toggle the "open" state of a
    element when that element's +// toggle element is clicked. +function toggleDetails(toggle: Element) { + const id = getDataDetailsId(toggle); + const {element} = lookupDetailsRegistry(id); + element.open = !element.open; +} + +// Prefix for local keys used with local storage. Idea is that other +// modules could also use local storage with a different prefix and we +// wouldn't step on each other's toes. +// +// NOTE: we're using the browser's "local storage" API via the +// 'localStorage' object to store both "local" (to the current Haddock +// page) and "global" (across all Haddock pages) configuration. Be +// aware of these two different uses of the term "local". +const localStoragePrefix: string = "local-details-config:"; + +// Local storage key for the current page. +function localStorageKey(): string { + return localStoragePrefix + document.location.pathname; +} + +// Clear all local storage related to instance list configs. +function clearLocalStorage() { + const keysToDelete: string[] = []; + for (var i = 0; i < localStorage.length; ++i) { + const key = localStorage.key(i); + if (key !== null && key.startsWith(localStoragePrefix)) { + keysToDelete.push(key); + } + } + keysToDelete.forEach(key => { + localStorage.removeItem(key); + }); +} + +// Compute and save the set of instance list ids that aren't in the +// default state. +function storeLocalConfig() { + if (!globalConfig.rememberToggles) return; + const instanceListToggles: HTMLElement[] = + // Restrict to 'details-toggle' elements for "instances" + // *plural*. These are the toggles that control instance lists and + // not the list of methods for individual instances. + Array.prototype.slice.call(document.getElementsByClassName( + 'instances details-toggle details-toggle-control')); + const nonDefaultInstanceListIds: string[] = []; + instanceListToggles.forEach(toggle => { + const id = getDataDetailsId(toggle); + const details = document.getElementById(id) as HTMLDetailsElement; + if (details.open != getDefaultOpenSetting()) { + nonDefaultInstanceListIds.push(id); + } + }); + + const json = JSON.stringify(nonDefaultInstanceListIds); + try { + // https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem#Exceptions. + localStorage.setItem(localStorageKey(), json); + } catch (e) {} +} + +function putInstanceListsInDefaultState() { + switch (globalConfig.defaultInstanceState) { + case DefaultState.Closed: _collapseAllInstances(true); break; + case DefaultState.Open: _collapseAllInstances(false); break; + default: break; + } +} + +// Expand and collapse instance lists according to global and local +// config. +function restoreToggled() { + loadGlobalConfig(); + putInstanceListsInDefaultState(); + if (!globalConfig.rememberToggles) { return; } + const local = localStorage.getItem(localStorageKey()); + if (!local) { return; } + try { + const nonDefaultInstanceListIds: string[] = JSON.parse(local); + nonDefaultInstanceListIds.forEach(id => { + const info = lookupDetailsRegistry(id); + info.element.open = ! getDefaultOpenSetting(); + }); + } catch(e) { + // Gracefully handle errors related to changed config format. + if (e instanceof SyntaxError || e instanceof TypeError) { + localStorage.removeItem(localStorageKey()); + } else { + throw e; + } + } +} + +// Handler for clicking on the "toggle" element that toggles the +//
    element with id given by the 'data-details-id' property +// of the "toggle" element. +function onToggleClick(ev: MouseEvent) { + ev.preventDefault(); + const toggle = ev.currentTarget as HTMLElement; + toggleDetails(toggle); + storeLocalConfig(); +} + +// Set event handlers on elements responsible for expanding and +// collapsing
    elements. +// +// This applies to all 'details-toggle's, not just to to top-level +// 'details-toggle's that control instance lists. +function initCollapseToggles() { + const toggles: HTMLElement[] = Array.prototype.slice.call(document.getElementsByClassName('details-toggle')); + toggles.forEach(toggle => { + const id = getDataDetailsId(toggle); + const info = lookupDetailsRegistry(id); + info.toggles.push(toggle); + toggle.addEventListener('click', onToggleClick); + if (toggle.classList.contains('details-toggle-control')) { + toggle.classList.add(info.element.open ? 'collapser' : 'expander'); + } + }); +} + +// Collapse or expand all instances. +function _collapseAllInstances(collapse: boolean) { + const ilists = document.getElementsByClassName('subs instances'); + [].forEach.call(ilists, function (ilist : Element) { + const toggleType = collapse ? 'collapser' : 'expander'; + const toggle = ilist.getElementsByClassName('instances ' + toggleType)[0]; + if (toggle) { + toggleDetails(toggle); + } + }); +} + +function collapseAllInstances() { + _collapseAllInstances(true); + storeLocalConfig(); +} + +function expandAllInstances() { + _collapseAllInstances(false); + storeLocalConfig(); +} + +export function init(showHide?: (action: () => void) => void) { + gatherDetailsElements(); + initCollapseToggles(); + restoreToggled(); + preact.render( + , + document.body + ); +} diff --git a/haddock-api/resources/html/js-src/init.ts b/haddock-api/resources/html/js-src/init.ts index 877874ae..1bfa8b3c 100644 --- a/haddock-api/resources/html/js-src/init.ts +++ b/haddock-api/resources/html/js-src/init.ts @@ -17,6 +17,6 @@ function onDomReady(callback: () => void) { onDomReady(() => { document.body.classList.add('js-enabled'); styleMenu.init(); - detailsHelper.init(); quickJump.init(); -}); \ No newline at end of file + detailsHelper.init(); +}); diff --git a/haddock-api/resources/html/js-src/style-menu.tsx b/haddock-api/resources/html/js-src/style-menu.tsx index bab840ca..2eb8344e 100644 --- a/haddock-api/resources/html/js-src/style-menu.tsx +++ b/haddock-api/resources/html/js-src/style-menu.tsx @@ -4,91 +4,14 @@ import {getCookie, setCookie, clearCookie} from "./cookies"; import preact = require("preact"); const { h, Component } = preact; -const rspace = /\s\s+/g, - rtrim = /^\s+|\s+$/g; - -function spaced(s: string) { return (" " + s + " ").replace(rspace, " "); } -function trim(s: string) { return s.replace(rtrim, ""); } - -function hasClass(elem: Element, value: string) { - const className = spaced(elem.className || ""); - return className.indexOf( " " + value + " " ) >= 0; -} - -function addClass(elem: Element, value: string) { - const className = spaced(elem.className || ""); - if ( className.indexOf( " " + value + " " ) < 0 ) { - elem.className = trim(className + " " + value); - } -} - -function removeClass(elem: Element, value: string) { - let className = spaced(elem.className || ""); - className = className.replace(" " + value + " ", " "); - elem.className = trim(className); -} - -function toggleClass(elem: Element, valueOn: string, valueOff: string, bool?: boolean): boolean { - if (bool == null) { bool = ! hasClass(elem, valueOn); } - if (bool) { - removeClass(elem, valueOff); - addClass(elem, valueOn); - } - else { - removeClass(elem, valueOn); - addClass(elem, valueOff); - } - return bool; -} - -function makeClassToggle(valueOn: string, valueOff: string): (elem: Element, bool?: boolean) => boolean { - return function(elem, bool) { - return toggleClass(elem, valueOn, valueOff, bool); - } -} - -const toggleShow = makeClassToggle("show", "hide"); +// Get all of the styles that are available function styles(): HTMLLinkElement[] { const es = Array.prototype.slice.call(document.getElementsByTagName("link")); return es.filter((a: HTMLLinkElement) => a.rel.indexOf("style") != -1 && a.title); } -class StyleMenuButton extends Component { - - render(props: { stys: string[] }) { - function action() { - styleMenu(); - return false; - }; - - return
  • - Style ▾ -
      - {props.stys.map((sty) => { - function action() { - setActiveStyleSheet(sty); - return false; - }; - - return
    • {sty}
    • ; - })} -
    -
  • ; - } - -} - -function addStyleMenu() { - const stys = styles().map((s) => s.title); - if (stys.length > 1) { - const pageMenu = document.querySelector('#page-menu') as HTMLUListElement; - const dummy = document.createElement('li'); - pageMenu.appendChild(dummy); - preact.render(, pageMenu, dummy); - } -} - +// Set a style (including setting the cookie) function setActiveStyleSheet(title: string) { const as = styles(); let found: null | HTMLLinkElement = null; @@ -110,17 +33,103 @@ function setActiveStyleSheet(title: string) { } } +// Reset the style based on the cookie function resetStyle() { const s = getCookie("haddock-style"); if (s) setActiveStyleSheet(s); } -function styleMenu(show?: boolean) { - const m = document.getElementById('style-menu'); - if (m) toggleShow(m, show); +class StylesButton extends Component { + render(props: { title: string, onClick: () => void }) { + function onClick(e: Event) { + e.preventDefault(); + props.onClick(); + } + return
  • {props.title}
  • ; + } } -export function init() { - addStyleMenu(); +// Add the style menu button +function addStyleMenu(stys: string[], action: () => void) { + if (stys.length > 1) { + const pageMenu = document.querySelector('#page-menu') as HTMLUListElement; + const dummy = document.createElement('li'); + pageMenu.appendChild(dummy); + preact.render(, pageMenu, dummy); + } +} + +type StyleProps = { + styles: string[] + showHideTrigger: (action: () => void) => void +} + +type StyleState = { + isVisible: boolean +} + +// Represents the full style dropdown +class Styles extends Component { + + componentWillMount() { + document.addEventListener('mousedown', this.hide.bind(this)); + + document.addEventListener('keydown', (e) => { + if (this.state.isVisible) { + if (e.key === 'Escape') { + this.hide(); + } + } + }) + } + + hide() { + this.setState({ isVisible: false }); + } + + show() { + if (!this.state.isVisible) { + this.setState({ isVisible: true }); + } + } + + toggleVisibility() { + if (this.state.isVisible) { + this.hide(); + } else { + this.show(); + } + } + + componentDidMount() { + this.props.showHideTrigger(this.toggleVisibility.bind(this)); + } + + render(props: StyleProps, state: StyleState) { + const stopPropagation = (e: Event) => { e.stopPropagation(); }; + + return
    + +
    ; + } +} + + +export function init(showHide?: (action: () => void) => void) { + const stys = styles().map((s) => s.title); + const addStylesButton = (action: () => void) => addStyleMenu(stys, action) resetStyle(); + preact.render( + , + document.body + ); } diff --git a/haddock-api/resources/html/quick-jump.css b/haddock-api/resources/html/quick-jump.css index 468d8036..8772809c 100644 --- a/haddock-api/resources/html/quick-jump.css +++ b/haddock-api/resources/html/quick-jump.css @@ -1,3 +1,11 @@ +/* @group Fundamentals */ + +.hidden { + display: none; +} + +/* @end */ + /* @group Search box layout */ #search { @@ -11,8 +19,10 @@ overflow-y: auto; } -#search.hidden { - display: none; +@media only screen and (max-width: 999px) { + #search { + top: 5.7em; + } } #search-form, #search-results { @@ -162,3 +172,49 @@ } /* @end */ + +/* @group Dropdown menus */ + +/* Based on #search styling above. */ + +.dropdown-menu { + position: fixed; + /* Not robust to window size changes. */ + top: 3.2em; + right: 0; + /* To display on top of synopsis menu on right side. */ + z-index: 1000; + border: 0.05em solid #b2d5fb; + background: #e8f3ff; +} + +@media only screen and (max-width: 999px) { + .dropdown-menu { + top: 5.7em; + } +} + +.dropdown-menu * { + margin: 0.1em; +} + +.dropdown-menu button { + border: 1px #5E5184 solid; + border-radius: 3px; + background: #5E5184; + padding: 3px; + color: #f4f4f4; + min-width: 6em; +} + +.dropdown-menu button:hover { + color: #5E5184; + background: #f4f4f4; +} + +.dropdown-menu button:active { + color: #f4f4f4; + background: #5E5184; +} + +/* @end */ -- cgit v1.2.3 From 8964666efc4d4ab9756a83d16a02115a38744408 Mon Sep 17 00:00:00 2001 From: gbaz Date: Fri, 1 Mar 2019 10:43:16 -0500 Subject: Increase contrast of Linuwal theme (#1037) This is to address the concern that, on less nice and older screens, some of the shades of grey blend in too easily with the white background. * darken the font slightly * darken slightly the grey behind type signatures and such * add a border and round the corners on code blocks * knock the font down by one point --- haddock-api/resources/html/Linuwial.std-theme/linuwial.css | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'haddock-api/resources/html/Linuwial.std-theme') diff --git a/haddock-api/resources/html/Linuwial.std-theme/linuwial.css b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css index 330c605a..cbb58a03 100644 --- a/haddock-api/resources/html/Linuwial.std-theme/linuwial.css +++ b/haddock-api/resources/html/Linuwial.std-theme/linuwial.css @@ -11,7 +11,7 @@ html { body { background: #fefefe; - color: #333; + color: #111; text-align: left; min-height: 100vh; position: relative; @@ -234,7 +234,7 @@ Display the package name on top of the menu links and center both elements: */ body, button { - font: 400 15px/1.4 'PT Sans', + font: 400 14px/1.4 'PT Sans', /* Fallback Font Stack */ -apple-system, BlinkMacSystemFont, @@ -390,6 +390,8 @@ pre { margin: 1em 0 0 0; background-color: #f7f7f7; overflow: auto; + border: 1px solid #ddd; + border-radius: 0.3em; } pre + p { @@ -408,7 +410,7 @@ blockquote { } .src { - background: #f4f4f4; + background: #f2f2f2; padding: 0.2em 0.5em; } @@ -501,7 +503,7 @@ table.info { } #contents-list { - background: #f7f7f7; + background: #f4f4f4; padding: 1em; margin: 0; } -- cgit v1.2.3