import * as types from '../../types'; import * as React from 'react'; import * as txt from './txt'; import * as gls from './gls'; import { style, classes } from 'typestyle'; import * as csstips from 'csstips'; import { colors } from '../../internal/styles'; import { TypedEvent } from "../../internal/utils"; export const IframeC2PResize = new TypedEvent(); namespace TocStyles { export const tocAnchorClass = style( csstips.padding(5, 5, 5, 10), { color: colors.text, textDecoration: 'none', $nest: { '&:hover': { color: colors.text, background: '#ddd', } } } ); export const marginLeft = (level: 1 | 2 | 3 | 4 | 5 | 6) => { return { marginLeft: (level * 10) + 'px' }; } export const currentPage = style({ fontWeight: 'bold', }) } const renderTocPageSub = (t: types.TableOfContentPageSub, isCurrent: boolean) => ( { return (isCurrent) ? "#" + t.id : '../' + t.pageSubDirName + '/#' + t.id; })()} onClick={() => { if (t.iframeId) { navToChildInIframe(t.iframeId, t.id); } }}> {t.text} ); const renderTocPageRoot = (t: types.TableOfContentPageRoot, isCurrent: boolean) => ( { return (isCurrent) ? "#" + t.pageSubDirName : '../' + t.pageSubDirName + '/#' + t.pageSubDirName; })()}> {t.heading} ); export const Toc = ({ toc, pageSubDirName }: { toc: types.TableOfContentEntry[], pageSubDirName: string, }) => Table of Contents { toc.map((t) => { const isCurrent = t.pageSubDirName === pageSubDirName; return t.type == 'pageSub' ? renderTocPageSub(t, isCurrent) : renderTocPageRoot(t, isCurrent) }) } ; /** * Scroll handling for iframes * http://stackoverflow.com/a/19503982/390330 */ window.addEventListener('message', (e) => { const data: types.IframeC2PMessage = e.data; if (data.type === 'IframeC2PScrollMore') { window.scrollTo(0, window.scrollY + data.more); } else if (data.type === 'IframeC2PSetHash') { window.location.hash = data.hash; } else if (data.type === 'IframeC2PResize') { IframeC2PResize.emit(data); } else { const _ensure: never = data; } }); /** Utility: nav to child item in some iframe */ function navToChildInIframe(iframeId: string, childId: string) { const child = document.getElementById(iframeId) as HTMLIFrameElement; if (child) { /** Scroll to iframe */ window.scrollTo(0, child.offsetTop) /** Also request sub item scroll */ const p2cScroll: types.IframeP2CGetScrollMore = { type: 'IframeP2CGetScrollMore', id: childId }; child.contentWindow.postMessage(p2cScroll, '*'); } } /** Also nav to any child iframe on initial load */ setTimeout(() => { const hash = window.location.hash; if (hash.startsWith('#' + types.iframeIdBeginsWith)) { const [iframeId, ...others] = hash.substr(1).split('-'); const childId = iframeId + '-' + others.join('-'); navToChildInIframe(iframeId, childId); } }, 500);