NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name hammerspoon.org Documentation // @license MIT // @version 2019.08.16 // @description Add TOC // @author krasnovpro // @include /^https?://(.*hammerspoon\.org/(docs|Spoons)|(127\.0\.0\.1|localhost):12345)/.*$/ // @updateURL https://openuserjs.org/meta/krasnovpro/hammerspoon.org_Documentation.meta.js // @downloadURL https://openuserjs.org/src/scripts/krasnovpro/hammerspoon.org_Documentation.user.js // @require https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js // @grant none // ==/UserScript== let cssToc = `<style> html { left: 0; top: 30px; } body { background: var(--line); padding: 0; margin-top: 0; } td, p, li { font-family: var(--ftitle); font-size: var(--fsize); font-weight: 100; } .api-documentation-overview th, .api-documentation-overview td { border-top: 1px solid #444; padding-top: calc(var(--margin) / 3); padding-left: var(--margin); } </style>`.trim(); let cssIndex = `<style> header>h1 { border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; } /* top urls block */ .urls { height: 1.3em; overflow: hidden; margin-bottom: var(--margin); padding: var(--margin); padding-top: 0; transition: height .3s ease-in-out; } .urls:hover { height: 13em; } .urls * { font-size: var(--fsize); line-height: var(--flheight); } .urls tr:first-of-type, .urls+br, body>br { display: none !important; } .api-documentation-overview th, .api-documentation-overview td { border-top: 1px solid var(--line); padding-top: calc(var(--margin) / 3); padding-left: var(--margin); } .api-documentation-overview p { font-family: var(--ftitle); font-weight: 100; font-size: var(--fsize); } /* search */ #search, #search_desc { left: calc(var(--mleft) + var(--margin)); top: 4rem; width: calc(100% - var(--mleft) - var(--mright) - var(--margin) * 3); } #search_desc { left: calc(100% - var(--mright) - var(--margin) * 2); width: var(--margin); } </style>`.trim(); let cssInner = `<style> :root { --bg: #222; --line: #333; --text: #bbb; --link: #b73; --desc: white; --ftitle: "Open Sans", "Roboto", Helvetica, Arial, sans-serif; --ftext: var(--ftitle); --fcode: "PragmataPro", "Menlo", "Lucida Console", Courier, monospace; --fsize: .7rem; --flheight: 1.5; --margin: 15px; --mleft: 20%; --mleft: 20vw; --mright: calc(var(--mleft)/2); --mbot: var(--mleft); } /* toc */ #toc { border: none; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; box-shadow: 0 calc(var(--margin) / 2) calc(var(--margin) * 2) calc(var(--margin) / -2) #000f; height: 20px; left: var(--mleft); opacity: 0; position: fixed; top: 51px; transition: height .2s ease-in-out, opacity .2s ease-in-out; width: calc(100% - var(--mleft) - var(--mright)); } #toc:hover { height: calc(100% - var(--mbot)); opacity: 1; } #hint { background: var(--line); border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; color: var(--link); font-family: var(--ftext); font-size: var(--fsize); left: calc(var(--mleft) + 10px); line-height: 10px; margin: 0; margin-left: -10px; padding: 10px; padding-top: 0; position: fixed; top: 52px; } /* sidebar */ .sidebar { height: 100%; left: 0; overflow-y: scroll; padding: calc(var(--margin) / 2) var(--margin); position: fixed; top: 0; width: var(--mleft); } .sidebar * { font-size: var(--fsize); line-height: var(--flheight); list-style: none; padding: 0; } .sidebar ul ul { margin: 0; margin-bottom: var(--margin); } .sidebar ul ul li { font-family: var(--fcode); } /* common */ html { bottom: 0; left: var(--mleft); overflow: auto; position: fixed; top: 92px; } body { background: var(--bg); border: none; color: var(--text); height: 100%; margin: 0; padding: 0 var(--mright) 10px 0; width: 100%; overflow: auto; } h1, h2, h3, h4, h5, h6 { border: none; font-family: var(--ftitle); font-weight: 100; margin: 0; } h1 {font-size: 4rem;} h2 {font-size: 3.5rem;} h3 {font-size: 3rem;} h4 {font-size: 2.5rem;} h5 {font-size: 2rem;} h6 {font-size: 1.5rem;} a { color: var(--link); text-decoration: none; } a:hover { border-bottom: 1px solid #b737; text-decoration: none; } .api-documentation-overview, .api-documentation-overview p { margin: 0; } table { padding: 0; margin: 0; } table tr, table th, table td, table tr:nth-child(2n), .documentation-section { border: none; background: none; padding: 0; padding-right: 10px; } td, p, li { font-family: var(--ftext); font-size: 1.2rem; font-weight: 300; letter-spacing: .02rem; line-height: var(--flheight); } ul { list-style-type: circle; padding-left: 1.5rem; } .highlight pre, pre, code { background: var(--line); color: var(--text); font-family: var(--fcode); padding: 0; white-space: pre-wrap !important; } code:before, code:after { content: ""; } td:nth-child(2) { word-break: break-word; } /* index */ section table th:nth-child(1), .tabcontent table td:nth-child(1) { font-family: var(--fcode); font-size: var(--fsize); font-weight: normal; padding-right: var(--margin); } section table.api-documentation-overview tr:not(:nth-child(1)) td, section table.api-documentation-overview tr:not(:nth-child(1)) th { padding-bottom: calc(var(--margin) / 2); } /* header */ header>h1 { background: var(--line); border-bottom: 1px solid var(--line); color: var(--desc); font-size: 2.5rem; height: 52px; left: var(--mleft); margin: 0; padding: 0 10px; position: fixed; top: 0; width: calc(100% - var(--mleft) - var(--mright)); } /* search */ #search, #search_desc { background-color: transparent; border: none; color: var(--text); font-family: var(--fcode); font-size: 1rem; height: 1rem; left: var(--margin); outline: none; padding: 0; position: fixed; top: 0; width: calc(100% - var(--margin) * 3); } #search_desc { left: calc(100% - var(--margin) * 2); width: var(--margin); } .searchresults { margin: 0 var(--margin); } .searchresults h2 { display: none; } .searchresults h3 { color: var(--text); font-size: var(--fsize); margin-top: var(--margin); } .searchresults h3:first-of-type { margin-top: 0; } .searchresults ul.results { list-style: none; margin: 0; } .searchresults li { font-family: var(--fcode); font-size: var(--fsize); list-style: none; } .searchresults li:last-of-type { margin-bottom: calc(var(--margin) * 2); } /* items title */ h3:nth-of-type(2), section[id] table tr th { display: none; } /* signature */ section[id] table tr:nth-child(1) td code { font-family: var(--fcode); } /* type */ section[id] table tr:nth-child(2) td, .note { font-family: var(--fcode); font-size: var(--fsize); margin: 0; opacity: .5; padding: 0; } /* description */ section[id] table tr:nth-child(3) td>p:nth-child(1) { color: var(--desc); font-family: var(--ftitle); font-weight: 100; letter-spacing: .05em; margin-top: var(--margin); } /* tabbar */ div.tab { background-color: inherit; border: none; } div.tab button { color: var(--link); background-color: inherit; padding: calc(var(--margin) / 2) var(--margin); } div.tab button:hover { background-color: var(--link); color: var(--bg); } div.tab button.tablinks.active { background-color: inherit; color: var(--text); } </style>`.trim(); (() => { if (document.title.match(/^Hammerspoon (.poons )*.ocs$/)) { // index page $('body').append(cssInner + cssIndex); for (let find of [ 'h3', ]) $(find).remove(); $('th:contains("Resource"), td:contains("Resource")').parents('section').addClass('urls'); $('#search_desc').attr('title', 'search descriptions'); } else { // inner pages for (let find of [ 'Parameters:', 'Paramters:', 'Returns:', 'Notes:', ]) $('p:contains(' + find + ')').addClass('note'); $('h3:contains("API Overview")+ul').wrap('<div class="sidebar"></div>'); $('body').append(cssInner + '<div id="hint">⌘</div>'); let toc = document.createElement('iframe'); // add toc menu toc.id = 'toc'; toc.src = $('header>h1>a:first-child').attr('href'); $('body').append(toc); $('#toc').on('load', () => { toc = $('#toc').contents(); toc.find('header').remove(); toc.find('th:contains("Resource")').parents('section').remove(); toc.find('html').append(cssInner + cssToc); toc.find('head').append('<base target="_top">'); toc.find('#search_desc').attr('alt', 'Search descriptions'); }); } // all pages for (let find of [ 'API Overview', 'API Documentation', ]) $('h3:contains(' + find + ')').remove(); $('section:contains("Search descriptions")').contents().filter(function () { return this.nodeType === 3; }).remove(); $('#search').focus(); })();