cinera.c: Config

Database version 5

Major features:
    Config file parsing
    Multiple projects per instance
    Searching across multiple projects
    Art sprites, usable by project, medium and support

Minor features:
    The search results are now sortable
    Optimised the search page sorting

Fixes:
    More reliable file system monitoring
    Well-formed templates are now valid, even with the absence of assets
    Correctly resove ~ in paths
    Gracefully handle the lack of an internet connection
    Renamed "annotator" to "indexer"
    Removed PlayerURLPrefix, in favour of .hmml "output" parameter

Replaced the flags collection with:
    -0 Dry-run mode
    -c Set the config file path
    -e Examine the database
    -v Print version
    -h Print help

New template tags:
    __CINERA_NAV__ dropdown
    __CINERA_NAV__ horizontal
    __CINERA_NAV__ plain
    __CINERA_PROJECT_PLAIN__

Deleted template tags:
    __CINERA_MENUS__
    __CINERA_SCRIPT__
This commit is contained in:
Matt Mascarenhas 2020-05-09 18:33:25 +01:00
parent 9051caa94e
commit 05518781c4
11 changed files with 24489 additions and 5074 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,131 @@
/* Generic Navigation */
/* Generic Navigation end */
/* Structure */
/* Horizontal */
ul.cineraNavHorizontal,
ul.cineraNavHorizontal ul {
display: flex;
flex-grow: 1;
flex-flow: row wrap;
border: 0;
margin: 0;
padding: 0;
}
ul.cineraNavHorizontal li {
display: flex;
flex-direction: column;
flex-grow: 1;
}
ul.cineraNavHorizontal {
border-right: 1px solid;
}
ul.cineraNavHorizontal a {
flex-grow: 1;
padding: 8px;
display: flex;
justify-content: center;
align-items: center;
border-left: 1px solid;
border-bottom: 1px solid;
}
/* Horizontal end */
/* Dropdown */
nav.cineraNavDropdown {
display: flex;
flex-direction: column;
}
nav.cineraNavDropdown .cineraNavTitle {
text-align: center;
padding: 8px 0;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
}
.cineraPositioner {
position: relative;
}
nav.cineraNavDropdown ul.cineraNavHorizontal {
display: none;
width: 100%;
z-index: 8;
position: absolute;
}
nav.cineraNavDropdown ul.cineraNavHorizontal.visible {
display: flex;
}
/* Dropdown end */
/* Structure end */
/* Typography */
ul.cineraNavHorizontal a,
ul.cineraNavPlain a {
text-decoration: none;
}
/* Plain */
ul.cineraNavPlain li.current > a {
font-weight: bold;
}
/* Plain end */
/* Typography end */
/* Index */ /* Index */
#cineraIndexControl { #cineraIndexControl {
display: flex; display: flex;
margin: 16px auto; margin: 16px auto;
max-width: 1024px; max-width: 1024px;
align-items: center;
padding: 8px; padding: 8px;
} }
.cineraFilterProject .cineraText,
.cineraProjectTitle
{
display: flex;
}
.cineraIndexFilter {
padding: 10px;
}
.cineraIndexFilter .filter_container
{
display: none;
position: absolute;
z-index: 64;
}
.cineraFilterProject,
.cineraIndexProject > .cineraIndexProject {
padding-left: 1em;
}
.cineraIndexProject {
margin-top: 4px;
}
.cineraIndexProject .cineraProjectTitle,
.cineraFilterProject
{
font-weight: bold;
font-size: 12px;
}
.cineraQueryContainer { .cineraQueryContainer {
flex-grow: 1; flex-grow: 1;
padding-left: 16px; padding-left: 16px;
@ -43,22 +162,30 @@
display: block; display: block;
} }
#cineraResults, #cineraResults,
#cineraIndex { #cineraIndex {
margin: 0 auto; margin: 0 auto;
max-width: 800px; max-width: 800px;
} }
#cineraResults .projectContainer {
display: flex;
flex-flow: column;
}
#cineraIndexControl #cineraIndexSort { #cineraIndexControl #cineraIndexSort {
padding: 4px; padding: 4px;
}
#cineraIndexControl #cineraIndexSort,
#cineraIndexControl .cineraIndexFilter .filter_container {
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
-moz-user-select: none; -moz-user-select: none;
-webkit-user-select: none; -webkit-user-select: none;
} }
#cineraIndex #cineraIndexEntries { #cineraIndex .cineraIndexEntries {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
width: 100%; width: 100%;
@ -79,13 +206,13 @@
width: 200px; width: 200px;
} }
#cineraIndexEntries div a { .cineraIndexEntries div a {
display: block; display: block;
padding: 5px; padding: 5px;
text-decoration: none; text-decoration: none;
} }
#cineraIndexEntries div a::before { .cineraIndexEntries div a::before {
content: "\2713"; content: "\2713";
margin: 0 4px; margin: 0 4px;
} }
@ -141,14 +268,14 @@
max-width: 100%; max-width: 100%;
} }
#cineraIndexEntries div a { .cineraIndexEntries div a {
font-size: 80%; font-size: 80%;
} }
} }
/* Player */ /* Player */
/* Structure */ /* Player / Structure */
.cineraMenus, .cineraMenus,
.cineraMenus > .menu > .refs .ref, .cineraMenus > .menu > .refs .ref,
@ -282,6 +409,12 @@
display: block; display: block;
} }
#cineraIndexControl .cineraIndexFilter .filter_container
{
border: 1px solid;
border-top: none;
}
.cineraMenus > .menu .quotes_container, .cineraMenus > .menu .quotes_container,
.cineraMenus > .menu .references_container, .cineraMenus > .menu .references_container,
.cineraMenus > .menu .filter_container, .cineraMenus > .menu .filter_container,
@ -343,11 +476,6 @@
padding: 16px; padding: 16px;
} }
.cineraMenus > .menu > .credits_container .credit .support .support_icon {
height: 16px;
width: 16px;
}
.cineraMenus > .menu > .refs .ref:last-child, .cineraMenus > .menu > .refs .ref:last-child,
.cineraMenus > .menu > .credits_container .credit:last-child { .cineraMenus > .menu > .credits_container .credit:last-child {
border: none; border: none;

4682
cinera/cinera_config.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -211,31 +211,24 @@ if(creditsMenu)
if(this != lastFocusedCreditItem) if(this != lastFocusedCreditItem)
{ {
lastFocusedCreditItem.classList.remove("focused"); lastFocusedCreditItem.classList.remove("focused");
unfocusSprite(lastFocusedCreditItem);
if(lastFocusedCreditItem.classList.contains("support")) if(lastFocusedCreditItem.classList.contains("support"))
{ {
setIconLightness(lastFocusedCreditItem.firstChild); setSpriteLightness(lastFocusedCreditItem.firstChild);
} }
lastFocusedCreditItem = this; lastFocusedCreditItem = this;
focusedElement = lastFocusedCreditItem; focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused"); focusedElement.classList.add("focused");
focusSprite(focusedElement);
if(focusedElement.classList.contains("support")) if(focusedElement.classList.contains("support"))
{ {
setIconLightness(focusedElement.firstChild); setSpriteLightness(focusedElement.firstChild);
} }
} }
}) })
} }
var supportIcons = creditsMenu.querySelectorAll(".support_icon");
{
for(var i = 0; i < supportIcons.length; ++i)
{
supportIcons[i].style.backgroundImage = "url(\"" + supportIcons[i].getAttribute("data-sprite") + "\")";
setIconLightness(supportIcons[i]);
}
}
} }
var sourceMenus = titleBar.querySelectorAll(".menu"); var sourceMenus = titleBar.querySelectorAll(".menu");
var helpButton = titleBar.querySelector(".help"); var helpButton = titleBar.querySelector(".help");
@ -319,3 +312,495 @@ else if(lastAnnotation = localStorage.getItem(lastAnnotationStorageItem))
{ {
player.setTime(lastAnnotation); player.setTime(lastAnnotation);
} }
function handleKey(key) {
var gotKey = true;
switch (key) {
case "q": {
if(quotesMenu)
{
toggleMenuVisibility(quotesMenu)
}
} break;
case "r": {
if(referencesMenu)
{
toggleMenuVisibility(referencesMenu)
}
} break;
case "f": {
if(filterMenu)
{
toggleMenuVisibility(filterMenu)
}
} break;
case "y": {
if(linkMenu)
{
toggleMenuVisibility(linkMenu)
}
break;
}
case "c": {
if(creditsMenu)
{
toggleMenuVisibility(creditsMenu)
}
} break;
case "t": {
if(cinera)
{
toggleTheatreMode();
}
} break;
case "T": {
if(cinera)
{
toggleSuperTheatreMode();
}
} break;
case "Enter": {
if(focusedElement)
{
if(focusedElement.parentNode.classList.contains("quotes_container"))
{
var time = focusedElement.querySelector(".timecode").getAttribute("data-timestamp");
player.setTime(parseInt(time, 10));
player.play();
}
else if(focusedElement.parentNode.classList.contains("references_container"))
{
var time = focusedIdentifier.getAttribute("data-timestamp");
player.setTime(parseInt(time, 10));
player.play();
}
else if(focusedElement.parentNode.classList.contains("credit"))
{
if(focusedElement.hasAttribute)
{
var url = focusedElement.getAttribute("href");
window.open(url, "_blank");
}
}
}
else
{
console.log("TODO(matt): Implement me, perhaps?\n");
}
} break;
case "o": {
if(focusedElement)
{
if(focusedElement.parentNode.classList.contains("references_container") ||
focusedElement.parentNode.classList.contains("quotes_container"))
{
var url = focusedElement.getAttribute("href");
window.open(url, "_blank");
}
else if(focusedElement.parentNode.classList.contains("credit"))
{
if(focusedElement.hasAttribute("href"))
{
var url = focusedElement.getAttribute("href");
window.open(url, "_blank");
}
}
}
} break;
case "w": case "k": case "ArrowUp": {
if(focusedElement)
{
if(focusedElement.parentNode.classList.contains("quotes_container"))
{
if(focusedElement.previousElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
lastFocusedQuote = focusedElement.previousElementSibling;
focusedElement = lastFocusedQuote;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
else if(focusedElement.parentNode.classList.contains("references_container"))
{
if(focusedElement.previousElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
focusedIdentifier.classList.remove("focused");
unfocusSprite(focusedIdentifier);
lastFocusedReference = focusedElement.previousElementSibling;
focusedElement = lastFocusedReference;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
lastFocusedIdentifier = focusedElement.querySelector(".ref_indices").firstElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
focusSprite(focusedIdentifier);
}
}
else if(focusedElement.parentNode.parentNode.classList.contains("filters"))
{
if(focusedElement.previousElementSibling &&
focusedElement.previousElementSibling.classList.contains("filter_content"))
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
lastFocusedCategory = focusedElement.previousElementSibling;
focusedElement = lastFocusedCategory;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
else if(focusedElement.parentNode.classList.contains("credit"))
{
if(focusedElement.parentNode.previousElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
if(focusedElement.parentNode.previousElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support"))
{
setSpriteLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
else
{
lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".person");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
}
}
} break;
case "s": case "j": case "ArrowDown": {
if(focusedElement)
{
if(focusedElement.parentNode.classList.contains("quotes_container"))
{
if(focusedElement.nextElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
lastFocusedQuote = focusedElement.nextElementSibling;
focusedElement = lastFocusedQuote;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
else if(focusedElement.parentNode.classList.contains("references_container"))
{
if(focusedElement.nextElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
focusedIdentifier.classList.remove("focused");
unfocusSprite(focusedIdentifier);
lastFocusedReference = focusedElement.nextElementSibling;
focusedElement = lastFocusedReference;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
lastFocusedIdentifier = focusedElement.querySelector(".ref_indices").firstElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
focusSprite(focusedIdentifier);
}
}
else if(focusedElement.parentNode.parentNode.classList.contains("filters"))
{
if(focusedElement.nextElementSibling &&
focusedElement.nextElementSibling.classList.contains("filter_content"))
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
lastFocusedCategory = focusedElement.nextElementSibling;
focusedElement = lastFocusedCategory;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
else if(focusedElement.parentNode.classList.contains("credit"))
{
if(focusedElement.parentNode.nextElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
if(focusedElement.parentNode.nextElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support"))
{
setSpriteLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
else
{
lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".person");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
}
}
} break;
case "a": case "h": case "ArrowLeft": {
if(focusedElement)
{
if(focusedElement.parentNode.classList.contains("references_container"))
{
if(focusedIdentifier.previousElementSibling)
{
focusedIdentifier.classList.remove("focused");
unfocusSprite(focusedIdentifier);
lastFocusedIdentifier = focusedIdentifier.previousElementSibling;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
focusSprite(focusedIdentifier);
}
else if(focusedIdentifier.parentNode.previousElementSibling.classList.contains("ref_indices"))
{
focusedIdentifier.classList.remove("focused");
unfocusSprite(focusedIdentifier);
lastFocusedIdentifier = focusedIdentifier.parentNode.previousElementSibling.lastElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
focusSprite(focusedIdentifier);
}
}
else if(focusedElement.classList.contains("filter_content"))
{
if(focusedElement.parentNode.classList.contains("filter_media") &&
focusedElement.parentNode.previousElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
lastFocusedMedium = focusedElement;
if(!lastFocusedTopic)
{
lastFocusedTopic = focusedElement.parentNode.previousElementSibling.children[1];
}
lastFocusedCategory = lastFocusedTopic;
focusedElement = lastFocusedCategory;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
else if(focusedElement.parentNode.classList.contains("credit"))
{
if(focusedElement.classList.contains("support"))
{
focusedElement.classList.remove("focused");
console.log(focusedElement);
unfocusSprite(focusedElement);
lastFocusedCreditItem = focusedElement.previousElementSibling;
setSpriteLightness(focusedElement.firstChild);
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
}
} break;
case "d": case "l": case "ArrowRight": {
if(focusedElement)
{
if(focusedElement.parentNode.classList.contains("references_container"))
{
if(focusedIdentifier.nextElementSibling)
{
focusedIdentifier.classList.remove("focused");
unfocusSprite(focusedIdentifier);
lastFocusedIdentifier = focusedIdentifier.nextElementSibling;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
focusSprite(focusedIdentifier);
}
else if(focusedIdentifier.parentNode.nextElementSibling)
{
focusedIdentifier.classList.remove("focused");
unfocusSprite(focusedIdentifier);
lastFocusedIdentifier = focusedIdentifier.parentNode.nextElementSibling.firstElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
focusSprite(focusedIdentifier);
}
}
else if(focusedElement.classList.contains("filter_content"))
{
if(focusedElement.parentNode.classList.contains("filter_topics") &&
focusedElement.parentNode.nextElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
lastFocusedTopic = focusedElement;
if(!lastFocusedMedium)
{
lastFocusedMedium = focusedElement.parentNode.nextElementSibling.children[1];
}
lastFocusedCategory = lastFocusedMedium;
focusedElement = lastFocusedCategory;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
else if(focusedElement.parentNode.classList.contains("credit"))
{
if(focusedElement.classList.contains("person") &&
focusedElement.nextElementSibling)
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
lastFocusedCreditItem = focusedElement.nextElementSibling;
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
}
} break;
case "x": case " ": {
if(focusedElement && focusedElement.classList.contains("filter_content"))
{
filterItemToggle(focusedElement);
if(focusedElement.nextElementSibling &&
focusedElement.nextElementSibling.classList.contains("filter_content"))
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
if(focusedElement.parentNode.classList.contains("filter_topics"))
{
lastFocusedTopic = focusedElement.nextElementSibling;
lastFocusedCategory = lastFocusedTopic;
}
else
{
lastFocusedMedium = focusedElement.nextElementSibling;
lastFocusedCategory = lastFocusedMedium;
}
lastFocusedElement = lastFocusedCategory;
focusedElement = lastFocusedElement;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
} break;
case "X": case "capitalSpace": {
if(focusedElement && focusedElement.classList.contains("filter_content"))
{
filterItemToggle(focusedElement);
if(focusedElement.previousElementSibling &&
focusedElement.previousElementSibling.classList.contains("filter_content"))
{
focusedElement.classList.remove("focused");
unfocusSprite(focusedElement);
if(focusedElement.parentNode.classList.contains("filter_topics"))
{
lastFocusedTopic = focusedElement.previousElementSibling;
lastFocusedCategory = lastFocusedTopic;
}
else
{
lastFocusedMedium = focusedElement.previousElementSibling;
lastFocusedCategory = lastFocusedMedium;
}
lastFocusedElement = lastFocusedCategory;
focusedElement = lastFocusedElement;
focusedElement.classList.add("focused");
focusSprite(focusedElement);
}
}
} break;
case "z": {
toggleFilterOrLinkMode();
} break;
case "v": {
if(focusedElement && focusedElement.classList.contains("filter_content"))
{
invertFilter(focusedElement)
}
} break;
case "V": {
resetFilter();
} break;
case "?": {
helpDocumentation.classList.toggle("visible");
} break;
case 'N':
case 'J':
case 'S': {
player.jumpToNextMarker();
} break;
case 'P':
case 'K':
case 'W': {
player.jumpToPrevMarker();
} break;
case '[':
case '<': {
if(prevEpisode)
{
location = prevEpisode.href;
}
} break;
case ']':
case '>': {
if(nextEpisode)
{
location = nextEpisode.href;
}
} break;
case 'Y': {
if(cineraLink)
{
if(linkAnnotation == false && player.playing)
{
player.pause();
}
if(linkMenu && !linkMenu.classList.contains("visible"))
{
toggleMenuVisibility(linkMenu);
}
SelectText(cineraLink);
}
}
default: {
gotKey = false;
} break;
}
return gotKey;
}

View File

@ -501,11 +501,11 @@ function toggleLinkMode(linkMode, link)
linkAnnotation = !linkAnnotation; linkAnnotation = !linkAnnotation;
if(linkAnnotation == true) if(linkAnnotation == true)
{ {
linkMode.textContent = "Link to current annotation"; linkMode.textContent = "Link to: current timestamp";
} }
else else
{ {
linkMode.textContent = "Link to nearest second"; linkMode.textContent = "Link to: nearest second";
} }
updateLink(); updateLink();
} }
@ -598,7 +598,7 @@ function toggleMenuVisibility(element) {
lastFocusedCreditItem = element.querySelectorAll(".credit .support")[0]; lastFocusedCreditItem = element.querySelectorAll(".credit .support")[0];
focusedElement = lastFocusedCreditItem; focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused"); focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild); setSpriteLightness(focusedElement.firstChild);
} }
else else
{ {
@ -901,11 +901,11 @@ function handleKey(key) {
if(focusedElement.parentNode.previousElementSibling.querySelector(".support") && if(focusedElement.parentNode.previousElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support")) focusedElement.classList.contains("support"))
{ {
setIconLightness(focusedElement.firstChild); setSpriteLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".support"); lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem; focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused"); focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild); setSpriteLightness(focusedElement.firstChild);
} }
else else
{ {
@ -968,11 +968,11 @@ function handleKey(key) {
if(focusedElement.parentNode.nextElementSibling.querySelector(".support") && if(focusedElement.parentNode.nextElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support")) focusedElement.classList.contains("support"))
{ {
setIconLightness(focusedElement.firstChild); setSpriteLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".support"); lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem; focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused"); focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild); setSpriteLightness(focusedElement.firstChild);
} }
else else
{ {
@ -1029,7 +1029,10 @@ function handleKey(key) {
focusedElement.classList.remove("focused"); focusedElement.classList.remove("focused");
lastFocusedCreditItem = focusedElement.previousElementSibling; lastFocusedCreditItem = focusedElement.previousElementSibling;
setIconLightness(focusedElement.firstChild); if(focusedElement.firstChild.classList.contains("cineraSprite"))
{
setSpriteLightness(focusedElement.firstChild);
}
focusedElement = lastFocusedCreditItem; focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused"); focusedElement.classList.add("focused");
} }
@ -1085,7 +1088,10 @@ function handleKey(key) {
lastFocusedCreditItem = focusedElement.nextElementSibling; lastFocusedCreditItem = focusedElement.nextElementSibling;
focusedElement = lastFocusedCreditItem; focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused"); focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild); if(focusedElement.firstChild.classList.contains("cineraSprite"))
{
setSpriteLightness(focusedElement.firstChild);
}
} }
} }
} }
@ -1244,6 +1250,7 @@ function filterItemToggle(filterItem) {
if(filterState[selectedCategory].off) if(filterState[selectedCategory].off)
{ {
filterItem.classList.add("off"); filterItem.classList.add("off");
disableSprite(filterItem);
if(!filterItem.parentNode.classList.contains("filter_media")) if(!filterItem.parentNode.classList.contains("filter_media"))
{ {
filterItem.querySelector(".icon").style.backgroundColor = "transparent"; filterItem.querySelector(".icon").style.backgroundColor = "transparent";
@ -1273,6 +1280,7 @@ function filterItemToggle(filterItem) {
if(markerCategories[k].classList.contains(selectedCategory)) if(markerCategories[k].classList.contains(selectedCategory))
{ {
markerCategories[k].classList.add("off"); markerCategories[k].classList.add("off");
disableSprite(markerCategories[k]);
} }
} }
testMarkers[j].classList.remove(selectedCategory); testMarkers[j].classList.remove(selectedCategory);
@ -1305,6 +1313,7 @@ function filterItemToggle(filterItem) {
else else
{ {
filterItem.classList.remove("off"); filterItem.classList.remove("off");
enableSprite(filterItem);
if(!filterItem.parentNode.classList.contains("filter_media")) if(!filterItem.parentNode.classList.contains("filter_media"))
{ {
filterItem.querySelector(".icon").style.backgroundColor = getComputedStyle(filterItem.querySelector(".icon")).getPropertyValue("border-color"); filterItem.querySelector(".icon").style.backgroundColor = getComputedStyle(filterItem.querySelector(".icon")).getPropertyValue("border-color");
@ -1338,6 +1347,7 @@ function filterItemToggle(filterItem) {
if(markerCategories[k].classList.contains(selectedCategory)) if(markerCategories[k].classList.contains(selectedCategory))
{ {
markerCategories[k].classList.remove("off"); markerCategories[k].classList.remove("off");
enableSprite(markerCategories[k]);
} }
} }
} }
@ -1489,6 +1499,7 @@ function navigateFilter(filterItem) {
if(filterItem != lastFocusedCategory) if(filterItem != lastFocusedCategory)
{ {
lastFocusedCategory.classList.remove("focused"); lastFocusedCategory.classList.remove("focused");
unfocusSprite(lastFocusedCategory);
if(filterItem.parentNode.classList.contains("filter_topics")) if(filterItem.parentNode.classList.contains("filter_topics"))
{ {
lastFocusedTopic = filterItem; lastFocusedTopic = filterItem;
@ -1501,6 +1512,7 @@ function navigateFilter(filterItem) {
} }
focusedElement = lastFocusedCategory; focusedElement = lastFocusedCategory;
focusedElement.classList.add("focused"); focusedElement.classList.add("focused");
focusSprite(focusedElement);
} }
} }
@ -1636,6 +1648,7 @@ function getBackgroundBrightness(element) {
var result = Math.sqrt(rgb[0] * rgb[0] * .241 + var result = Math.sqrt(rgb[0] * rgb[0] * .241 +
rgb[1] * rgb[1] * .691 + rgb[1] * rgb[1] * .691 +
rgb[2] * rgb[2] * .068); rgb[2] * rgb[2] * .068);
console.log(result);
return result; return result;
} }
@ -1668,15 +1681,3 @@ function setDotLightness(topicDot)
topicDot.style.borderColor = ("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");
}
}

86
cinera/cinera_post.js Normal file
View File

@ -0,0 +1,86 @@
var cineraDropdownNavigation = document.getElementsByClassName("cineraNavDropdown");
for(var i = 0; i < cineraDropdownNavigation.length; ++i)
{
var cineraFamily = cineraDropdownNavigation[i].getElementsByClassName("cineraNavHorizontal")[0];
cineraDropdownNavigation[i].addEventListener("click", function() {
if(cineraFamily.classList.contains("visible"))
{
cineraFamily.classList.remove("visible");
}
else
{
cineraFamily.classList.add("visible");
}
});
cineraDropdownNavigation[i].addEventListener("mouseenter", function() {
cineraFamily.classList.add("visible");
});
cineraDropdownNavigation[i].addEventListener("mouseleave", function() {
cineraFamily.classList.remove("visible");
});
}
var Sprites = document.getElementsByClassName("cineraSprite");
for(var i = 0; i < Sprites.length; ++i)
{
var This = Sprites[i];
var TileX = This.getAttribute("data-tile-width");
var TileY = This.getAttribute("data-tile-height");
var AspectRatio = TileX / TileY;
// TODO(matt): Nail down the desiredness situation. Perhaps respond to:
// width / min-width / height / min-height set in a CSS file
// flexbox layout, if possible
// NOTE(matt): These values are "decoupled" here, to facilitate handling of sizes other than the original
// We'll probably need some way of checking the desired and original of both the X and Y, and pick which one on
// which to base the computation of the other
var DesiredX = TileX;
var DesiredY = DesiredX / AspectRatio;
var Proportion = DesiredX / TileX;
//
////
// NOTE(matt): Size the container and its background image
//
This.style.width = DesiredX + "px";
This.style.height = DesiredY + "px";
var SpriteWidth = This.getAttribute("data-sprite-width");
var SpriteHeight = This.getAttribute("data-sprite-height");
This.style.backgroundSize = SpriteWidth * Proportion + "px " + SpriteHeight * Proportion + "px";
//
////
// NOTE(matt): Pick the tile
//
setSpriteLightness(This);
if(This.classList.contains("dark"))
{
This.style.backgroundPositionX = This.getAttribute("data-x-dark") + "px";
}
if(elementIsFocused(This))
{
This.style.backgroundPositionY = This.getAttribute("data-y-focused") + "px";
}
if(This.classList.contains("off"))
{
This.style.backgroundPositionY = This.getAttribute("data-y-disabled") + "px";
}
else
{
This.style.backgroundPositionY = This.getAttribute("data-y-normal") + "px";
}
//
////
// NOTE(matt): Finally apply the background image
var URL = This.getAttribute("data-src");
This.style.backgroundImage = "url('" + URL + "')";
}

112
cinera/cinera_pre.js Normal file
View File

@ -0,0 +1,112 @@
function getBackgroundBrightness(element) {
var colour = getComputedStyle(element).getPropertyValue("background-color");
var depth = 0;
while((colour == "transparent" || colour == "rgba(0, 0, 0, 0)") && depth <= 4)
{
element = element.parentNode;
colour = getComputedStyle(element).getPropertyValue("background-color");
++depth;
}
var rgb = colour.slice(4, -1).split(", ");
var result = Math.sqrt(rgb[0] * rgb[0] * .241 +
rgb[1] * rgb[1] * .691 +
rgb[2] * rgb[2] * .068);
return result;
}
function setSpriteLightness(spriteElement)
{
if(getBackgroundBrightness(spriteElement) < 127)
{
spriteElement.classList.add("dark");
}
else
{
spriteElement.classList.remove("dark");
}
}
function elementIsFocused(Element)
{
var Result = false;
if(Element.classList.contains("focused"))
{
Result = true;
}
while(Element.parent)
{
Element = Element.parent;
if(Element.classList.contains("focused"))
{
Result = true;
break;
}
}
return Result;
}
function focusSprite(Element)
{
if(Element.classList.contains("cineraSprite"))
{
setSpriteLightness(Element);
Element.style.backgroundPositionY = Element.getAttribute("data-y-focused") + "px";
}
for(var i = 0; i < Element.childElementCount; ++i)
{
focusSprite(Element.children[i]);
}
}
function enableSprite(Element)
{
if(Element.classList.contains("focused"))
{
focusSprite(Element);
}
else
{
if(Element.classList.contains("cineraSprite"))
{
setSpriteLightness(Element);
Element.style.backgroundPositionY = Element.getAttribute("data-y-normal") + "px";
}
for(var i = 0; i < Element.childElementCount; ++i)
{
enableSprite(Element.children[i]);
}
}
}
function disableSprite(Element)
{
if(Element.classList.contains("cineraSprite"))
{
setSpriteLightness(Element);
Element.style.backgroundPositionY = Element.getAttribute("data-y-disabled") + "px";
}
for(var i = 0; i < Element.childElementCount; ++i)
{
disableSprite(Element.children[i]);
}
}
function unfocusSprite(Element)
{
if(Element.classList.contains("off"))
{
disableSprite(Element);
}
else
{
if(Element.classList.contains("cineraSprite"))
{
setSpriteLightness(Element);
Element.style.backgroundPositionY = Element.getAttribute("data-y-normal") + "px";
}
for(var i = 0; i < Element.childElementCount; ++i)
{
unfocusSprite(Element.children[i]);
}
}
}

View File

@ -9,41 +9,202 @@ if (location.hash && location.hash.length > 0) {
} }
var indexControl = document.getElementById("cineraIndexControl"); var indexControl = document.getElementById("cineraIndexControl");
var indexContainer = document.getElementById("cineraIndex");
var projectID = indexContainer.attributes.getNamedItem("data-project").value;
var theme = indexContainer.classList.item(0);
var baseURL = indexContainer.attributes.getNamedItem("data-baseURL").value;
var playerLocation = indexContainer.attributes.getNamedItem("data-playerLocation").value;
var resultsSummary = document.getElementById("cineraResultsSummary");
var indexSort = indexControl.querySelector("#cineraIndexSort"); var indexSort = indexControl.querySelector("#cineraIndexSort");
var indexEntries = indexContainer.querySelector("#cineraIndexEntries");
var indexSortChronological = true; var indexSortChronological = true;
indexSort.addEventListener("click", function(ev) { var filterMenu = indexControl.querySelector(".cineraIndexFilter");
if(indexSortChronological) if(filterMenu)
{
var filterContainer = filterMenu.querySelector(".filter_container");
//menuState.push(linkMenu);
filterMenu.addEventListener("mouseenter", function(ev) {
filterContainer.style.display = "block";
});
filterMenu.addEventListener("mouseleave", function(ev) {
filterContainer.style.display = "none";
});
}
function hideEntriesOfProject(ProjectElement)
{
if(!ProjectElement.classList.contains("off"))
{ {
this.firstChild.nodeValue = "Sort: New to Old ⏷" ProjectElement.classList.add("off");
indexEntries.style.flexFlow = "column-reverse"; }
var baseURL = ProjectElement.attributes.getNamedItem("data-baseURL").value;
for(var i = 0; i < projects.length; ++i)
{
var ThisProject = projects[i];
if(ThisProject.baseURL === baseURL)
{
ThisProject.filteredOut = true;
if(ThisProject.entriesContainer != null)
{
ThisProject.entriesContainer.style.display = "none";
disableSprite(ThisProject.entriesContainer.parentElement);
}
}
}
}
function showEntriesOfProject(ProjectElement)
{
if(ProjectElement.classList.contains("off"))
{
ProjectElement.classList.remove("off");
}
var baseURL = ProjectElement.attributes.getNamedItem("data-baseURL").value;
for(var i = 0; i < projects.length; ++i)
{
var ThisProject = projects[i];
if(ThisProject.baseURL === baseURL)
{
ThisProject.filteredOut = false;
if(ThisProject.entriesContainer != null)
{
ThisProject.entriesContainer.style.display = "flex";
enableSprite(ThisProject.entriesContainer.parentElement);
}
}
}
}
function hideProjectSearchResults(baseURL)
{
var cineraResults = document.getElementById("cineraResults");
if(cineraResults)
{
var cineraResultsProjects = cineraResults.querySelectorAll(".projectContainer");
for(var i = 0; i < cineraResultsProjects.length; ++i)
{
var resultBaseURL = cineraResultsProjects[i].attributes.getNamedItem("data-baseURL").value;
if(baseURL === resultBaseURL)
{
cineraResultsProjects[i].style.display = "none";
return;
}
}
}
}
function showProjectSearchResults(baseURL)
{
var cineraResults = document.getElementById("cineraResults");
if(cineraResults)
{
var cineraResultsProjects = cineraResults.querySelectorAll(".projectContainer");
for(var i = 0; i < cineraResultsProjects.length; ++i)
{
var resultBaseURL = cineraResultsProjects[i].attributes.getNamedItem("data-baseURL").value;
if(baseURL === resultBaseURL)
{
cineraResultsProjects[i].style.display = "flex";
return;
}
}
}
}
function toggleEntriesOfProjectAndChildren(ProjectFilterElement)
{
var baseURL = ProjectFilterElement.attributes.getNamedItem("data-baseURL").value;
var shouldShow = ProjectFilterElement.classList.contains("off");
if(shouldShow)
{
ProjectFilterElement.classList.remove("off");
enableSprite(ProjectFilterElement);
} }
else else
{ {
this.firstChild.nodeValue = "Sort: Old to New ⏶" ProjectFilterElement.classList.add("off");
indexEntries.style.flexFlow = "column"; disableSprite(ProjectFilterElement);
} }
indexSortChronological = !indexSortChronological;
});
var lastQuery = null; for(var i = 0; i < projects.length; ++i)
var resultsToRender = []; {
var resultsIndex = 0; var ThisProject = projects[i];
var resultsMarkerIndex = -1; if(ThisProject.baseURL === baseURL)
{
if(shouldShow)
{
ThisProject.filteredOut = false;
enableSprite(ThisProject.projectTitleElement.parentElement);
if(ThisProject.entriesContainer != null)
{
ThisProject.entriesContainer.style.display = "flex";
}
showProjectSearchResults(projects[i].baseURL);
}
else
{
ThisProject.filteredOut = true;
disableSprite(ThisProject.projectTitleElement.parentElement);
if(ThisProject.entriesContainer != null)
{
ThisProject.entriesContainer.style.display = "none";
}
hideProjectSearchResults(ThisProject.baseURL);
}
}
}
var indexChildFilterProjects = ProjectFilterElement.querySelectorAll(".cineraFilterProject");
for(var j = 0; j < indexChildFilterProjects.length; ++j)
{
var ThisElement = indexChildFilterProjects[j];
if(shouldShow)
{
var baseURL = ThisElement.attributes.getNamedItem("data-baseURL").value;
showEntriesOfProject(ThisElement);
showProjectSearchResults(baseURL);
}
else
{
var baseURL = ThisElement.attributes.getNamedItem("data-baseURL").value;
hideEntriesOfProject(ThisElement);
hideProjectSearchResults(baseURL);
}
}
}
var indexFilter = indexControl.querySelector(".cineraIndexFilter");
if(indexFilter)
{
var indexFilterProjects = indexFilter.querySelectorAll(".cineraFilterProject");
for(var i = 0; i < indexFilterProjects.length; ++i)
{
indexFilterProjects[i].addEventListener("mouseover", function(ev) {
ev.stopPropagation();
this.classList.add("focused");
focusSprite(this);
});
indexFilterProjects[i].addEventListener("mouseout", function(ev) {
ev.stopPropagation();
this.classList.remove("focused");
unfocusSprite(this);
});
indexFilterProjects[i].addEventListener("click", function(ev) {
ev.stopPropagation();
toggleEntriesOfProjectAndChildren(this);
});
}
}
var resultsSummary = document.getElementById("cineraResultsSummary");
var resultsContainer = document.getElementById("cineraResults"); var resultsContainer = document.getElementById("cineraResults");
var rendering = false;
var indexContainer = document.getElementById("cineraIndex");
var projectsContainer = indexContainer.querySelectorAll(".cineraIndexProject");
var projectContainerPrototype = document.createElement("DIV");
projectContainerPrototype.classList.add("projectContainer");
var dayContainerPrototype = document.createElement("DIV"); var dayContainerPrototype = document.createElement("DIV");
dayContainerPrototype.classList.add("dayContainer"); dayContainerPrototype.classList.add("dayContainer");
dayContainerPrototype.classList.add(theme);
var dayNamePrototype = document.createElement("SPAN"); var dayNamePrototype = document.createElement("SPAN");
dayNamePrototype.classList.add("dayName"); dayNamePrototype.classList.add("dayName");
@ -51,7 +212,6 @@ dayContainerPrototype.appendChild(dayNamePrototype);
var markerListPrototype = document.createElement("DIV"); var markerListPrototype = document.createElement("DIV");
markerListPrototype.classList.add("markerList"); markerListPrototype.classList.add("markerList");
markerListPrototype.classList.add(theme);
dayContainerPrototype.appendChild(markerListPrototype); dayContainerPrototype.appendChild(markerListPrototype);
var markerPrototype = document.createElement("A"); var markerPrototype = document.createElement("A");
@ -61,9 +221,132 @@ if(resultsContainer.getAttribute("data-single") == 0)
markerPrototype.setAttribute("target", "_blank"); markerPrototype.setAttribute("target", "_blank");
} }
var highlightPrototype = document.createElement("B"); function prepareToParseIndexFile(project)
{
project.xhr.addEventListener("load", function() {
var contents = project.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.name != null && episode.title != null) {
episode.filename = episode.name;
episode.day = getEpisodeName(episode.filename + ".html.md");
episode.dayContainerPrototype = project.dayContainerPrototype;
episode.markerPrototype = markerPrototype;
episode.playerURLPrefix = project.playerURLPrefix;
project.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).trim().slice(1, -1);
} 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");
project.parsed = true;
runSearch(true);
});
project.xhr.addEventListener("error", function() {
console.error("Failed to load content");
});
}
var episodes = []; var projects = [];
function prepareProjects()
{
for(var i = 0; i < projectsContainer.length; ++i)
{
var ID = projectsContainer[i].attributes.getNamedItem("data-project").value;
var baseURL = projectsContainer[i].attributes.getNamedItem("data-baseURL").value;
var playerLocation = projectsContainer[i].attributes.getNamedItem("data-playerLocation").value;
var theme = projectsContainer[i].classList.item(1);
projects[i] =
{
baseURL: baseURL,
playerURLPrefix: (baseURL ? baseURL + "/" : "") + (playerLocation ? playerLocation + "/" : ""),
indexLocation: (baseURL ? baseURL + "/" : "") + ID + ".index",
projectTitleElement: projectsContainer[i].querySelector(":scope > .cineraProjectTitle"),
entriesContainer: projectsContainer[i].querySelector(":scope > .cineraIndexEntries"),
dayContainerPrototype: dayContainerPrototype.cloneNode(true),
filteredOut: false,
parsed: false,
searched: false,
resultsToRender: [],
resultsIndex: 0,
theme: theme,
episodes: [],
xhr: new XMLHttpRequest(),
}
projects[i].dayContainerPrototype.classList.add(theme);
projects[i].dayContainerPrototype.children[1].classList.add(theme);
document.querySelector(".spinner").classList.add("show");
projects[i].xhr.open("GET", projects[i].indexLocation);
projects[i].xhr.setRequestHeader("Content-Type", "text/plain");
projects[i].xhr.send();
prepareToParseIndexFile(projects[i]);
}
}
prepareProjects();
indexSort.addEventListener("click", function(ev) {
if(indexSortChronological)
{
this.firstChild.nodeValue = "Sort: New to Old ⏷"
for(var i = 0; i < projects.length; ++i)
{
if(projects[i].entriesContainer)
{
projects[i].entriesContainer.style.flexFlow = "column-reverse";
}
}
}
else
{
this.firstChild.nodeValue = "Sort: Old to New ⏶"
for(var i = 0; i < projects.length; ++i)
{
if(projects[i].entriesContainer)
{
projects[i].entriesContainer.style.flexFlow = "column";
}
}
}
indexSortChronological = !indexSortChronological;
runSearch(true);
});
var lastQuery = null;
var markerList = null;
var projectContainer = null;
var resultsMarkerIndex = -1;
var rendering = false;
var highlightPrototype = document.createElement("B");
function getEpisodeName(filename) { function getEpisodeName(filename) {
var day = filename; var day = filename;
@ -90,57 +373,128 @@ function padTimeComponent(component) {
return (component < 10 ? "0" + component : component); return (component < 10 ? "0" + component : component);
} }
function resetProjectsForSearch()
{
for(var i = 0; i < projects.length; ++i)
{
var project = projects[i];
project.searched = false;
project.resultsToRender = [];
}
}
var renderHandle; var renderHandle;
function runSearch() {
function runSearch(refresh) {
var queryStr = document.getElementById("query").value; var queryStr = document.getElementById("query").value;
if (lastQuery != queryStr) { if (refresh || lastQuery != queryStr) {
var oldResultsContainer = resultsContainer; var oldResultsContainer = resultsContainer;
resultsContainer = oldResultsContainer.cloneNode(false); resultsContainer = oldResultsContainer.cloneNode(false);
oldResultsContainer.parentNode.insertBefore(resultsContainer, oldResultsContainer); oldResultsContainer.parentNode.insertBefore(resultsContainer, oldResultsContainer);
oldResultsContainer.remove(); oldResultsContainer.remove();
resultsIndex = 0; for(var i = 0; i < projects.length; ++i)
{
projects[i].resultsIndex = 0;
}
resultsMarkerIndex = -1; resultsMarkerIndex = -1;
} }
lastQuery = queryStr; lastQuery = queryStr;
resultsToRender = [];
resetProjectsForSearch();
var numEpisodes = 0; var numEpisodes = 0;
var numMarkers = 0; var numMarkers = 0;
var totalSeconds = 0; var totalSeconds = 0;
// NOTE(matt): Function defined within runSearch() so that we can modify numEpisodes, numMarkers and totalSeconds
function runSearchInterior(resultsToRender, query, episode)
{
var matches = [];
for (var k = 0; k < episode.markers.length; ++k) {
query.lastIndex = 0;
var result = query.exec(episode.markers[k].text);
if (result && result[0].length > 0) {
numMarkers++;
matches.push(episode.markers[k]);
if (k < episode.markers.length-1) {
totalSeconds += episode.markers[k+1].totalTime - episode.markers[k].totalTime;
}
}
}
if (matches.length > 0) {
numEpisodes++;
resultsToRender.push({
query: query,
episode: episode,
matches: matches
});
}
}
if (queryStr && queryStr.length > 0) { if (queryStr && queryStr.length > 0) {
indexContainer.style.display = "none"; indexContainer.style.display = "none";
resultsSummary.style.display = "block"; resultsSummary.style.display = "block";
if (episodes.length > 0) { var shouldRender = false;
var query = new RegExp(queryStr.replace("(", "\\(").replace(")", "\\)").replace(/\|+/, "\|").replace(/\|$/, "").replace(/(^|[^\\])\\$/, "$1"), "gi"); var query = new RegExp(queryStr.replace("(", "\\(").replace(")", "\\)").replace(/\|+/, "\|").replace(/\|$/, "").replace(/(^|[^\\])\\$/, "$1"), "gi");
for (var i = 0; i < episodes.length; ++i) {
var episode = episodes[i]; // Visible
var matches = []; for(var i = 0; i < projects.length; ++i)
for (var j = 0; j < episode.markers.length; ++j) { {
query.lastIndex = 0; var project = projects[i];
var result = query.exec(episode.markers[j].text); if(project.parsed && !project.filteredOut && project.episodes.length > 0) {
if (result && result[0].length > 0) { if(indexSortChronological)
numMarkers++; {
matches.push(episode.markers[j]); for(var j = 0; j < project.episodes.length; ++j) {
if (j < episode.markers.length-1) { var episode = project.episodes[j];
totalSeconds += episode.markers[j+1].totalTime - episode.markers[j].totalTime; runSearchInterior(project.resultsToRender, query, episode);
}
} }
} }
if (matches.length > 0) { else
numEpisodes++; {
resultsToRender.push({ for(var j = project.episodes.length; j > 0; --j) {
query: query, var episode = project.episodes[j - 1];
episode: episode, runSearchInterior(project.resultsToRender, query, episode);
matches: matches }
});
} }
}
shouldRender = true;
project.searched = true;
}
}
// Invisible
for(var i = 0; i < projects.length; ++i)
{
var project = projects[i];
if(project.parsed && project.filteredOut && !project.searched && project.episodes.length > 0) {
if(indexSortChronological)
{
for(var j = 0; j < project.episodes.length; ++j) {
var episode = project.episodes[j];
runSearchInterior(project.resultsToRender, query, episode);
}
}
else
{
for(var j = project.episodes.length; j > 0; --j) {
var episode = project.episodes[j - 1];
runSearchInterior(project.resultsToRender, query, episode);
}
}
shouldRender = true;
project.searched = true;
}
}
if(shouldRender)
{
if (rendering) { if (rendering) {
clearTimeout(renderHandle); clearTimeout(renderHandle);
} }
renderResults(); renderResults();
} else {
document.querySelector(".spinner").classList.add("show");
} }
} }
else else
@ -155,63 +509,85 @@ function runSearch() {
} }
function renderResults() { function renderResults() {
if (resultsIndex < resultsToRender.length) { var maxItems = 42;
rendering = true; var numItems = 0;
var maxItems = 42; for(var i = 0; i < projects.length; ++i)
var numItems = 0; {
while (numItems < maxItems && resultsIndex < resultsToRender.length) { var project = projects[i];
var query = resultsToRender[resultsIndex].query; if (project.resultsIndex < project.resultsToRender.length) {
var episode = resultsToRender[resultsIndex].episode; rendering = true;
var matches = resultsToRender[resultsIndex].matches; while (numItems < maxItems && project.resultsIndex < project.resultsToRender.length) {
var markerList = null; var query = project.resultsToRender[project.resultsIndex].query;
if (resultsMarkerIndex == -1) { var episode = project.resultsToRender[project.resultsIndex].episode;
var dayContainer = dayContainerPrototype.cloneNode(true); var matches = project.resultsToRender[project.resultsIndex].matches;
var dayName = dayContainer.children[0]; if (resultsMarkerIndex == -1) {
markerList = dayContainer.children[1]; if(project.resultsIndex == 0 || project.resultsToRender[project.resultsIndex - 1].episode.playerURLPrefix != episode.playerURLPrefix)
dayName.textContent = episode.day + ": " + episode.title; {
resultsContainer.appendChild(dayContainer); projectContainer = projectContainerPrototype.cloneNode(true);
resultsMarkerIndex = 0; for(var i = 0; i < projects.length; ++i)
numItems++; {
} else { if(projects[i].playerURLPrefix === episode.playerURLPrefix)
markerList = document.querySelector("#cineraResults > .dayContainer:nth-child(" + (resultsIndex+1) + ") .markerList"); {
} projectContainer.setAttribute("data-baseURL", projects[i].baseURL);
if(projects[i].filteredOut)
while (numItems < maxItems && resultsMarkerIndex < matches.length) { {
var match = matches[resultsMarkerIndex]; projectContainer.style.display = "none";
var marker = markerPrototype.cloneNode(); }
var playerURLPrefix = (baseURL ? baseURL + "/" : "") + (playerLocation ? playerLocation + "/" : ""); }
marker.setAttribute("href", playerURLPrefix + episode.filename.replace(/"/g, "") + "/#" + match.totalTime); }
query.lastIndex = 0; resultsContainer.appendChild(projectContainer);
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(); else
highlightEl.textContent = result[0]; {
marker.appendChild(highlightEl); projectContainer = resultsContainer.lastElementChild;
cursor = result.index + result[0].length; }
var dayContainer = episode.dayContainerPrototype.cloneNode(true);
var dayName = dayContainer.children[0];
markerList = dayContainer.children[1];
dayName.textContent = episode.day + ": " + episode.title;
projectContainer.appendChild(dayContainer);
resultsMarkerIndex = 0;
numItems++;
}
while (numItems < maxItems && resultsMarkerIndex < matches.length) {
var match = matches[resultsMarkerIndex];
var marker = episode.markerPrototype.cloneNode(true);
marker.setAttribute("href", episode.playerURLPrefix + 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);
numItems++;
resultsMarkerIndex++;
} }
if (cursor < text.length) { if (resultsMarkerIndex == matches.length) {
marker.appendChild(document.createTextNode(text.slice(cursor, text.length))); resultsMarkerIndex = -1;
project.resultsIndex++;
} }
markerList.appendChild(marker);
numItems++;
resultsMarkerIndex++;
}
if (resultsMarkerIndex == matches.length) {
resultsMarkerIndex = -1;
resultsIndex++;
} }
renderHandle = setTimeout(renderResults, 0);
} else {
rendering = false;
} }
renderHandle = setTimeout(renderResults, 0);
} else {
rendering = false;
} }
} }
@ -244,55 +620,6 @@ queryEl.addEventListener("input", function(ev) {
runSearch(); 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).trim().slice(1, -1);
} 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");
});
var indexLocation = (baseURL ? baseURL + "/" : "") + projectID + ".index";
xhr.open("GET", indexLocation);
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.send();
runSearch(); runSearch();
// Testing

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 893 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 801 B

7656
cinera/stb_image.h Normal file

File diff suppressed because it is too large Load Diff