blob: 2eb8344e1ca84ef6c8e0e9f59b51e4f61f16fdc0 (
plain) (
tree)
|
|
// Haddock JavaScript utilities
import {getCookie, setCookie, clearCookie} from "./cookies";
import preact = require("preact");
const { h, Component } = preact;
// 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);
}
// Set a style (including setting the cookie)
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");
}
}
// Reset the style based on the cookie
function resetStyle() {
const s = getCookie("haddock-style");
if (s) setActiveStyleSheet(s);
}
class StylesButton extends Component<any, any> {
render(props: { title: string, onClick: () => void }) {
function onClick(e: Event) {
e.preventDefault();
props.onClick();
}
return <li><a href="#" onClick={onClick}>{props.title}</a></li>;
}
}
// 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(<StylesButton onClick={action} title="Styles"/>, pageMenu, dummy);
}
}
type StyleProps = {
styles: string[]
showHideTrigger: (action: () => void) => void
}
type StyleState = {
isVisible: boolean
}
// Represents the full style dropdown
class Styles extends Component<StyleProps, StyleState> {
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 <div id="style" class={state.isVisible ? '' : 'hidden'}>
<div id="style-menu" class="dropdown-menu" onMouseDown={stopPropagation}>
{
props.styles.map((sty) =>
<button type="button"
onClick={(e) => { this.hide(); setActiveStyleSheet(sty) }}>
{sty}
</button>
)
}
</div>
</div>;
}
}
export function init(showHide?: (action: () => void) => void) {
const stys = styles().map((s) => s.title);
const addStylesButton = (action: () => void) => addStyleMenu(stys, action)
resetStyle();
preact.render(
<Styles showHideTrigger={showHide || addStylesButton} styles={stys} />,
document.body
);
}
|