2016-01-29 01:27:15 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to
|
|
|
|
* deal in the Software without restriction, including without limitation the
|
|
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
* IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2016-08-07 19:01:56 +03:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
* Imports
|
|
|
|
* ------------------------------------------------------------------------- */
|
2016-01-29 01:27:15 +03:00
|
|
|
|
2016-09-30 14:29:45 +03:00
|
|
|
import FastClick from "fastclick"
|
|
|
|
|
|
|
|
// import Expander from "./components/expander"
|
2016-10-06 13:14:33 +03:00
|
|
|
|
2016-10-23 12:35:41 +03:00
|
|
|
import GithubSourceFacts from "./components/GithubSourceFacts"
|
2016-10-06 13:14:33 +03:00
|
|
|
import Material from "./components/Material"
|
2016-09-30 14:29:45 +03:00
|
|
|
|
|
|
|
// import Search from './components/search';
|
2016-01-29 01:27:15 +03:00
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------------
|
2016-08-07 19:01:56 +03:00
|
|
|
* Application
|
2016-01-29 01:27:15 +03:00
|
|
|
* ------------------------------------------------------------------------- */
|
|
|
|
|
2016-10-06 13:14:33 +03:00
|
|
|
class Application {
|
|
|
|
|
2016-10-23 12:35:41 +03:00
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @param {object} config Configuration object
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
constructor(config) {
|
2016-11-02 21:21:14 +03:00
|
|
|
this.config_ = config
|
2016-10-23 12:35:41 +03:00
|
|
|
}
|
|
|
|
|
2016-10-06 13:14:33 +03:00
|
|
|
/**
|
2016-11-02 21:21:14 +03:00
|
|
|
* Initialize all components
|
2016-10-06 13:14:33 +03:00
|
|
|
*/
|
|
|
|
initialize() {
|
2016-10-23 12:35:41 +03:00
|
|
|
|
2016-11-02 21:21:14 +03:00
|
|
|
/* Initialize sticky sidebars */
|
|
|
|
this.initializeSidebar("[data-md-sidebar=primary]", "(min-width: 1200px)")
|
|
|
|
this.initializeSidebar("[data-md-sidebar=secondary]")
|
|
|
|
|
|
|
|
/* Initialize navigation style modifiers */
|
|
|
|
this.initializeNavBlur("[data-md-sidebar=secondary] .md-nav__link")
|
|
|
|
this.initializeNavCollapse("[data-md-collapse]", "(min-width: 1200px)")
|
|
|
|
|
|
|
|
// TODO
|
2016-10-23 12:35:41 +03:00
|
|
|
if (this.hasGithubRepo()) {
|
|
|
|
const githubSource = new GithubSourceFacts(
|
2016-11-02 21:21:14 +03:00
|
|
|
this.config_.storage,
|
|
|
|
this.config_.repo.url
|
2016-10-23 12:35:41 +03:00
|
|
|
)
|
|
|
|
githubSource.initialize()
|
|
|
|
}
|
2016-11-02 21:21:14 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize sidebar within optional media query range
|
|
|
|
*
|
|
|
|
* @param {(string|HTMLElement)} el - Selector or HTML element
|
|
|
|
* @param {string} [query] - Media query
|
|
|
|
*/
|
|
|
|
initializeSidebar(el, query = null) {
|
|
|
|
const sidebar = new Material.Sidebar(el)
|
|
|
|
const listeners = [
|
|
|
|
new Material.Listener.Viewport.Offset(() => sidebar.update()),
|
|
|
|
new Material.Listener.Viewport.Resize(() => sidebar.update())
|
|
|
|
]
|
|
|
|
|
|
|
|
/* Initialize depending on media query */
|
|
|
|
if (typeof query === "string" && query.length) {
|
|
|
|
new Material.Listener.Viewport.Media(query, media => {
|
|
|
|
if (media.matches) {
|
|
|
|
sidebar.update()
|
|
|
|
for (const listener of listeners)
|
|
|
|
listener.listen()
|
|
|
|
} else {
|
|
|
|
sidebar.reset()
|
|
|
|
for (const listener of listeners)
|
|
|
|
listener.unlisten()
|
|
|
|
}
|
|
|
|
}).listen()
|
|
|
|
|
|
|
|
/* Initialize without media query */
|
|
|
|
} else {
|
|
|
|
sidebar.update()
|
|
|
|
for (const listener of listeners)
|
|
|
|
listener.listen()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize blurring of anchors above page y-offset
|
|
|
|
*
|
|
|
|
* @param {(string|NodeList<HTMLElement>)} els - Selector or HTML elements
|
|
|
|
*/
|
|
|
|
initializeNavBlur(els) {
|
|
|
|
const blur = new Material.Nav.Blur(els)
|
|
|
|
const listeners = [
|
|
|
|
new Material.Listener.Viewport.Offset(() => blur.update())
|
|
|
|
]
|
|
|
|
|
|
|
|
/* Initialize blur and listeners */
|
|
|
|
blur.update()
|
|
|
|
for (const listener of listeners)
|
|
|
|
listener.listen()
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize collapsible nested navigation elements
|
|
|
|
*
|
|
|
|
* @param {(string|NodeList<HTMLElement>)} els - Selector or HTML elements
|
|
|
|
* @param {string} [query] - Media query
|
|
|
|
*/
|
|
|
|
initializeNavCollapse(els, query = null) {
|
|
|
|
const collapsibles = document.querySelectorAll(els)
|
|
|
|
for (const collapsible of collapsibles) {
|
|
|
|
const collapse = new Material.Nav.Collapse(collapsible)
|
|
|
|
const listener = new Material.Listener.Toggle(
|
|
|
|
collapsible.previousElementSibling, () => collapse.update())
|
|
|
|
|
|
|
|
/* Initialize depending on media query */
|
|
|
|
new Material.Listener.Viewport.Media(query, media => {
|
|
|
|
if (media.matches) {
|
|
|
|
listener.listen()
|
|
|
|
} else {
|
|
|
|
collapse.reset()
|
|
|
|
listener.unlisten()
|
|
|
|
}
|
|
|
|
}).listen()
|
|
|
|
}
|
2016-10-23 12:35:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is this application about a Github repository?
|
|
|
|
*
|
|
|
|
* @return {bool} - true if `repo.icon` or `repo.url` contains 'github'
|
|
|
|
*/
|
|
|
|
hasGithubRepo() {
|
2016-11-02 21:21:14 +03:00
|
|
|
return this.config_.repo.icon === "github"
|
|
|
|
|| this.config_.repo.url.includes("github")
|
2016-10-06 13:14:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Application
|
|
|
|
|
2016-11-02 21:21:14 +03:00
|
|
|
// const consume = reader => {
|
|
|
|
// let total = 0, body = ""
|
|
|
|
// return new Promise((resolve, reject) => {
|
|
|
|
// function pump() {
|
|
|
|
// reader.read().then(({ done, value }) => {
|
|
|
|
// if (done) {
|
|
|
|
// console.log(body)
|
|
|
|
// resolve()
|
|
|
|
// return
|
|
|
|
// }
|
|
|
|
// total += value.byteLength
|
|
|
|
// // value +=
|
|
|
|
// body += value
|
|
|
|
// console.log(`received ${value.byteLength}, total: ${total}`)
|
|
|
|
// pump()
|
|
|
|
// })
|
|
|
|
// .catch(reject)
|
|
|
|
// }
|
|
|
|
// pump()
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// fetch("/mkdocs/search_index.json")
|
|
|
|
// .then(res => consume(res.body.getReader()))
|
|
|
|
// .then(() => console.log("consumed entire body"))
|
|
|
|
// .catch(e => console.log(e))
|
|
|
|
|
2016-10-06 13:14:33 +03:00
|
|
|
// TODO: wrap in function call
|
|
|
|
// application module export
|
|
|
|
|
2016-01-29 01:27:15 +03:00
|
|
|
/* Initialize application upon DOM ready */
|
2016-09-30 14:29:45 +03:00
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
2016-01-29 01:27:15 +03:00
|
|
|
|
|
|
|
/* Test for iOS */
|
2016-09-30 14:29:45 +03:00
|
|
|
Modernizr.addTest("ios", () => {
|
|
|
|
return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)
|
|
|
|
})
|
2016-01-29 01:27:15 +03:00
|
|
|
|
|
|
|
/* Test for web application context */
|
2016-09-30 14:29:45 +03:00
|
|
|
Modernizr.addTest("standalone", () => {
|
|
|
|
return !!navigator.standalone
|
|
|
|
})
|
2016-01-29 01:27:15 +03:00
|
|
|
|
|
|
|
/* Attack FastClick to mitigate 300ms delay on touch devices */
|
2016-09-30 14:29:45 +03:00
|
|
|
FastClick.attach(document.body)
|
2016-01-29 01:27:15 +03:00
|
|
|
|
2016-10-23 20:31:54 +03:00
|
|
|
// query.addEventListener("focus", () => {
|
|
|
|
// document.querySelector(".md-search").dataset.mdLocked = ""
|
|
|
|
// })
|
2016-09-02 01:33:45 +03:00
|
|
|
|
|
|
|
/* Intercept click on search mode toggle */
|
|
|
|
|
2016-11-02 21:21:14 +03:00
|
|
|
// TODO: this needs to be abstracted...
|
2016-10-23 20:31:54 +03:00
|
|
|
document.getElementById("query").addEventListener("focus", () => {
|
|
|
|
document.getElementById("search").checked = true
|
|
|
|
})
|
|
|
|
|
|
|
|
// should be registered on body, but leads to problems
|
|
|
|
document.querySelector(".md-container").addEventListener("click", () => {
|
|
|
|
if (document.getElementById("search").checked)
|
|
|
|
document.getElementById("search").checked = false
|
|
|
|
})
|
|
|
|
|
|
|
|
// stop propagation, if search is active...
|
|
|
|
document.querySelector(".md-search").addEventListener("click", ev => {
|
|
|
|
ev.stopPropagation()
|
|
|
|
})
|
2016-10-23 11:21:37 +03:00
|
|
|
// toggleSearchClose.addEventListener("click", ev => {
|
|
|
|
// ev.preventDefault()
|
|
|
|
// // ev.target
|
|
|
|
//
|
|
|
|
// const search = document.getElementById("search")
|
|
|
|
// search.checked = false
|
|
|
|
// })
|
|
|
|
|
2016-09-23 12:56:25 +03:00
|
|
|
// }, 1000);
|
2016-09-02 01:33:45 +03:00
|
|
|
|
2016-10-23 11:21:37 +03:00
|
|
|
fetch(
|
|
|
|
"https://api.github.com/repos/squidfunk/mkdocs-material/releases/latest")
|
|
|
|
.then(response => {
|
|
|
|
return response.json()
|
|
|
|
})
|
|
|
|
// .then(data => {
|
|
|
|
// // console.log(data)
|
|
|
|
// })
|
|
|
|
|
2016-09-30 14:29:45 +03:00
|
|
|
})
|