var originalTextContent = { TitleQuotes: null, TitleReferences: null, TitleCredits: null, EpisodePrev: null, EpisodeNext: null, }; var menuState = []; var titleBar = document.querySelector(".cineraMenus"); var quotesMenu = titleBar.querySelector(".quotes_container"); if(quotesMenu) { originalTextContent.TitleQuotes = quotesMenu.previousElementSibling.textContent; menuState.push(quotesMenu); var quoteItems = quotesMenu.querySelectorAll(".ref"); if(quoteItems) { for(var i = 0; i < quoteItems.length; ++i) { quoteItems[i].addEventListener("mouseenter", function(ev) { mouseOverQuotes(this); }) }; } 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) { originalTextContent.TitleReferences = referencesMenu.previousElementSibling.textContent; 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"); var filterInitState = new Object(); var filterState = new Object(); 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 filterItemName = filterItems[i].classList.item(1); if(filterItems[i].parentNode.classList.contains("filter_topics")) { filterInitState[filterItemName] = { "type" : "topic", "off": (filterItems[i].classList.item(2) == "off") }; filterState[filterItemName] = { "type" : "topic", "off": (filterItems[i].classList.item(2) == "off") }; } else { filterInitState[filterItemName] = { "type" : "medium", "off": (filterItems[i].classList.item(2) == "off") }; filterState[filterItemName] = { "type" : "medium", "off": (filterItems[i].classList.item(2) == "off") }; } } } var views = { REGULAR: 0, THEATRE: 1, SUPERTHEATRE: 2, }; var devices = { DESKTOP: 0, MOBILE: 1, }; var cineraProps = { C: null, V: views.REGULAR, Z: null, X: null, Y: null, W: null, mW: null, H: null, mH: null, P: null, D: devices.DESKTOP, }; var viewsMenu = titleBar.querySelector(".views"); if(viewsMenu) { menuState.push(viewsMenu); var viewsContainer = viewsMenu.querySelector(".views_container"); viewsMenu.addEventListener("mouseenter", function(ev) { handleMouseOverViewsMenu(); }); viewsMenu.addEventListener("mouseleave", function(ev) { viewsContainer.style.display = "none"; }); var viewItems = viewsMenu.querySelectorAll(".view"); for(var i = 0; i < viewItems.length; ++i) { viewItems[i].addEventListener("click", function(ev) { switch(this.getAttribute("data-id")) { case "regular": case "theatre": { toggleTheatreMode(); } break; case "super": { toggleSuperTheatreMode(); } break; } }); } } var baseURL = location.hash ? (location.toString().substr(0, location.toString().length - location.hash.length)) : location; var linkMenu = titleBar.querySelector(".link_container"); linkAnnotation = true; if(linkMenu) { menuState.push(linkMenu); var linkMode = linkMenu.querySelector("#cineraLinkMode"); var link = linkMenu.querySelector("#cineraLink"); linkMode.addEventListener("click", function(ev) { toggleLinkMode(linkMode, link); }); link.addEventListener("click", function(ev) { CopyToClipboard(link); toggleMenuVisibility(linkMenu); }); } var creditsMenu = titleBar.querySelector(".credits_container"); if(creditsMenu) { originalTextContent.TitleCredits = creditsMenu.previousElementSibling.textContent; 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"); unfocusSprite(lastFocusedCreditItem); if(lastFocusedCreditItem.classList.contains("support")) { setSpriteLightness(lastFocusedCreditItem.firstChild); } lastFocusedCreditItem = this; focusedElement = lastFocusedCreditItem; focusedElement.classList.add("focused"); focusSprite(focusedElement); if(focusedElement.classList.contains("support")) { setSpriteLightness(focusedElement.firstChild); } } }) } } var sourceMenus = titleBar.querySelectorAll(".menu"); var helpButton = titleBar.querySelector(".help"); window.addEventListener("blur", function(){ helpButton.firstElementChild.innerText = "¿"; helpButton.firstElementChild.title = "Keypresses will not pass through to Cinera because focus is currently elsewhere.\n\nTo regain focus, please press Tab / Shift-Tab (multiple times) or click somewhere related to Cinera other than the video, e.g. this button"; }); window.addEventListener("focus", function(){ helpButton.firstElementChild.innerText = "?"; helpButton.firstElementChild.title = "" }); 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(".cineraPlayerContainer") var prevEpisode = playerContainer.querySelector(".episodeMarker.prev"); if(prevEpisode) { originalTextContent.EpisodePrev = prevEpisode.firstChild.textContent; } var nextEpisode = playerContainer.querySelector(".episodeMarker.next"); if(nextEpisode) { originalTextContent.EpisodeNext = nextEpisode.firstChild.textContent; } var testMarkers = playerContainer.querySelectorAll(".marker"); var cinera = playerContainer.parentNode; // NOTE(matt): All the originalTextContent values must be set by this point, because the player's construction may need them var player = new Player(playerContainer, onRefChanged); var cineraViewStorageItem = "cineraView"; if(viewsMenu && localStorage.getItem(cineraViewStorageItem)) { toggleTheatreMode(); } window.addEventListener("resize", function() { player.updateSize(); }); document.addEventListener("keydown", function(ev) { var key = ev.key; if(ev.getModifierState("Shift") && key == " ") { key = "capitalSpace"; } if(!ev.getModifierState("Control") && 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 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]); } var lastAnnotationStorageItem = "cineraTimecode_" + window.location.pathname; var lastAnnotation; if(location.hash) { player.setTime(location.hash.startsWith('#') ? location.hash.substr(1) : location.hash); } else if(lastAnnotation = localStorage.getItem(lastAnnotationStorageItem)) { 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; }