From e41c1cbe9f0476997eac7b4a3f17cbc6b2262faf Mon Sep 17 00:00:00 2001
From: Tim Baumann
Date: Mon, 9 Oct 2017 18:33:09 +0200
Subject: Use element for collapsibles (#690)
* Remove unnecessary call to 'collapseSection'
The call is unnecessary since there is no corresponding toggle for hiding the
section of orphan instances.
* Use for collapsibles
This makes them work even when JS is disabled. Closes #560.
---
.../resources/html/Ocean.std-theme/ocean.css | 30 +-
haddock-api/resources/html/haddock-bundle.min.js | 2 +-
haddock-api/resources/html/js-src/cookies.ts | 20 +
.../resources/html/js-src/details-helper.ts | 106 +++
haddock-api/resources/html/js-src/haddock-util.ts | 173 ----
haddock-api/resources/html/js-src/init.ts | 9 +-
haddock-api/resources/html/js-src/style-menu.ts | 116 +++
haddock-api/src/Haddock/Backends/Xhtml.hs | 21 +-
.../src/Haddock/Backends/Xhtml/DocMarkup.hs | 6 +-
haddock-api/src/Haddock/Backends/Xhtml/Layout.hs | 14 +-
haddock-api/src/Haddock/Backends/Xhtml/Utils.hs | 35 +-
html-test/ref/A.html | 76 +-
html-test/ref/B.html | 56 +-
html-test/ref/Bold.html | 18 +-
html-test/ref/Bug1.html | 26 +-
html-test/ref/Bug201.html | 24 +-
html-test/ref/Bug253.html | 18 +-
html-test/ref/Bug26.html | 62 +-
html-test/ref/Bug294.html | 50 +-
html-test/ref/Bug298.html | 48 +-
html-test/ref/Bug3.html | 22 +-
html-test/ref/Bug308.html | 24 +-
html-test/ref/Bug308CrossModule.html | 18 +-
html-test/ref/Bug310.html | 38 +-
html-test/ref/Bug313.html | 24 +-
html-test/ref/Bug335.html | 44 +-
html-test/ref/Bug387.html | 32 +-
html-test/ref/Bug4.html | 22 +-
html-test/ref/Bug6.html | 146 ++--
html-test/ref/Bug613.html | 94 +-
html-test/ref/Bug7.html | 72 +-
html-test/ref/BugDeprecated.html | 80 +-
html-test/ref/BugExportHeadings.html | 80 +-
html-test/ref/BundledPatterns.html | 150 ++--
html-test/ref/BundledPatterns2.html | 154 ++--
html-test/ref/DeprecatedClass.html | 46 +-
html-test/ref/DeprecatedData.html | 70 +-
html-test/ref/DeprecatedFunction.html | 32 +-
html-test/ref/DeprecatedFunction2.html | 22 +-
html-test/ref/DeprecatedFunction3.html | 22 +-
html-test/ref/DeprecatedNewtype.html | 48 +-
html-test/ref/DeprecatedReExport.html | 22 +-
html-test/ref/DeprecatedRecord.html | 52 +-
html-test/ref/DeprecatedTypeFamily.html | 48 +-
html-test/ref/DeprecatedTypeSynonym.html | 40 +-
html-test/ref/Examples.html | 26 +-
html-test/ref/Extensions.html | 18 +-
html-test/ref/GADTRecords.html | 92 +-
html-test/ref/Hash.html | 146 ++--
html-test/ref/HiddenInstances.html | 86 +-
html-test/ref/HiddenInstancesB.html | 68 +-
html-test/ref/Hyperlinks.html | 22 +-
html-test/ref/IgnoreExports.html | 32 +-
html-test/ref/Instances.html | 320 ++++---
html-test/ref/Math.html | 22 +-
html-test/ref/NamedDoc.html | 10 +-
html-test/ref/Nesting.html | 72 +-
html-test/ref/NoLayout.html | 22 +-
html-test/ref/NonGreedy.html | 18 +-
html-test/ref/Operators.html | 212 ++---
html-test/ref/OrphanInstances.html | 22 +-
html-test/ref/PR643.html | 18 +-
html-test/ref/PR643_1.html | 18 +-
html-test/ref/PatternSyns.html | 200 ++---
html-test/ref/Properties.html | 26 +-
html-test/ref/QuasiExpr.html | 40 +-
html-test/ref/SpuriousSuperclassConstraints.html | 30 +-
html-test/ref/Test.html | 952 +++++++++++----------
html-test/ref/Threaded.html | 22 +-
html-test/ref/Threaded_TH.html | 18 +-
html-test/ref/Ticket112.html | 18 +-
html-test/ref/Ticket75.html | 36 +-
html-test/ref/TitledPicture.html | 32 +-
html-test/ref/TypeFamilies.html | 618 +++++++------
html-test/ref/TypeFamilies2.html | 134 +--
html-test/ref/Unicode.html | 22 +-
76 files changed, 3040 insertions(+), 2644 deletions(-)
create mode 100644 haddock-api/resources/html/js-src/cookies.ts
create mode 100644 haddock-api/resources/html/js-src/details-helper.ts
delete mode 100644 haddock-api/resources/html/js-src/haddock-util.ts
create mode 100644 haddock-api/resources/html/js-src/style-menu.ts
diff --git a/haddock-api/resources/html/Ocean.std-theme/ocean.css b/haddock-api/resources/html/Ocean.std-theme/ocean.css
index 20e37ca8..0852dea5 100644
--- a/haddock-api/resources/html/Ocean.std-theme/ocean.css
+++ b/haddock-api/resources/html/Ocean.std-theme/ocean.css
@@ -46,6 +46,14 @@ 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 Fonts & Sizes */
/* Basic technique & IE workarounds from YUI 3
@@ -106,7 +114,7 @@ pre, code, kbd, samp, tt, .src {
/* @group Common */
-.caption, h1, h2, h3, h4, h5, h6 {
+.caption, h1, h2, h3, h4, h5, h6, summary {
font-weight: bold;
color: rgb(78,98,114);
margin: 0.8em 0 0.4em;
@@ -168,6 +176,16 @@ p.caption.expander {
min-height: 9px;
}
+summary {
+ cursor: pointer;
+ outline: none;
+ list-style-image: url(plus.gif);
+ list-style-position: outside;
+}
+
+details[open] > summary {
+ list-style-image: url(minus.gif);
+}
pre {
padding: 0.25em;
@@ -338,7 +356,8 @@ div#style-menu-holder {
z-index: 1;
}
-#synopsis .caption {
+#synopsis summary {
+ display: block;
float: left;
width: 29px;
color: rgba(255,255,255,0);
@@ -346,16 +365,13 @@ div#style-menu-holder {
margin: 0;
font-size: 1px;
padding: 0;
+ background: url(synopsis.png) no-repeat 0px -8px;
}
-#synopsis p.caption.collapser {
+#synopsis details[open] > summary {
background: url(synopsis.png) no-repeat -64px -8px;
}
-#synopsis p.caption.expander {
- background: url(synopsis.png) no-repeat 0px -8px;
-}
-
#synopsis ul {
height: 100%;
overflow: auto;
diff --git a/haddock-api/resources/html/haddock-bundle.min.js b/haddock-api/resources/html/haddock-bundle.min.js
index 64357c4a..2badbc56 100644
--- a/haddock-api/resources/html/haddock-bundle.min.js
+++ b/haddock-api/resources/html/haddock-bundle.min.js
@@ -1,2 +1,2 @@
-!function e(t,n,o){function r(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){var n=t[s][1][e];return r(n||e)},u,u.exports,e,t,n,o)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s=0}function s(e,t){var n=o(e.className||"");n.indexOf(" "+t+" ")<0&&(e.className=r(n+" "+t))}function a(e,t){var n=o(e.className||"");n=n.replace(" "+t+" "," "),e.className=r(n)}function l(e,t,n,o){return null==o&&(o=!i(e,t)),o?(a(e,n),s(e,t)):(a(e,t),s(e,n)),o}function c(e,t){return function(n,o){return l(n,e,t,o)}}function u(e){var t=b(document.getElementById("section."+e));return x(document.getElementById("control."+e),t),h(e),t}function h(e){S[e]?delete S[e]:S[e]=!0;var t=[];for(var n in S)S.hasOwnProperty(n)&&t.push(n);document.cookie="collapsed="+encodeURIComponent(t.join("+"))}function d(e,t){document.cookie=e+"="+encodeURIComponent(t)+";path=/;"}function p(e){document.cookie=e+"=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;"}function f(e){for(var t=e+"=",n=document.cookie.split(";"),o=0;o"+e.title+""}),e.length>1&&v("")},n.resetStyle=function(){var e=f("haddock-style");e&&g(e)}},{}],2:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var o=e("./haddock-util"),r=e("./quick-jump");!function(e){"interactive"===document.readyState?e():document.addEventListener("readystatechange",function(){"interactive"===document.readyState&&e()})}(function(){o.addStyleMenu(),o.resetStyle(),o.restoreCollapsed(),r.init()})},{"./haddock-util":1,"./quick-jump":3}],3:[function(e,t,n){"use strict";function o(e,t,n){var o=new XMLHttpRequest;o.onreadystatechange=function(){o.readyState===XMLHttpRequest.DONE&&(200===o.status?t&&t(JSON.parse(o.responseText)):n&&n(o))},o.open("GET",e,!0),o.send()}function r(e){var t=document.querySelector("#page-menu"),n=document.createElement("li");t.insertBefore(n,t.firstChild),d.render(p(v,{onClick:e,title:"Quick Jump"}),t,n)}function i(e,t){return t.length<=e?t:t.slice(0,e)}function s(){return p("table",{class:"keyboard-shortcuts"},p("tr",null,p("th",null,"Key"),p("th",null,"Shortcut")),p("tr",null,p("td",null,p("span",{class:"key"},"s")),p("td",null,"Open this search box")),p("tr",null,p("td",null,p("span",{class:"key"},"esc")),p("td",null,"Close this search box")),p("tr",null,p("td",null,p("span",{class:"key"},"↓"),",",p("span",{class:"key"},"ctrl")," + ",p("span",{class:"key"},"j")),p("td",null,"Move down in search results")),p("tr",null,p("td",null,p("span",{class:"key"},"↑"),",",p("span",{class:"key"},"ctrl")," + ",p("span",{class:"key"},"k")),p("td",null,"Move up in search results")),p("tr",null,p("td",null,p("span",{class:"key"},"↵")),p("td",null,"Go to active search result")))}function a(){return p("p",null,"You can find any exported type, constructor, class, function or pattern defined in this package by (approximate) name.")}function l(e){var t=[p("p",null,"Your search for '",e.searchString,"' produced the following list of results: ",p("code",null,"[]"),"."),p("p",null,p("code",null,"Nothing")," matches your query for '",e.searchString,"'."),p("p",null,p("code",null,"Left \"no matches for '",e.searchString,"'\" :: Either String (NonEmpty SearchResult)"))];return t[(e.searchString||"a").charCodeAt(0)%t.length]}function c(e,t){d.render(p(m,{baseUrl:e||".",showHideTrigger:t||r}),document.body)}var u=this&&this.__extends||function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function o(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(o.prototype=n.prototype,new o)}}();Object.defineProperty(n,"__esModule",{value:!0});var h=e("fuse.js"),d=e("preact"),p=d.h,f=d.Component,v=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return u(t,e),t.prototype.render=function(e){return p("li",null,p("a",{href:"#",onClick:function(t){t.preventDefault(),e.onClick()}},e.title))},t}(f),m=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.linkIndex=0,t.focusPlease=!1,t.navigatedByKeyboard=!1,t}return u(t,e),t.prototype.componentWillMount=function(){var e=this;this.setState({searchString:"",isVisible:!1,expanded:{},activeLinkIndex:-1,moduleResults:[]}),o(this.props.baseUrl+"/doc-index.json",function(t){e.setState({fuse:new h(t,{threshold:.4,caseSensitive:!0,includeScore:!0,tokenize:!0,keys:["name","module"]}),moduleResults:[]})},function(t){console&&console.error("could not load 'doc-index.json' for searching",t),e.setState({failedLoading:!0})}),document.addEventListener("mousedown",this.hide.bind(this)),document.addEventListener("keydown",function(t){e.state.isVisible&&("Escape"===t.key?e.hide():"ArrowUp"===t.key||"k"===t.key&&t.ctrlKey?(t.preventDefault(),e.navigateLinks(-1)):"ArrowDown"===t.key||"j"===t.key&&t.ctrlKey?(t.preventDefault(),e.navigateLinks(1)):"Enter"===t.key&&e.state.activeLinkIndex>=0&&e.followActiveLink()),"s"===t.key&&"input"!==t.target.tagName.toLowerCase()&&(t.preventDefault(),e.show())})},t.prototype.hide=function(){this.setState({isVisible:!1})},t.prototype.show=function(){this.state.isVisible||(this.focusPlease=!0,this.setState({isVisible:!0,activeLinkIndex:-1}))},t.prototype.toggleVisibility=function(){this.state.isVisible?this.hide():this.show()},t.prototype.navigateLinks=function(e){var t=Math.max(-1,Math.min(this.linkIndex-1,this.state.activeLinkIndex+e));this.navigatedByKeyboard=!0,this.setState({activeLinkIndex:t})},t.prototype.followActiveLink=function(){this.activeLinkAction&&this.activeLinkAction()},t.prototype.updateResults=function(){var e=this.input&&this.input.value||"",t={};this.state.fuse.search(e).forEach(function(e){var n=e.item.module;(t[n]||(t[n]=[])).push(e)});var n=[];for(var o in t)!function(e){var o=t[e],r=0;o.forEach(function(e){r+=1/e.score}),n.push({module:e,totalScore:1/r,items:o})}(o);n.sort(function(e,t){return e.totalScore-t.totalScore}),this.setState({searchString:e,isVisible:!0,moduleResults:n})},t.prototype.componentDidUpdate=function(){if(this.searchResults&&this.activeLink&&this.navigatedByKeyboard){var e=this.activeLink.getClientRects()[0],t=this.searchResults.getClientRects()[0].top;e.bottom>window.innerHeight?this.searchResults.scrollTop+=e.bottom-window.innerHeight+80:e.topn)return i(e,this.pattern,o);var r=this.options,a=r.location,l=r.distance,c=r.threshold,u=r.findAllMatches,h=r.minMatchCharLength;return s(e,this.pattern,this.patternAlphabet,{location:a,distance:l,threshold:c,findAllMatches:u,minMatchCharLength:h})}}]),e}();e.exports=l},function(e,t,n){"use strict";var o=n(0),r=function e(t,n,r){if(n){var i=n.indexOf("."),s=n,a=null;-1!==i&&(s=n.slice(0,i),a=n.slice(i+1));var l=t[s];if(null!==l&&void 0!==l)if(a||"string"!=typeof l&&"number"!=typeof l)if(o(l))for(var c=0,u=l.length;c0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=[],o=-1,r=-1,i=0,s=e.length;i=t&&n.push([o,r]),o=-1)}return e[i-1]&&i-o>=t&&n.push([o,i-1]),n}},function(e,t,n){"use strict";e.exports=function(e){for(var t={},n=e.length,o=0;o2&&void 0!==arguments[2]?arguments[2]:/ +/g,r=new RegExp(t.replace(o,"\\$&").replace(n,"|")),i=e.match(r),s=!!i,a=[];if(s)for(var l=0,c=i.length;l=E;P-=1){var R=P-1,U=n[e.charAt(R)];if(U&&(b[R]=1),j[P]=(j[P+1]<<1|1)&U,0!==N&&(j[P]|=(L[P+1]|L[P])<<1|1|L[P+1]),j[P]&I&&(C=o(t,{errors:N,currentLocation:R,expectedLocation:m,distance:c}))<=y){if(y=C,(_=R)<=m)break;E=Math.max(1,2*m-_)}}if(o(t,{errors:N+1,currentLocation:m,expectedLocation:m,distance:c})>y)break;L=j}return{isMatch:_>=0,score:0===C?.001:C,matchedIndices:r(b,v)}}},function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var r=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:"",t=[];if(this.options.tokenize)for(var n=e.split(this.options.tokenSeparator),o=0,r=n.length;o0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n=this.list,o={},r=[];if("string"==typeof n[0]){for(var i=0,s=n.length;i1)throw new Error("Key weight has to be > 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,l=e.index,c=t.tokenSearchers,u=void 0===c?[]:c,h=t.fullSearcher,d=void 0===h?[]:h,p=t.resultMap,f=void 0===p?{}:p,v=t.results,m=void 0===v?[]:v;if(void 0!==i&&null!==i){var g=!1,y=-1,_=0;if("string"==typeof i){this._log("\nKey: "+(""===n?"-":n));var k=d.search(i);if(this._log('Full text: "'+i+'", score: '+k.score),this.options.tokenize){for(var b=i.split(this.options.tokenSeparator),x=[],S=0;S-1&&(E=(E+y)/2),this._log("Score average:",E);var T=!this.options.tokenize||!this.options.matchAllTokens||_>=u.length;if(this._log("\nCheck Matches: "+T),(g||k.isMatch)&&T){var j=f[l];j?j.output.push({key:n,arrayIndex:r,value:i,score:E,matchedIndices:k.matchedIndices}):(f[l]={item:s,output:[{key:n,arrayIndex:r,value:i,score:E,matchedIndices:k.matchedIndices}]},m.push(f[l]))}}else if(a(i))for(var P=0,R=i.length;P-1&&(s.arrayIndex=i.arrayIndex),t.matches.push(s)}}}),this.options.includeScore&&n.push(function(e,t){t.score=e.score});for(var o=0,r=e.length;o2;)A.push(arguments[s]);for(n&&null!=n.children&&(A.length||A.push(n.children),delete n.children);A.length;)if((r=A.pop())&&void 0!==r.pop)for(s=r.length;s--;)A.push(r[s]);else"boolean"==typeof r&&(r=null),(i="function"!=typeof t)&&(null==r?r="":"number"==typeof r?r=String(r):"string"!=typeof r&&(i=!1)),i&&o?a[a.length-1]+=r:a===O?a=[r]:a.push(r),o=i;var l=new e;return l.nodeName=t,l.children=a,l.attributes=null==n?void 0:n,l.key=null==n?void 0:n.key,void 0!==N.vnode&&N.vnode(l),l}function o(e,t){for(var n in t)e[n]=t[n];return e}function r(e){!e.__d&&(e.__d=!0)&&1==j.push(e)&&(N.debounceRendering||E)(i)}function i(){var e,t=j;for(j=[];e=t.pop();)e.__d&&L(e)}function s(e,t,n){return"string"==typeof t||"number"==typeof t?void 0!==e.splitText:"string"==typeof t.nodeName?!e._componentConstructor&&a(e,t.nodeName):n||e._componentConstructor===t.nodeName}function a(e,t){return e.__n===t||e.nodeName.toLowerCase()===t.toLowerCase()}function l(e){var t=o({},e.attributes);t.children=e.children;var n=e.nodeName.defaultProps;if(void 0!==n)for(var r in n)void 0===t[r]&&(t[r]=n[r]);return t}function c(e,t){var n=t?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e);return n.__n=e,n}function u(e){var t=e.parentNode;t&&t.removeChild(e)}function h(e,t,n,o,r){if("className"===t&&(t="class"),"key"===t);else if("ref"===t)n&&n(null),o&&o(e);else if("class"!==t||r)if("style"===t){if(o&&"string"!=typeof o&&"string"!=typeof n||(e.style.cssText=o||""),o&&"object"==typeof o){if("string"!=typeof n)for(var i in n)i in o||(e.style[i]="");for(var i in o)e.style[i]="number"==typeof o[i]&&!1===T.test(i)?o[i]+"px":o[i]}}else if("dangerouslySetInnerHTML"===t)o&&(e.innerHTML=o.__html||"");else if("o"==t[0]&&"n"==t[1]){var s=t!==(t=t.replace(/Capture$/,""));t=t.toLowerCase().substring(2),o?n||e.addEventListener(t,p,s):e.removeEventListener(t,p,s),(e.__l||(e.__l={}))[t]=o}else if("list"!==t&&"type"!==t&&!r&&t in e)d(e,t,null==o?"":o),null!=o&&!1!==o||e.removeAttribute(t);else{var a=r&&t!==(t=t.replace(/^xlink\:?/,""));null==o||!1===o?a?e.removeAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase()):e.removeAttribute(t):"function"!=typeof o&&(a?e.setAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase(),o):e.setAttribute(t,o))}else e.className=o||""}function d(e,t,n){try{e[t]=n}catch(e){}}function p(e){return this.__l[e.type](N.event&&N.event(e)||e)}function f(){for(var e;e=P.pop();)N.afterMount&&N.afterMount(e),e.componentDidMount&&e.componentDidMount()}function v(e,t,n,o,r,i){R++||(U=null!=r&&void 0!==r.ownerSVGElement,D=null!=e&&!("__preactattr_"in e));var s=m(e,t,n,o,i);return r&&s.parentNode!==r&&r.appendChild(s),--R||(D=!1,i||f()),s}function m(e,t,n,o,r){var i=e,s=U;if(null!=t&&"boolean"!=typeof t||(t=""),"string"==typeof t||"number"==typeof t)return e&&void 0!==e.splitText&&e.parentNode&&(!e._component||r)?e.nodeValue!=t&&(e.nodeValue=t):(i=document.createTextNode(t),e&&(e.parentNode&&e.parentNode.replaceChild(i,e),y(e,!0))),i.__preactattr_=!0,i;var l=t.nodeName;if("function"==typeof l)return C(e,t,n,o);if(U="svg"===l||"foreignObject"!==l&&U,l=String(l),(!e||!a(e,l))&&(i=c(l,U),e)){for(;e.firstChild;)i.appendChild(e.firstChild);e.parentNode&&e.parentNode.replaceChild(i,e),y(e,!0)}var u=i.firstChild,h=i.__preactattr_,d=t.children;if(null==h){h=i.__preactattr_={};for(var p=i.attributes,f=p.length;f--;)h[p[f].name]=p[f].value}return!D&&d&&1===d.length&&"string"==typeof d[0]&&null!=u&&void 0!==u.splitText&&null==u.nextSibling?u.nodeValue!=d[0]&&(u.nodeValue=d[0]):(d&&d.length||null!=u)&&g(i,d,n,o,D||null!=h.dangerouslySetInnerHTML),k(i,t.attributes,h),U=s,i}function g(e,t,n,o,r){var i,a,l,c,h,d=e.childNodes,p=[],f={},v=0,g=0,_=d.length,k=0,b=t?t.length:0;if(0!==_)for(L=0;L<_;L++){var x=d[L],S=x.__preactattr_;null!=(w=b&&S?x._component?x._component.__k:S.key:null)?(v++,f[w]=x):(S||(void 0!==x.splitText?!r||x.nodeValue.trim():r))&&(p[k++]=x)}if(0!==b)for(L=0;L2?[].slice.call(arguments,2):e.children)},Component:I,render:function(e,t,n){return v(n,e,{},!1,t,!1)},rerender:i,options:N};void 0!==t?t.exports=F:self.preact=F}()},{}]},{},[2]);
+!function e(t,n,o){function r(s,a){if(!n[s]){if(!t[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){var n=t[s][1][e];return r(n||e)},u,u.exports,e,t,n,o)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s element with id '"+e+"'");return t}function r(e){for(var t=e.target,n=t.id,r=o(n),i=r.element.open,s=0,l=r.toggles;s0&&(d[n.id]={element:n,openByDefault:!!n.open,toggles:[]},n.addEventListener("toggle",r))}}function s(e){var t=o(e).element;t.open=!t.open}function a(){var e=Object.keys(p);document.cookie="toggled="+encodeURIComponent(e.join("+"))}function l(){var e=h.getCookie("toggled");if(e)for(var t=0,n=e.split("+");t=0&&e.followActiveLink()),"s"===t.key&&"input"!==t.target.tagName.toLowerCase()&&(t.preventDefault(),e.show())})},t.prototype.hide=function(){this.setState({isVisible:!1})},t.prototype.show=function(){this.state.isVisible||(this.focusPlease=!0,this.setState({isVisible:!0,activeLinkIndex:-1}))},t.prototype.toggleVisibility=function(){this.state.isVisible?this.hide():this.show()},t.prototype.navigateLinks=function(e){var t=Math.max(-1,Math.min(this.linkIndex-1,this.state.activeLinkIndex+e));this.navigatedByKeyboard=!0,this.setState({activeLinkIndex:t})},t.prototype.followActiveLink=function(){this.activeLinkAction&&this.activeLinkAction()},t.prototype.updateResults=function(){var e=this.input&&this.input.value||"",t={};this.state.fuse.search(e).forEach(function(e){var n=e.item.module;(t[n]||(t[n]=[])).push(e)});var n=[];for(var o in t)!function(e){var o=t[e],r=0;o.forEach(function(e){r+=1/e.score}),n.push({module:e,totalScore:1/r,items:o})}(o);n.sort(function(e,t){return e.totalScore-t.totalScore}),this.setState({searchString:e,isVisible:!0,moduleResults:n})},t.prototype.componentDidUpdate=function(){if(this.searchResults&&this.activeLink&&this.navigatedByKeyboard){var e=this.activeLink.getClientRects()[0],t=this.searchResults.getClientRects()[0].top;e.bottom>window.innerHeight?this.searchResults.scrollTop+=e.bottom-window.innerHeight+80:e.top=0}function s(e,t){var n=o(e.className||"");n.indexOf(" "+t+" ")<0&&(e.className=r(n+" "+t))}function a(e,t){var n=o(e.className||"");n=n.replace(" "+t+" "," "),e.className=r(n)}function l(e,t,n,o){return null==o&&(o=!i(e,t)),o?(a(e,n),s(e,t)):(a(e,t),s(e,n)),o}function c(e){var t=document.getElementById("page-menu");if(t&&t.firstChild){var n=t.firstChild.cloneNode(!1);n.innerHTML=e,t.appendChild(n)}}function u(){return Array.prototype.slice.call(document.getElementsByTagName("link")).filter(function(e){return-1!=e.rel.indexOf("style")&&e.title})}function h(){var e=u(),t="";e.forEach(function(e){t+=""+e.title+""}),e.length>1&&c("")}function d(e){for(var t=u(),n=null,o=0;on)return i(e,this.pattern,o);var r=this.options,a=r.location,l=r.distance,c=r.threshold,u=r.findAllMatches,h=r.minMatchCharLength;return s(e,this.pattern,this.patternAlphabet,{location:a,distance:l,threshold:c,findAllMatches:u,minMatchCharLength:h})}}]),e}();e.exports=l},function(e,t,n){"use strict";var o=n(0),r=function e(t,n,r){if(n){var i=n.indexOf("."),s=n,a=null;-1!==i&&(s=n.slice(0,i),a=n.slice(i+1));var l=t[s];if(null!==l&&void 0!==l)if(a||"string"!=typeof l&&"number"!=typeof l)if(o(l))for(var c=0,u=l.length;c0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=[],o=-1,r=-1,i=0,s=e.length;i=t&&n.push([o,r]),o=-1)}return e[i-1]&&i-o>=t&&n.push([o,i-1]),n}},function(e,t,n){"use strict";e.exports=function(e){for(var t={},n=e.length,o=0;o2&&void 0!==arguments[2]?arguments[2]:/ +/g,r=new RegExp(t.replace(o,"\\$&").replace(n,"|")),i=e.match(r),s=!!i,a=[];if(s)for(var l=0,c=i.length;l=E;P-=1){var R=P-1,U=n[e.charAt(R)];if(U&&(b[R]=1),T[P]=(T[P+1]<<1|1)&U,0!==I&&(T[P]|=(L[P+1]|L[P])<<1|1|L[P+1]),T[P]&N&&(C=o(t,{errors:I,currentLocation:R,expectedLocation:g,distance:c}))<=y){if(y=C,(_=R)<=g)break;E=Math.max(1,2*g-_)}}if(o(t,{errors:I+1,currentLocation:g,expectedLocation:g,distance:c})>y)break;L=T}return{isMatch:_>=0,score:0===C?.001:C,matchedIndices:r(b,v)}}},function(e,t,n){"use strict";function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var r=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:"",t=[];if(this.options.tokenize)for(var n=e.split(this.options.tokenSeparator),o=0,r=n.length;o0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n=this.list,o={},r=[];if("string"==typeof n[0]){for(var i=0,s=n.length;i1)throw new Error("Key weight has to be > 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,l=e.index,c=t.tokenSearchers,u=void 0===c?[]:c,h=t.fullSearcher,d=void 0===h?[]:h,p=t.resultMap,f=void 0===p?{}:p,v=t.results,g=void 0===v?[]:v;if(void 0!==i&&null!==i){var m=!1,y=-1,_=0;if("string"==typeof i){this._log("\nKey: "+(""===n?"-":n));var k=d.search(i);if(this._log('Full text: "'+i+'", score: '+k.score),this.options.tokenize){for(var b=i.split(this.options.tokenSeparator),x=[],w=0;w-1&&(E=(E+y)/2),this._log("Score average:",E);var j=!this.options.tokenize||!this.options.matchAllTokens||_>=u.length;if(this._log("\nCheck Matches: "+j),(m||k.isMatch)&&j){var T=f[l];T?T.output.push({key:n,arrayIndex:r,value:i,score:E,matchedIndices:k.matchedIndices}):(f[l]={item:s,output:[{key:n,arrayIndex:r,value:i,score:E,matchedIndices:k.matchedIndices}]},g.push(f[l]))}}else if(a(i))for(var P=0,R=i.length;P-1&&(s.arrayIndex=i.arrayIndex),t.matches.push(s)}}}),this.options.includeScore&&n.push(function(e,t){t.score=e.score});for(var o=0,r=e.length;o2;)A.push(arguments[s]);for(n&&null!=n.children&&(A.length||A.push(n.children),delete n.children);A.length;)if((r=A.pop())&&void 0!==r.pop)for(s=r.length;s--;)A.push(r[s]);else"boolean"==typeof r&&(r=null),(i="function"!=typeof t)&&(null==r?r="":"number"==typeof r?r=String(r):"string"!=typeof r&&(i=!1)),i&&o?a[a.length-1]+=r:a===O?a=[r]:a.push(r),o=i;var l=new e;return l.nodeName=t,l.children=a,l.attributes=null==n?void 0:n,l.key=null==n?void 0:n.key,void 0!==I.vnode&&I.vnode(l),l}function o(e,t){for(var n in t)e[n]=t[n];return e}function r(e){!e.__d&&(e.__d=!0)&&1==T.push(e)&&(I.debounceRendering||E)(i)}function i(){var e,t=T;for(T=[];e=t.pop();)e.__d&&L(e)}function s(e,t,n){return"string"==typeof t||"number"==typeof t?void 0!==e.splitText:"string"==typeof t.nodeName?!e._componentConstructor&&a(e,t.nodeName):n||e._componentConstructor===t.nodeName}function a(e,t){return e.__n===t||e.nodeName.toLowerCase()===t.toLowerCase()}function l(e){var t=o({},e.attributes);t.children=e.children;var n=e.nodeName.defaultProps;if(void 0!==n)for(var r in n)void 0===t[r]&&(t[r]=n[r]);return t}function c(e,t){var n=t?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e);return n.__n=e,n}function u(e){var t=e.parentNode;t&&t.removeChild(e)}function h(e,t,n,o,r){if("className"===t&&(t="class"),"key"===t);else if("ref"===t)n&&n(null),o&&o(e);else if("class"!==t||r)if("style"===t){if(o&&"string"!=typeof o&&"string"!=typeof n||(e.style.cssText=o||""),o&&"object"==typeof o){if("string"!=typeof n)for(var i in n)i in o||(e.style[i]="");for(var i in o)e.style[i]="number"==typeof o[i]&&!1===j.test(i)?o[i]+"px":o[i]}}else if("dangerouslySetInnerHTML"===t)o&&(e.innerHTML=o.__html||"");else if("o"==t[0]&&"n"==t[1]){var s=t!==(t=t.replace(/Capture$/,""));t=t.toLowerCase().substring(2),o?n||e.addEventListener(t,p,s):e.removeEventListener(t,p,s),(e.__l||(e.__l={}))[t]=o}else if("list"!==t&&"type"!==t&&!r&&t in e)d(e,t,null==o?"":o),null!=o&&!1!==o||e.removeAttribute(t);else{var a=r&&t!==(t=t.replace(/^xlink\:?/,""));null==o||!1===o?a?e.removeAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase()):e.removeAttribute(t):"function"!=typeof o&&(a?e.setAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase(),o):e.setAttribute(t,o))}else e.className=o||""}function d(e,t,n){try{e[t]=n}catch(e){}}function p(e){return this.__l[e.type](I.event&&I.event(e)||e)}function f(){for(var e;e=P.pop();)I.afterMount&&I.afterMount(e),e.componentDidMount&&e.componentDidMount()}function v(e,t,n,o,r,i){R++||(U=null!=r&&void 0!==r.ownerSVGElement,D=null!=e&&!("__preactattr_"in e));var s=g(e,t,n,o,i);return r&&s.parentNode!==r&&r.appendChild(s),--R||(D=!1,i||f()),s}function g(e,t,n,o,r){var i=e,s=U;if(null!=t&&"boolean"!=typeof t||(t=""),"string"==typeof t||"number"==typeof t)return e&&void 0!==e.splitText&&e.parentNode&&(!e._component||r)?e.nodeValue!=t&&(e.nodeValue=t):(i=document.createTextNode(t),e&&(e.parentNode&&e.parentNode.replaceChild(i,e),y(e,!0))),i.__preactattr_=!0,i;var l=t.nodeName;if("function"==typeof l)return C(e,t,n,o);if(U="svg"===l||"foreignObject"!==l&&U,l=String(l),(!e||!a(e,l))&&(i=c(l,U),e)){for(;e.firstChild;)i.appendChild(e.firstChild);e.parentNode&&e.parentNode.replaceChild(i,e),y(e,!0)}var u=i.firstChild,h=i.__preactattr_,d=t.children;if(null==h){h=i.__preactattr_={};for(var p=i.attributes,f=p.length;f--;)h[p[f].name]=p[f].value}return!D&&d&&1===d.length&&"string"==typeof d[0]&&null!=u&&void 0!==u.splitText&&null==u.nextSibling?u.nodeValue!=d[0]&&(u.nodeValue=d[0]):(d&&d.length||null!=u)&&m(i,d,n,o,D||null!=h.dangerouslySetInnerHTML),k(i,t.attributes,h),U=s,i}function m(e,t,n,o,r){var i,a,l,c,h,d=e.childNodes,p=[],f={},v=0,m=0,_=d.length,k=0,b=t?t.length:0;if(0!==_)for(L=0;L<_;L++){var x=d[L],w=x.__preactattr_;null!=(S=b&&w?x._component?x._component.__k:w.key:null)?(v++,f[S]=x):(w||(void 0!==x.splitText?!r||x.nodeValue.trim():r))&&(p[k++]=x)}if(0!==b)for(L=0;L2?[].slice.call(arguments,2):e.children)},Component:N,render:function(e,t,n){return v(n,e,{},!1,t,!1)},rerender:i,options:I};void 0!==t?t.exports=B:self.preact=B}()},{}]},{},[3]);
//# sourceMappingURL=haddock-bundle.min.js.map
diff --git a/haddock-api/resources/html/js-src/cookies.ts b/haddock-api/resources/html/js-src/cookies.ts
new file mode 100644
index 00000000..3b68d6d8
--- /dev/null
+++ b/haddock-api/resources/html/js-src/cookies.ts
@@ -0,0 +1,20 @@
+export function setCookie(name: string, value: string) {
+ document.cookie = name + "=" + encodeURIComponent(value) + ";path=/;";
+}
+
+export function clearCookie(name: string) {
+ document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;";
+}
+
+export function getCookie(name: string) {
+ const nameEQ = name + "=";
+ const ca = document.cookie.split(';');
+ for (let i = 0; i < ca.length; i++) {
+ let c = ca[i];
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
+ if (c.indexOf(nameEQ) == 0) {
+ return decodeURIComponent(c.substring(nameEQ.length,c.length));
+ }
+ }
+ return null;
+}
\ No newline at end of file
diff --git a/haddock-api/resources/html/js-src/details-helper.ts b/haddock-api/resources/html/js-src/details-helper.ts
new file mode 100644
index 00000000..f13ac905
--- /dev/null
+++ b/haddock-api/resources/html/js-src/details-helper.ts
@@ -0,0 +1,106 @@
+import {getCookie} from "./cookies";
+
+interface HTMLDetailsElement extends HTMLElement {
+ open: boolean
+}
+
+interface DetailsInfo {
+ element: HTMLDetailsElement
+ openByDefault: boolean
+ toggles: HTMLElement[]
+}
+
+// Global state
+const detailsRegistry: { [id: string]: DetailsInfo } = {};
+const toggled: { [id: string]: true } = {}; /* stores which 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/haddock-util.ts b/haddock-api/resources/html/js-src/haddock-util.ts
deleted file mode 100644
index 257ceb6a..00000000
--- a/haddock-api/resources/html/js-src/haddock-util.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-// Haddock JavaScript utilities
-
-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");
-const toggleCollapser = makeClassToggle("collapser", "expander");
-
-function toggleSection(id: string): boolean {
- const b = toggleShow(document.getElementById("section." + id) as Element);
- toggleCollapser(document.getElementById("control." + id) as Element, b);
- rememberCollapsed(id);
- return b;
-}
-
-// TODO: get rid of global variables
-if (typeof window !== 'undefined') {
- (window as any).toggleSection = toggleSection;
-}
-
-const collapsed: { [id: string]: boolean } = {};
-function rememberCollapsed(id: string) {
- if(collapsed[id])
- delete collapsed[id]
- else
- collapsed[id] = true;
-
- const sections: string[] = [];
- for(let i in collapsed) {
- if(collapsed.hasOwnProperty(i))
- sections.push(i);
- }
- // cookie specific to this page; don't use setCookie which sets path=/
- document.cookie = "collapsed=" + encodeURIComponent(sections.join('+'));
-}
-
-export function restoreCollapsed() {
- const cookie = getCookie("collapsed");
- if(!cookie)
- return;
-
- const ids = cookie.split('+');
- for(const i in ids)
- {
- if(document.getElementById("section." + ids[i]))
- toggleSection(ids[i]);
- }
-}
-
-function setCookie(name: string, value: string) {
- document.cookie = name + "=" + encodeURIComponent(value) + ";path=/;";
-}
-
-function clearCookie(name: string) {
- document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;";
-}
-
-function getCookie(name: string) {
- const nameEQ = name + "=";
- const ca = document.cookie.split(';');
- for (let i = 0; i < ca.length; i++) {
- let c = ca[i];
- while (c.charAt(0)==' ') c = c.substring(1,c.length);
- if (c.indexOf(nameEQ) == 0) {
- return decodeURIComponent(c.substring(nameEQ.length,c.length));
- }
- }
- return null;
-}
-
-function addMenuItem(html: string) {
- const menu = document.getElementById("page-menu");
- if (menu && menu.firstChild) {
- const btn = menu.firstChild.cloneNode(false) as Element;
- btn.innerHTML = html;
- menu.appendChild(btn);
- }
-}
-
-function styles(): HTMLLinkElement[] {
- const es = Array.prototype.slice.call(document.getElementsByTagName("link"));
- return es.filter((a: HTMLLinkElement) => a.rel.indexOf("style") != -1 && a.title);
-}
-
-export function addStyleMenu() {
- const as = styles();
- let btns = "";
- as.forEach((a) => {
- btns += ""
- + a.title + ""
- });
- if (as.length > 1) {
- const h = "";
- addMenuItem(h);
- }
-}
-
-function setActiveStyleSheet(title: string) {
- const as = styles();
- let found: null | HTMLLinkElement = null;
- for(let i = 0; i < as.length; i++) {
- const a = as[i];
- a.disabled = true;
- // need to do this always, some browsers are edge triggered
- if(a.title == title) {
- found = a;
- }
- }
- if (found) {
- found.disabled = false;
- setCookie("haddock-style", title);
- }
- else {
- as[0].disabled = false;
- clearCookie("haddock-style");
- }
- styleMenu(false);
-}
-
-export 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);
-}
\ No newline at end of file
diff --git a/haddock-api/resources/html/js-src/init.ts b/haddock-api/resources/html/js-src/init.ts
index 0619dfc3..877874ae 100644
--- a/haddock-api/resources/html/js-src/init.ts
+++ b/haddock-api/resources/html/js-src/init.ts
@@ -1,4 +1,5 @@
-import * as util from "./haddock-util";
+import * as styleMenu from "./style-menu";
+import * as detailsHelper from "./details-helper";
import * as quickJump from "./quick-jump";
function onDomReady(callback: () => void) {
@@ -14,8 +15,8 @@ function onDomReady(callback: () => void) {
}
onDomReady(() => {
- util.addStyleMenu();
- util.resetStyle();
- util.restoreCollapsed();
+ document.body.classList.add('js-enabled');
+ styleMenu.init();
+ detailsHelper.init();
quickJump.init();
});
\ No newline at end of file
diff --git a/haddock-api/resources/html/js-src/style-menu.ts b/haddock-api/resources/html/js-src/style-menu.ts
new file mode 100644
index 00000000..3911655b
--- /dev/null
+++ b/haddock-api/resources/html/js-src/style-menu.ts
@@ -0,0 +1,116 @@
+// Haddock JavaScript utilities
+
+import {getCookie, setCookie, clearCookie} from "./cookies";
+
+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");
+
+function addMenuItem(html: string) {
+ const menu = document.getElementById("page-menu");
+ if (menu && menu.firstChild) {
+ const btn = menu.firstChild.cloneNode(false) as Element;
+ btn.innerHTML = html;
+ menu.appendChild(btn);
+ }
+}
+
+function styles(): HTMLLinkElement[] {
+ const es = Array.prototype.slice.call(document.getElementsByTagName("link"));
+ return es.filter((a: HTMLLinkElement) => a.rel.indexOf("style") != -1 && a.title);
+}
+
+function addStyleMenu() {
+ const as = styles();
+ let btns = "";
+ as.forEach((a) => {
+ btns += ""
+ + a.title + ""
+ });
+ if (as.length > 1) {
+ const h = "";
+ addMenuItem(h);
+ }
+}
+
+function setActiveStyleSheet(title: string) {
+ const as = styles();
+ let found: null | HTMLLinkElement = null;
+ for(let i = 0; i < as.length; i++) {
+ const a = as[i];
+ a.disabled = true;
+ // need to do this always, some browsers are edge triggered
+ if(a.title == title) {
+ found = a;
+ }
+ }
+ if (found) {
+ found.disabled = false;
+ setCookie("haddock-style", title);
+ }
+ else {
+ as[0].disabled = false;
+ clearCookie("haddock-style");
+ }
+ styleMenu(false);
+}
+
+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);
+}
+
+export function init() {
+ addStyleMenu();
+ resetStyle();
+}
\ No newline at end of file
diff --git a/haddock-api/src/Haddock/Backends/Xhtml.hs b/haddock-api/src/Haddock/Backends/Xhtml.hs
index e8148782..c76c0c88 100644
--- a/haddock-api/src/Haddock/Backends/Xhtml.hs
+++ b/haddock-api/src/Haddock/Backends/Xhtml.hs
@@ -310,11 +310,11 @@ mkNode qual ss p (Node s leaf pkg srcPkg short ts) =
htmlModule <+> shortDescr +++ htmlPkg +++ subtree
where
modAttrs = case (ts, leaf) of
- (_:_, False) -> collapseControl p True "module"
+ (_:_, False) -> collapseControl p "module"
(_, _ ) -> [theclass "module"]
cBtn = case (ts, leaf) of
- (_:_, True) -> thespan ! collapseControl p True "" << spaceHtml
+ (_:_, True) -> thespan ! collapseControl p "" << spaceHtml
(_, _ ) -> noHtml
-- We only need an explicit collapser button when the module name
-- is also a leaf, and so is a link to a module page. Indeed, the
@@ -332,7 +332,12 @@ mkNode qual ss p (Node s leaf pkg srcPkg short ts) =
shortDescr = maybe noHtml (origDocToHtml qual) short
htmlPkg = maybe noHtml (thespan ! [theclass "package"] <<) srcPkg
- subtree = mkNodeList qual (s:ss) p ts ! collapseSection p True ""
+ subtree =
+ if null ts then noHtml else
+ collapseDetails p DetailsOpen (
+ thesummary ! [ theclass "hide-when-js-enabled" ] << "Submodules" +++
+ mkNodeList qual (s:ss) p ts
+ )
@@ -586,10 +591,12 @@ ifaceToHtml maybe_source_url maybe_wiki_url iface unicode qual
| no_doc_at_all = noHtml
| otherwise
= divSynopsis $
- paragraph ! collapseControl "syn" False "caption" << "Synopsis" +++
- shortDeclList (
- mapMaybe (processExport True linksInfo unicode qual) exports
- ) ! (collapseSection "syn" False "" ++ collapseToggle "syn")
+ collapseDetails "syn" DetailsClosed (
+ thesummary << "Synopsis" +++
+ shortDeclList (
+ mapMaybe (processExport True linksInfo unicode qual) exports
+ ) ! collapseToggle "syn" ""
+ )
-- if the documentation doesn't begin with a section header, then
-- add one ("Documentation").
diff --git a/haddock-api/src/Haddock/Backends/Xhtml/DocMarkup.hs b/haddock-api/src/Haddock/Backends/Xhtml/DocMarkup.hs
index 18c8a0ff..e63667b0 100644
--- a/haddock-api/src/Haddock/Backends/Xhtml/DocMarkup.hs
+++ b/haddock-api/src/Haddock/Backends/Xhtml/DocMarkup.hs
@@ -165,9 +165,9 @@ hackMarkup fmt' h' =
UntouchedDoc d -> (markup fmt $ _doc d, [_meta d])
CollapsingHeader (Header lvl titl) par n nm ->
let id_ = makeAnchorId $ "ch:" ++ fromMaybe "noid:" nm ++ show n
- expanded = False
- col' = collapseControl id_ expanded "caption"
- instTable = (thediv ! collapseSection id_ expanded [] <<)
+ col' = collapseControl id_ "caption"
+ summary = thesummary ! [ theclass "hide-when-js-enabled" ] << "Expand"
+ instTable contents = collapseDetails id_ DetailsClosed (summary +++ contents)
lvs = zip [1 .. ] [h1, h2, h3, h4, h5, h6]
getHeader = fromMaybe caption (lookup lvl lvs)
subCaption = getHeader ! col' << markup fmt titl
diff --git a/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs b/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs
index 6993c7f6..e020b909 100644
--- a/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs
+++ b/haddock-api/src/Haddock/Backends/Xhtml/Layout.hs
@@ -199,10 +199,10 @@ subInstances :: Qualification
-> [(SubDecl,Located DocName)] -> Html
subInstances qual nm lnks splice = maybe noHtml wrap . instTable
where
- wrap = (subSection <<) . (subCaption +++)
- instTable = fmap (thediv ! collapseSection id_ True [] <<) . subTableSrc qual lnks splice
+ wrap contents = subSection (collapseDetails id_ DetailsOpen (summary +++ contents))
+ instTable = subTableSrc qual lnks splice
subSection = thediv ! [theclass "subs instances"]
- subCaption = paragraph ! collapseControl id_ True "caption" << "Instances"
+ summary = thesummary << "Instances"
id_ = makeAnchorId $ "i:" ++ nm
@@ -212,7 +212,7 @@ subOrphanInstances :: Qualification
subOrphanInstances qual lnks splice = maybe noHtml wrap . instTable
where
wrap = ((h1 << "Orphan instances") +++)
- instTable = fmap (thediv ! collapseSection id_ True [] <<) . subTableSrc qual lnks splice
+ instTable = fmap (thediv ! [ identifier ("section." ++ id_) ] <<) . subTableSrc qual lnks splice
id_ = makeAnchorId $ "orphans"
@@ -222,7 +222,7 @@ subInstHead :: String -- ^ Instance unique id (for anchor generation)
subInstHead iid hdr =
expander noHtml <+> hdr
where
- expander = thespan ! collapseControl (instAnchorId iid) False "instance"
+ expander = thespan ! collapseControl (instAnchorId iid) "instance"
subInstDetails :: String -- ^ Instance unique id (for anchor generation)
@@ -241,7 +241,9 @@ subFamInstDetails iid fi =
subInstSection :: String -- ^ Instance unique id (for anchor generation)
-> Html
-> Html
-subInstSection iid = thediv ! collapseSection (instAnchorId iid) False "inst-details"
+subInstSection iid contents = collapseDetails (instAnchorId iid) DetailsClosed (summary +++ contents)
+ where
+ summary = thesummary ! [ theclass "hide-when-js-enabled" ] << "Instance details"
instAnchorId :: String -> String
instAnchorId iid = makeAnchorId $ "i:" ++ iid
diff --git a/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs b/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs
index a8b4a4ec..a75c4b9a 100644
--- a/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs
+++ b/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs
@@ -25,7 +25,8 @@ module Haddock.Backends.Xhtml.Utils (
hsep, vcat,
- collapseSection, collapseToggle, collapseControl,
+ DetailsState(..), collapseDetails, thesummary,
+ collapseToggle, collapseControl,
) where
@@ -213,26 +214,22 @@ groupId g = makeAnchorId ("g:" ++ g)
-- A section of HTML which is collapsible.
--
--- | Attributes for an area that can be collapsed
-collapseSection :: String -> Bool -> String -> [HtmlAttr]
-collapseSection id_ state classes = [ identifier sid, theclass cs ]
- where cs = unwords (words classes ++ [pick state "show" "hide"])
- sid = "section." ++ id_
+data DetailsState = DetailsOpen | DetailsClosed
+
+collapseDetails :: String -> DetailsState -> Html -> Html
+collapseDetails id_ state = tag "details" ! (identifier id_ : openAttrs)
+ where openAttrs = case state of { DetailsOpen -> [emptyAttr "open"]; DetailsClosed -> [] }
+
+thesummary :: Html -> Html
+thesummary = tag "summary"
-- | Attributes for an area that toggles a collapsed area
-collapseToggle :: String -> [HtmlAttr]
-collapseToggle id_ = [ strAttr "onclick" js ]
- where js = "toggleSection('" ++ id_ ++ "')";
+collapseToggle :: String -> String -> [HtmlAttr]
+collapseToggle id_ classes = [ theclass cs, strAttr "data-details-id" id_ ]
+ where cs = unwords (words classes ++ ["details-toggle"])
-- | Attributes for an area that toggles a collapsed area,
-- and displays a control.
-collapseControl :: String -> Bool -> String -> [HtmlAttr]
-collapseControl id_ state classes =
- [ identifier cid, theclass cs ] ++ collapseToggle id_
- where cs = unwords (words classes ++ [pick state "collapser" "expander"])
- cid = "control." ++ id_
-
-
-pick :: Bool -> a -> a -> a
-pick True t _ = t
-pick False _ f = f
+collapseControl :: String -> String -> [HtmlAttr]
+collapseControl id_ classes = collapseToggle id_ cs
+ where cs = unwords (words classes ++ ["details-toggle-control"])
\ No newline at end of file
diff --git a/html-test/ref/A.html b/html-test/ref/A.html
index 094455f8..1fbfb371 100644
--- a/html-test/ref/A.html
+++ b/html-test/ref/A.html
@@ -39,44 +39,46 @@
>A
B
Bold
Bug1
Bug201
Synopsis
- f :: ()
Synopsis
f :: ()- g :: ()
Synopsis
- f :: ()
- g :: ()
Synopsis
- class C a where
- g :: ()
- class C a where
Instances
Instances
#Instances
Instances
#
Instances
Instances
Bug298Synopsis
- (<^>) :: (a -> a) -> a -> a
- (<^) :: a -> a -> a
- (^>) :: a -> a -> a
- (⋆^) :: a -> a -> a
Synopsis
(<^>) :: (a -> a) -> a -> a- (<^) :: a -> a -> a
- (^>) :: a -> a -> a
- (⋆^) :: a -> a -> a
- f :: ()
Bug3
Bug308
Synopsis
- f :: ()
Synopsis
f :: ()- g :: ()
Bug308CrossModule
Bug310
Synopsis
- type family (a :: Nat) + (b :: Nat) :: Nat where ...
Synopsis
- type family (a :: Nat) + (b :: Nat) :: Nat where ...
Synopsis
- a :: a
Synopsis
a :: a- b :: a
Bug335
Synopsis
- f :: ()
Synopsis
f :: ()- g :: ()
Bug613
Instances
Instances
Instances
Instances
The Bar class
Instances
Instances
BugDeprecatedBundledPatterns
BundledPatterns2
DeprecatedClass
DeprecatedData
DeprecatedFunction
DeprecatedFunction2
DeprecatedFunction3
DeprecatedNewtype
DeprecatedRecord
DeprecatedTypeFamily
DeprecatedTypeSynonym
Examples
Extensions
GADTRecords
Instances
Instances
HiddenInstancesShould be visible
Instances
Instances
Should be visible
Instances
Instances
HiddenInstancesBShould be visible
Instances
Instances
Should be visible
Instances
Instances
HyperlinksIgnoreExports
Instances
Instances
Instances
Instances
Instances
Instances
Instances
Instances
Instances
Instances
Instances
NamedDoc
Nesting
Synopsis
- d :: t
- e :: t
- f :: t
- g :: t
Synopsis
d :: t- e :: t
- f :: t
- g :: t
- h :: t
- i :: t
- j :: t
- k :: t
NoLayout
NonGreedy
Synopsis
- (+-) :: a -> a -> a
- (*/) :: a -> a -> a
- foo :: a -> a -> a
Synopsis
- data Foo
- (*/) :: a -> a -> a
- foo :: a -> a -> a
- data Foo
- pattern (:+) :: forall a. a -> a -> [a]
- data a <-> b where
- type family a ++ b
- data family a ** b
- class a ><> b | a -> b where
- | Foo :- Foo
- pattern (:+) :: forall a. a -> a -> [a]
- data a <-> b where
- type (>-<) a b = a <-> b
(:<->) :: a -> b -> a
<-> b
type family a ++ bdata family a ** bclass a ><> b | a -> b wheretype (>-<) a b = a <-> bDocumentation
Orphan instances
Properties
Instances
Instances
Instances
#
Instances
Instances
Instances
Instances
Ticket112
Ticket75
TitledPicture
Synopsis
- data X
Synopsis
- data Y
- data Z
- type family Bar b where ...
- type family (a :: k) <> (b :: k) :: k
- class (a :: k) >< (b :: k)
=
ZA| ZBclass Test atype family Foo a :: kdata family Bat (a :: k) :: *class Assoc a wheretype family Bar b where ...type family (a :: k) <> (b :: k) :: kclass (a :: k) >< (b :: k)
Instances
Instances
(><) |
Instance details |
Assoc |
|
Test |
Instance details |
type |
|
type |
|
data |
|
type |
|
data |
|
type |
|
type |
|
Doc for: data Y
Instances
Instances
Assoc |
|
Test |
Instance details |
data |
|
data |
|
type |
|
data |
|
type |
|
type |
|
Instances
Instances
Doc for: class Test a
Instances
Instances
Test |
Instance details |
Test |
Instance details |
Doc for: type family Foo a
Instances
Instances
Doc for: data family Bat a
Instances
Instances
Instances
Instances
#
Instances
Instances
#
Instances
Instances
TypeFamilies2Synopsis
- data W
- type family Foo a
Synopsis
data W- type family Foo a
- data family Bar a
Exported type
Instances
Instances
Exported type family
Instances
Instances
Exported data family