cinera.c: Search [#7]

Also put the stuff in a new directory called cinera, that contains only
the files needed to get going, with example template files.
This commit is contained in:
Matt Mascarenhas 2017-11-11 00:34:47 +00:00
parent c7d764c0a6
commit 4572817837
12 changed files with 1649 additions and 646 deletions

120
README.md
View File

@ -1,81 +1,125 @@
Fair warning: This is all under development and not yet packaged up for easy
deployment
## hmml_to_html
## cinera
### Download, and prepare the parser
1. `git clone git@gitssh.handmade.network:Annotation-Pushers/Annotation-System.git`
2. `cd Annotation-System/hmmlib`
3. `make`
4. `cp hmml.a hmmlib.h ../hmml_to_html/`
5. `cd ../hmml_to_html/`
4. `cp hmml.a hmmlib.h ../cinera/`
5. `cd ../cinera/`
Note: For each parser update, remember to make and copy it into place
### Build
1. `zsh hmml_to_html.c` (replacing zsh with your shell as appropriate)
1. `zsh cinera.c` (replacing zsh with your shell as appropriate)
### Run
#### Ordinary operation
#### Single Edition operation
./hmml_to_html test.hmml
cinera test.hmml
This simply generates an HTML file (and updates `cinera_topics.css` if needed)
from `test.hmml` and outputs to `out.html`
Note that if the `.hmml` file contains quotes (as `test.hmml` does), it would be
easiest for now just to remove the quote from `test.hmml`. If you want quotes
to work, run:
#### Project Edition operation
mkdir /home/matt/git/GitHub/insofaras/25fc16d58a297a486334
git clone https://gist.github.com/insofaras/25fc16d58a297a486334 /home/matt/git/GitHub/insofaras/25fc16d58a297a486334
cinera -p ProjectID
(Seriously, the path is hardcoded for now)
Setting the ProjectID with the `-p` flag triggers Project Edition. In this
edition `cinera` monitors the Project Input Directory for new, edited and
deleted .hmml files, and generates one table of contents / search page and a
player page each for valid sets of annotations (or removes them, if needed).
Note also that `cinera.css` contains a `body {}` block at the bottom which you
may want to remove / comment out
By default all directories - input and output - are set to the current working
directory. Typical operation will involve setting these flags:
-d Project Input Directory, the directory where the .hmml files reside
-r Root Directory, path shallower than or equal to the CSS, Images and JS
directories
-u Root URL, corresponding to the Root Directory (optional if the Output
Base Directory resides in the Root Directory)
-b Output Base Directory, location of the table of contents / search page
-t Player Template Location
-x Index Template Location
#### Integration
CINERA_MODE=INTEGRATE ./hmml_to_html test.hmml
CINERA_MODE=INTEGRATE cinera test.hmml
This will integrate into `template.html` (currently hardcoded) the player and
related elements generated from `test.hmml` and output to `out.html`
This will integrate into `template_player.html` (configurable with -t) the
player and related elements generated from `test.hmml` and output to
`out_integrated.html`
Feel free to play with `template.html` to your heart's content. If you do
anything invalid, `hmml_to_html` will tell you what's wrong
Feel free to play with `template_player.html` to your heart's content. If you do
anything invalid, `cinera` will tell you what's wrong
#### Templates
Valid tags:
- `<!-- __CINERA_TITLE__ -->` _the day / episode name, intended to be used
inside your own `<title>` element, but may be used wherever and as many times
as you want on your page_
*Index Template*
- `<!-- __CINERA_INCLUDES__ -->` _the necessary `.css` and `.js` files_
- `<!-- __CINERA_INDEX__ -->` _the table of contents, and search functionality_
*Player Template*
- `<!-- __CINERA_INCLUDES__ -->` _the necessary `.css` and `.js` files, and charset setting_
- `<!-- __CINERA_MENUS__ -->` _ _the menu bar that typically appears above the
player in my samples_
- `<!-- __CINERA_MENUS__ -->` _ _the menu bar that typically appears above the player in my samples_
- `<!-- __CINERA_PLAYER__ -->` _the player_
- `<!-- __CINERA_SCRIPT__ -->` _the listeners that enable interaction with the player_
- `<!-- __CINERA_SCRIPT__ -->` _the filter state objects and `.js` file, which must come after both the MENUS and PLAYER tags_
#### Arguments
Usage: ./hmml_to_html [option(s)] filename(s)
Usage: ./cinera [option(s)] filename(s)
Options:
-c <CSS directory path>
Override default CSS directory (".")
-i <images directory path>
Override default images directory (".")
-j <JS directory path>
Override default JS directory (".")
-o <output location>
Override default output location ("out.html")
-q <quotes directory path>
Override default quotes directory ("/home/matt/git/GitHub/insofaras/25fc16d58a297a486334")
-t <template location>
Override default template location ("template.html")
and automatically enable integration
-h
display this help
Paths:
-r <root directory>
Override default root directory (".")
-u <root URL>
Override default root URL ("")
-b <base output directory>
Override project's default base output directory (".")
-c <CSS directory path>
Override default CSS directory (""), relative to root
-i <images directory path>
Override default images directory (""), relative to root
-j <JS directory path>
Override default JS directory (""), relative to root
-t <player template location>
Override default player template location ("template_player.html"), relative to root
and automatically enable integration
-x <index template location>
Override default index template location ("template_index.html"), relative to root
and automatically enable integration
-o <output location>
Override default output player location for SINGLE_EDITION ("out.html")
-d <project directory>
Override default project directory (".")
-f
Force integration with an incomplete template
-p <project ID>
Set the project ID, corresponding to the "project" field in the HMML files
-l <n>
Override default log level (0), where n is from 0 (terse) to 7 (verbose)
-m <default medium>
Override default default medium ("programming")
-U <seconds>
Override default update interval ("4")
-h
display this help
#### Environment Variables
CINERA_MODE=INTEGRATE
Enable integration

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,87 @@
/* Index */
.queryContainer {
width: 1024px;
margin: 15px auto;
display: flex;
flex-direction: horizontal;
}
.queryContainer label {
flex-grow: 0;
flex-shrink: 0;
}
.queryContainer .inputContainer {
flex-grow: 1;
position: relative;
}
#query {
width: 100%;
}
.spinner {
position: absolute;
top: 2px;
right: 5px;
color: black;
height: 100%;
display: none;
}
.spinner.show {
display: block;
}
#results,
#cineraIndex {
width: 800px;
margin: 0 auto;
}
.dayName {
width: 200px;
display: inline-block;
vertical-align: top;
font-size: 12px;
line-height: 16px;
box-sizing: border-box;
padding: 5px;
}
#cineraIndex dt a {
display: block;
padding: 5px;
text-decoration: none;
}
.markerList {
display: inline-block;
width: 600px;
box-sizing: border-box;
vertical-align: top;
}
.markerList > .marker {
padding: 10px 5px;
cursor: pointer;
border-top: 1px solid;
display: block;
text-decoration: none;
}
.markerList > .marker:first-child {
border: none;
}
#resultsSummary {
text-align: center;
margin: 10px 0;
}
/* Player */
/* Structure */
.title,
@ -181,10 +265,14 @@
}
.title > .menu > .credits_container .credit .support {
text-align: right;
padding: 16px;
}
.title > .menu > .credits_container .credit .support .support_icon {
height: 16px;
width: 16px;
}
.title > .menu > .refs .ref:last-child,
.title > .menu > .credits_container .credit:last-child {
border: none;

View File

@ -1,3 +1,37 @@
/* Search */
.dayContainer.hero,
#cineraIndex.hero dt {
background-color: #161616;
}
.dayContainer:nth-child(2n).hero,
#cineraIndex.hero dt:nth-child(2n) {
background-color: #303030;
}
.dayContainer.hero > .dayName,
#cineraIndex.hero dt a {
color: #8A877D;
}
.markerList.hero > .marker
{
border-color: rgba(255, 255, 255, 0.1);
color: #ddd;
}
.markerList.hero > .marker b {
color: black;
background-color: rgb(255, 155, 0);
}
.markerList.hero > .marker:hover {
background-color: #444;
}
/* Player */
.title.hero,
.title.hero .menu .refs,
.title.hero .menu > .refs .ref,

View File

@ -1,3 +1,6 @@
.dayContainer.riscy,
#cineraIndex.riscy dt,
.title.riscy,
.title.riscy > .menu .refs,
.title.riscy > .menu .filter_container,
@ -8,9 +11,31 @@
.markers_container.riscy,
.markers_container.riscy > .marker {
background-color: #EEE;
}
.dayContainer:nth-child(2n).riscy,
#cineraIndex.riscy dt:nth-child(2n) {
background-color: #FFF;
}
.markerList.riscy > .marker,
.title.riscy,
.title.riscy > .menu .refs,
.title.riscy > .menu .filter_container,
.title.riscy > .menu > .refs .ref,
.title.riscy > .menu > .filter_container .filter_mode,
.title.riscy > .menu > .credits_container,
.title.riscy > .menu > .credits_container .credit,
.markers_container.riscy,
.markers_container.riscy > .marker {
border-color: rgba(246, 178, 26, 0.8);
}
.dayContainer.riscy > .dayName,
.markerList.riscy > .marker,
#cineraIndex.riscy dt a,
.title.riscy,
.title.riscy > .menu > .refs .ref,
/*.title.riscy > .menu > .refs .ref .timecode:hover:before,*/
@ -36,23 +61,22 @@
}
.title.riscy > .menu > .refs .ref.current .ref_indices .timecode.focused {
color: rgb(246, 178, 26);
color: rgb(246, 178, 26);
}
.markerList.riscy > .marker:hover,
#cineraIndex.riscy dt:hover,
/*.title.riscy > .menu:hover,*/
.title.riscy > .menu.visible,
/*.title.riscy > .menu > .refs .ref:hover,*/
.title.riscy > .menu > .quotes_container .ref.focused,
.title.riscy > .menu > .references_container .ref.focused,
.title.riscy > .menu > .filter_container .filter_mode:hover,
/*.title.riscy > .menu > .filter_container .filter_content:hover,*/
.title.riscy > .menu > .filter_container .filter_content.focused,
/*.title.riscy > .menu > .credits_container .credit *:hover,*/
.title.riscy > .menu > .credits_container .credit *.focused,
.markers_container.riscy > .marker:hover > .content {
background-color: #FFF8E7;
}
@ -63,15 +87,13 @@ color: rgb(246, 178, 26);
color: #FFF8E7;
}
.markerList.riscy > .marker b,
.title.riscy > .menu > .refs .ref.current,
/*.title.riscy > .menu > .refs .ref.current .timecode:hover:before,*/
.markers_container.riscy > .marker > .progress .content {
color: #FFF;
}
.title.riscy > .menu > .refs .ref.current,
.markers_container.riscy > .marker > .progress .content {
background-color: rgb(42, 49, 114);
color: #FFF;
}
/*.title.riscy > .menu > .refs .ref.current:hover,*/

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,186 @@
var menuState = [];
var titleBar = document.querySelector(".title");
var quotesMenu = titleBar.querySelector(".quotes_container");
if(quotesMenu)
{
menuState.push(quotesMenu);
var quoteTimecodes = quotesMenu.querySelectorAll(".refs .ref .ref_indices .timecode");
for (var i = 0; i < quoteTimecodes.length; ++i) {
quoteTimecodes[i].addEventListener("click", function(ev) {
if (player) {
var time = ev.currentTarget.getAttribute("data-timestamp");
mouseSkipToTimecode(player, time, ev);
}
});
}
var lastFocusedQuote = null;
}
var referencesMenu = titleBar.querySelector(".references_container");
if(referencesMenu)
{
menuState.push(referencesMenu);
var referenceItems = referencesMenu.querySelectorAll(".ref");
if(referenceItems)
{
for(var i = 0; i < referenceItems.length; ++i)
{
referenceItems[i].addEventListener("mouseenter", function(ev) {
mouseOverReferences(this);
})
};
var lastFocusedReference = null;
var lastFocusedIdentifier = null;
}
var refTimecodes = referencesMenu.querySelectorAll(".refs .ref .ref_indices .timecode");
for (var i = 0; i < refTimecodes.length; ++i) {
refTimecodes[i].addEventListener("click", function(ev) {
if (player) {
var time = ev.currentTarget.getAttribute("data-timestamp");
mouseSkipToTimecode(player, time, ev);
}
});
}
}
if(referencesMenu || quotesMenu)
{
var refSources = titleBar.querySelectorAll(".refs .ref"); // This is for both quotes and refs
for (var i = 0; i < refSources.length; ++i) {
refSources[i].addEventListener("click", function(ev) {
if (player) {
player.pause();
}
});
}
}
var filterMenu = titleBar.querySelector(".filter_container");
if(filterMenu)
{
menuState.push(filterMenu);
var lastFocusedCategory = null;
var lastFocusedTopic = null;
var lastFocusedMedium = null;
var filter = filterMenu.parentNode;
var filterModeElement = filter.querySelector(".filter_mode");
filterModeElement.addEventListener("click", function(ev) {
toggleFilterMode();
});
var filterMode = filterModeElement.classList[1];
var filterItems = filter.querySelectorAll(".filter_content");
for(var i = 0; i < filterItems.length; ++i)
{
filterItems[i].addEventListener("mouseenter", function(ev) {
navigateFilter(this);
})
filterItems[i].addEventListener("click", function(ev) {
filterItemToggle(this);
});
}
}
var creditsMenu = titleBar.querySelector(".credits_container");
if(creditsMenu)
{
menuState.push(creditsMenu);
var lastFocusedCreditItem = null;
var creditItems = creditsMenu.querySelectorAll(".person, .support");
for(var i = 0; i < creditItems.length; ++i)
{
creditItems[i].addEventListener("mouseenter", function(ev) {
if(this != lastFocusedCreditItem)
{
lastFocusedCreditItem.classList.remove("focused");
if(lastFocusedCreditItem.classList.contains("support"))
{
setIconLightness(lastFocusedCreditItem.firstChild);
}
lastFocusedCreditItem = this;
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
if(focusedElement.classList.contains("support"))
{
setIconLightness(focusedElement.firstChild);
}
}
})
}
var supportIcons = creditsMenu.querySelectorAll(".support_icon");
{
for(var i = 0; i < supportIcons.length; ++i)
{
setIconLightness(supportIcons[i]);
}
}
}
var sourceMenus = titleBar.querySelectorAll(".menu");
var helpButton = titleBar.querySelector(".help");
var helpDocumentation = helpButton.querySelector(".help_container");
helpButton.addEventListener("click", function(ev) {
handleMouseOverMenu(this, ev.type);
})
var focusedElement = null;
var focusedIdentifier = null;
var playerContainer = document.querySelector(".player_container")
var player = new Player(playerContainer, onRefChanged);
window.addEventListener("resize", function() { player.updateSize(); });
document.addEventListener("keydown", function(ev) {
var key = ev.key;
if(ev.getModifierState("Shift") && key == " ")
{
key = "capitalSpace";
}
if(handleKey(key) == true && focusedElement)
{
ev.preventDefault();
}
});
for(var i = 0; i < sourceMenus.length; ++i)
{
sourceMenus[i].addEventListener("mouseenter", function(ev) {
handleMouseOverMenu(this, ev.type);
})
sourceMenus[i].addEventListener("mouseleave", function(ev) {
handleMouseOverMenu(this, ev.type);
})
};
var testMarkers = playerContainer.querySelectorAll(".marker");
window.addEventListener("blur", function(){
document.getElementById("focus-warn").style.display = "block";
});
window.addEventListener("focus", function(){
document.getElementById("focus-warn").style.display = "none";
});
var colouredItems = playerContainer.querySelectorAll(".author, .member, .project");
for(i = 0; i < colouredItems.length; ++i)
{
setTextLightness(colouredItems[i]);
}
var topicDots = document.querySelectorAll(".category");
for(var i = 0; i < topicDots.length; ++i)
{
setDotLightness(topicDots[i]);
}
if(location.hash) {
player.setTime(location.hash.startsWith('#') ? location.hash.substr(1) : location.hash);
}

View File

@ -392,14 +392,22 @@ function toggleMenuVisibility(element) {
if(element.querySelectorAll(".credit .support")[0])
{
lastFocusedCreditItem = element.querySelectorAll(".credit .support")[0];
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
else
{
lastFocusedCreditItem = element.querySelectorAll(".credit .person")[0];
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
}
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
else
{
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
}
}
}
@ -532,15 +540,18 @@ function handleKey(key) {
if(focusedElement.parentNode.previousElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support"))
{
setIconLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
else
{
lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".person");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
focusedElement.classList.add("focused");
}
}
}
@ -596,15 +607,18 @@ function handleKey(key) {
if(focusedElement.parentNode.nextElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support"))
{
setIconLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
else
{
lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".person");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
focusedElement.classList.add("focused");
}
}
}
@ -618,11 +632,17 @@ function handleKey(key) {
if(focusedIdentifier.previousElementSibling)
{
focusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = focusedIdentifier.previousElementSibling;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
else if(focusedIdentifier.parentNode.previousElementSibling.classList.contains("ref_indices"))
{
focusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = focusedIdentifier.parentNode.previousElementSibling.lastElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
}
else if(focusedElement.classList.contains("filter_content"))
{
@ -648,6 +668,7 @@ function handleKey(key) {
focusedElement.classList.remove("focused");
lastFocusedCreditItem = focusedElement.previousElementSibling;
setIconLightness(focusedElement.firstChild);
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
@ -668,6 +689,13 @@ function handleKey(key) {
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
else if(focusedIdentifier.parentNode.nextElementSibling)
{
focusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = focusedIdentifier.parentNode.nextElementSibling.firstElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
}
else if(focusedElement.classList.contains("filter_content"))
{
@ -696,6 +724,7 @@ function handleKey(key) {
lastFocusedCreditItem = focusedElement.nextElementSibling;
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
}
}
@ -951,11 +980,16 @@ function filterItemToggle(filterItem) {
function resetFilter() {
for(i in filterItems)
{
if(filterItems[i].classList && filterItems[i].classList.contains("off"))
if(filterItems[i].classList)
{
filterItemToggle(filterItems[i]);
var selectedCategory = filterItems[i].classList[1];
if(filterInitState[selectedCategory].off ^ filterState[selectedCategory].off)
{
filterItemToggle(filterItems[i]);
}
}
}
if(filterMode == "exclusive")
{
toggleFilterMode();
@ -1082,7 +1116,7 @@ function mouseOverReferences(reference) {
focusedElement = lastFocusedReference;
focusedElement.classList.add("focused");
var ourIdentifiers = reference.querySelector(".ref_indices").children;
var ourIdentifiers = reference.querySelectorAll(".timecode");
weWereLastFocused = false;
for(var k = 0; k < ourIdentifiers.length; ++k)
{
@ -1094,7 +1128,7 @@ function mouseOverReferences(reference) {
if(!weWereLastFocused)
{
lastFocusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = reference.querySelector(".ref_indices").firstElementChild;
lastFocusedIdentifier = ourIdentifiers[0];
}
focusedIdentifer = lastFocusedIdentifier;
focusedIdentifer.classList.add("focused");
@ -1219,7 +1253,19 @@ function setDotLightness(topicDot)
}
else
{
topicDot.style.backgroundColor = ("hsl(" + Hue + ", " + Saturation + "%, 24%)");
topicDot.style.borderColor = ("hsl(" + Hue + ", " + Saturation + "%, 24%)");
topicDot.style.backgroundColor = ("hsl(" + Hue + ", " + Saturation + "%, 47%)");
topicDot.style.borderColor = ("hsl(" + Hue + ", " + Saturation + "%, 47%)");
}
}
function setIconLightness(iconElement)
{
if(getBackgroundBrightness(iconElement) < 127)
{
iconElement.style.backgroundPosition = ("0px 0px");
}
else
{
iconElement.style.backgroundPosition = ("16px 0px");
}
}

240
cinera/cinera_search.js Normal file
View File

@ -0,0 +1,240 @@
if (location.hash && location.hash.length > 0) {
var initialQuery = location.hash;
if (initialQuery[0] == "#") {
initialQuery = initialQuery.slice(1);
}
document.getElementById("query").value = decodeURIComponent(initialQuery);
}
var indexContainer = document.getElementById("cineraIndex");
var lastQuery = null;
var resultsToRender = [];
var resultsIndex = 0;
var resultsMarkerIndex = 0;
var resultsContainer = document.getElementById("results");
var rendering = false;
var dayContainerPrototype = document.createElement("DIV");
dayContainerPrototype.classList.add("dayContainer");
dayContainerPrototype.classList.add(projectID);
var dayNamePrototype = document.createElement("SPAN");
dayNamePrototype.classList.add("dayName");
dayContainerPrototype.appendChild(dayNamePrototype);
var markerListPrototype = document.createElement("DIV");
markerListPrototype.classList.add("markerList");
markerListPrototype.classList.add(projectID);
dayContainerPrototype.appendChild(markerListPrototype);
var markerPrototype = document.createElement("A");
markerPrototype.classList.add("marker");
markerPrototype.setAttribute("target", "_blank");
var highlightPrototype = document.createElement("B");
var episodes = [];
function getEpisodeName(filename) {
var day = filename;
var dayParts = day.match(/([a-zA-Z_-]+)([0-9]+)?([a-zA-Z]+)?/);
day = dayParts[1].slice(0, 1).toUpperCase() + dayParts[1].slice(1) + (dayParts[2] ? " " + dayParts[2] : "") + (dayParts[3] ? " " + dayParts[3].toUpperCase() : "");
return day;
}
function markerTime(totalTime) {
var markTime = "(";
var hours = Math.floor(totalTime / 60 / 60);
var minutes = Math.floor(totalTime / 60) % 60;
var seconds = totalTime % 60;
if (hours > 0) {
markTime += padTimeComponent(hours) + ":";
}
markTime += padTimeComponent(minutes) + ":" + padTimeComponent(seconds) + ")";
return markTime;
}
function padTimeComponent(component) {
return (component < 10 ? "0" + component : component);
}
function runSearch() {
var queryStr = document.getElementById("query").value;
if (lastQuery != queryStr) {
var oldResultsContainer = resultsContainer;
resultsContainer = oldResultsContainer.cloneNode(false);
oldResultsContainer.parentNode.insertBefore(resultsContainer, oldResultsContainer);
oldResultsContainer.remove();
resultsIndex = 0;
resultsMarkerIndex = 0;
}
lastQuery = queryStr;
resultsToRender = [];
var numEpisodes = 0;
var numMarkers = 0;
var totalSeconds = 0;
if (queryStr && queryStr.length > 0) {
indexContainer.style.display = "none";
if (episodes.length > 0) {
var query = new RegExp(queryStr.replace("(", "\\(").replace(")", "\\)").replace(/(^|[^\\])\\$/, "$1"), "gi");
for (var i = 0; i < episodes.length; ++i) {
var episode = episodes[i];
var matches = [];
for (var j = 0; j < episode.markers.length; ++j) {
query.lastIndex = 0;
var result = query.exec(episode.markers[j].text);
if (result && result[0].length > 0) {
numMarkers++;
matches.push(episode.markers[j]);
if (j < episode.markers.length-1) {
totalSeconds += episode.markers[j+1].totalTime - episode.markers[j].totalTime;
}
}
}
if (matches.length > 0) {
numEpisodes++;
resultsToRender.push({
query: query,
episode: episode,
matches: matches
});
}
}
if (!rendering) {
renderResults();
}
} else {
document.querySelector(".spinner").classList.add("show");
}
}
else
{
indexContainer.style.display = "block";
}
var totalTime = Math.floor(totalSeconds/60/60) + "h " + Math.floor(totalSeconds/60)%60 + "m " + totalSeconds%60 + "s ";
document.getElementById("resultsSummary").textContent = "Found: " + numEpisodes + " episodes, " + numMarkers + " markers, " + totalTime + "total.";
}
function renderMatches(renderStart) {
var query = resultsToRender[resultsIndex].query;
var episode = resultsToRender[resultsIndex].episode;
var matches = resultsToRender[resultsIndex].matches;
var markerList = null;
if (resultsMarkerIndex == 0) {
var dayContainer = dayContainerPrototype.cloneNode(true);
var dayName = dayContainer.children[0];
markerList = dayContainer.children[1];
dayName.textContent = episode.day + ": " + episode.title;
resultsContainer.appendChild(dayContainer);
} else {
markerList = document.querySelector("#results > .dayContainer:nth-child(" + (resultsIndex+1) + ") .markerList");
}
do {
var match = matches[resultsMarkerIndex];
var marker = markerPrototype.cloneNode();
marker.setAttribute("href", episode.filename.replace(/"/g, "") + "/#" + match.totalTime);
query.lastIndex = 0;
var cursor = 0;
var text = match.text;
var result = null;
marker.appendChild(document.createTextNode(match.prettyTime + " "));
while (result = query.exec(text)) {
if (result.index > cursor) {
marker.appendChild(document.createTextNode(text.slice(cursor, result.index)));
}
var highlightEl = highlightPrototype.cloneNode();
highlightEl.textContent = result[0];
marker.appendChild(highlightEl);
cursor = result.index + result[0].length;
}
if (cursor < text.length) {
marker.appendChild(document.createTextNode(text.slice(cursor, text.length)));
}
markerList.appendChild(marker);
resultsMarkerIndex++;
} while (resultsMarkerIndex < matches.length && performance.now() - renderStart < 1);
return resultsMarkerIndex == matches.length;
}
function renderResults() {
if (resultsIndex < resultsToRender.length) {
rendering = true;
var renderStart = performance.now();
while (resultsIndex < resultsToRender.length && performance.now() - renderStart < 1) {
var done = renderMatches(renderStart);
if (done) {
resultsMarkerIndex = 0;
resultsIndex++;
}
}
requestAnimationFrame(renderResults);
} else {
rendering = false;
}
}
var queryEl = document.getElementById("query")
queryEl.addEventListener("input", function(ev) {
history.replaceState(null, null, "#" + encodeURIComponent(queryEl.value));
runSearch();
});
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function() {
var contents = xhr.response;
var lines = contents.split("\n");
var mode = "none";
var episode = null;
for (var i = 0; i < lines.length; ++i) {
var line = lines[i];
if (line.trim().length == 0) { continue; }
if (line == "---") {
if (episode != null) {
episode.filename = episode.name;
episode.day = getEpisodeName(episode.filename + ".html.md");
episodes.push(episode);
}
episode = {};
mode = "none";
} else if (line.startsWith("name:")) {
episode.name = line.slice(6);
} else if (line.startsWith("title:")) {
episode.title = line.slice(7).replace(/"/g, "");
} else if (line.startsWith("markers")) {
mode = "markers";
episode.markers = [];
} else if (mode == "markers") {
var match = line.match(/"(\d+)": "(.+)"/);
if (match == null) {
console.log(name, line);
} else {
var totalTime = parseInt(line.slice(1));
var marker = {
totalTime: totalTime,
prettyTime: markerTime(totalTime),
text: match[2].replace(/\\"/g, "\"")
}
episode.markers.push(marker);
}
}
}
document.querySelector(".spinner").classList.remove("show");
runSearch();
});
xhr.addEventListener("error", function() {
console.error("Failed to load content");
});
xhr.open("GET", indexLocation);
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.send();
runSearch();

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

View File

@ -0,0 +1,12 @@
<!-- Index template -->
<html>
<head>
<title>RISCY BUSINESS Episode Guide</title>
<!-- __CINERA_INCLUDES__ -->
</head>
<body>
<h1 style="background-color: #3399FF; text-align:center; width: 100%; margin: 0 auto">RISCY BUSINESS Episode Guide</h1>
<div>This should just be the table of contents, heroes and heroines</div>
<!-- __CINERA_INDEX__ -->
</body>
</html>

View File

@ -0,0 +1,17 @@
<!-- Player template -->
<html>
<head>
<title><!-- __CINERA_TITLE__ --> - RISCY BUSINESS</title>
<!-- __CINERA_INCLUDES__ -->
</head>
<!-- 1. This is a random comment. How does this affect it, if at all? -->
<body>
<a href="../">Awesome Contents</a>
<h1 style="background-color: #3399FF; text-align:center; width: 100%; margin: 0 auto"><!-- __CINERA_TITLE__ --></h1>
<!-- __CINERA_MENUS__ -->
<!-- __CINERA_PLAYER__ -->
<!-- 2. This is a random comment. How does this affect it, if at all? -->
<!-- __CINERA_SCRIPT__ -->
<!-- 3. This is a random comment. How does this affect it, if at all? -->
</body>
</html>