diff options
author | Alec Theriault <alec.theriault@gmail.com> | 2018-11-10 14:35:10 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-10 14:35:10 -0800 |
commit | f4d53a159642aa9182241259709659e7074425d5 (patch) | |
tree | bd149a37f465ea9d94f32108992380d4352cd4db /haddock-api/resources/html/js-src/style-menu.tsx | |
parent | 8a491e437f1c8379b66a420f8584c1761b45aa7e (diff) | |
parent | 6e281ee1dfc994c40775eda044992980738d044e (diff) |
Merge pull request #949 from haskell/wip/new-ocean
Introduce NewOcean theme.
Diffstat (limited to 'haddock-api/resources/html/js-src/style-menu.tsx')
-rw-r--r-- | haddock-api/resources/html/js-src/style-menu.tsx | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/haddock-api/resources/html/js-src/style-menu.tsx b/haddock-api/resources/html/js-src/style-menu.tsx new file mode 100644 index 00000000..bab840ca --- /dev/null +++ b/haddock-api/resources/html/js-src/style-menu.tsx @@ -0,0 +1,126 @@ +// Haddock JavaScript utilities + +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"); + +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<any, any> { + + render(props: { stys: string[] }) { + function action() { + styleMenu(); + return false; + }; + + return <li><div id='style-menu-holder' onClick={action}> + <a href='#'>Style ▾</a> + <ul id='style-menu' class='hide'> + {props.stys.map((sty) => { + function action() { + setActiveStyleSheet(sty); + return false; + }; + + return <li><a href='#' onClick={action}>{sty}</a></li>; + })} + </ul> + </div></li>; + } + +} + +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(<StyleMenuButton stys={stys} title="Style"/>, pageMenu, dummy); + } +} + +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"); + } +} + +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(); +} |