diff options
| author | czaks <marcin@6irc.net> | 2014-04-06 21:27:41 +0200 |
|---|---|---|
| committer | czaks <marcin@6irc.net> | 2014-04-06 21:27:41 +0200 |
| commit | 647c59f8209e3a82adb3e54f4c211fc67f1e1fd6 (patch) | |
| tree | c517e1b16765968507b5a7f653b1c335be58cde4 /js | |
| parent | be572328014df3d3b4c9d1692e21a9dced0b384f (diff) | |
move webm js into a better place
Diffstat (limited to 'js')
| -rw-r--r-- | js/expand-video.js | 235 | ||||
| -rw-r--r-- | js/webm-settings.js | 81 |
2 files changed, 316 insertions, 0 deletions
diff --git a/js/expand-video.js b/js/expand-video.js new file mode 100644 index 00000000..27438427 --- /dev/null +++ b/js/expand-video.js @@ -0,0 +1,235 @@ +/* This file is dedicated to the public domain; you may do as you wish with it. */ +/* Note: This code expects the global variable configRoot to be set. */ + +function setupVideo(thumb, url) { + var video = null; + var videoContainer, videoHide; + var expanded = false; + var hovering = false; + var loop = true; + var loopControls = [document.createElement("span"), document.createElement("span")]; + var fileInfo = thumb.parentNode.querySelector(".fileinfo"); + var mouseDown = false; + + function unexpand() { + if (expanded) { + expanded = false; + if (video.pause) video.pause(); + videoContainer.style.display = "none"; + thumb.style.display = "inline"; + video.style.maxWidth = "inherit"; + video.style.maxHeight = "inherit"; + } + } + + function unhover() { + if (hovering) { + hovering = false; + if (video.pause) video.pause(); + videoContainer.style.display = "none"; + video.style.maxWidth = "inherit"; + video.style.maxHeight = "inherit"; + } + } + + // Create video element if does not exist yet + function getVideo() { + if (video == null) { + video = document.createElement("video"); + video.src = url; + video.loop = loop; + video.innerText = "Your browser does not support HTML5 video."; + + videoHide = document.createElement("img"); + videoHide.src = configRoot + "cc/collapse.gif"; + videoHide.alt = "[ - ]"; + videoHide.title = "Collapse video"; + videoHide.style.marginLeft = "-15px"; + videoHide.style.cssFloat = "left"; + videoHide.addEventListener("click", unexpand, false); + + videoContainer = document.createElement("div"); + videoContainer.style.paddingLeft = "15px"; + videoContainer.style.display = "none"; + videoContainer.appendChild(videoHide); + videoContainer.appendChild(video); + thumb.parentNode.insertBefore(videoContainer, thumb.nextSibling); + + // Dragging to the left collapses the video + video.addEventListener("mousedown", function(e) { + if (e.button == 0) mouseDown = true; + }, false); + video.addEventListener("mouseup", function(e) { + if (e.button == 0) mouseDown = false; + }, false); + video.addEventListener("mouseenter", function(e) { + mouseDown = false; + }, false); + video.addEventListener("mouseout", function(e) { + if (mouseDown && e.clientX - video.getBoundingClientRect().left <= 0) { + unexpand(); + } + mouseDown = false; + }, false); + } + } + + // Clicking on thumbnail expands video + thumb.addEventListener("click", function(e) { + if (setting("videoexpand") && !e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) { + getVideo(); + expanded = true; + hovering = false; + + video.style.position = "static"; + video.style.pointerEvents = "inherit"; + video.style.display = "inline"; + videoHide.style.display = "inline"; + videoContainer.style.display = "block"; + videoContainer.style.position = "static"; + thumb.style.display = "none"; + + video.muted = (setting("videovolume") == 0); + video.volume = setting("videovolume"); + video.controls = true; + if (video.readyState == 0) { + video.addEventListener("loadedmetadata", expand2, false); + } else { + setTimeout(expand2, 0); + } + video.play(); + e.preventDefault(); + } + }, false); + + function expand2() { + video.style.maxWidth = "100%"; + video.style.maxHeight = window.innerHeight + "px"; + var bottom = video.getBoundingClientRect().bottom; + if (bottom > window.innerHeight) { + window.scrollBy(0, bottom - window.innerHeight); + } + // work around Firefox volume control bug + video.volume = Math.max(setting("videovolume") - 0.001, 0); + video.volume = setting("videovolume"); + } + + // Hovering over thumbnail displays video + thumb.addEventListener("mouseover", function(e) { + if (setting("videohover")) { + getVideo(); + expanded = false; + hovering = true; + + var docRight = document.documentElement.getBoundingClientRect().right; + var thumbRight = thumb.querySelector("img, video").getBoundingClientRect().right; + var maxWidth = docRight - thumbRight - 20; + if (maxWidth < 250) maxWidth = 250; + + video.style.position = "fixed"; + video.style.right = "0px"; + video.style.top = "0px"; + var docRight = document.documentElement.getBoundingClientRect().right; + var thumbRight = thumb.querySelector("img, video").getBoundingClientRect().right; + video.style.maxWidth = maxWidth + "px"; + video.style.maxHeight = "100%"; + video.style.pointerEvents = "none"; + + video.style.display = "inline"; + videoHide.style.display = "none"; + videoContainer.style.display = "inline"; + videoContainer.style.position = "fixed"; + + video.muted = (setting("videovolume") == 0); + video.volume = setting("videovolume"); + video.controls = false; + video.play(); + } + }, false); + + thumb.addEventListener("mouseout", unhover, false); + + // Scroll wheel on thumbnail adjusts default volume + thumb.addEventListener("wheel", function(e) { + if (setting("videohover")) { + var volume = setting("videovolume"); + if (e.deltaY > 0) volume -= 0.1; + if (e.deltaY < 0) volume += 0.1; + if (volume < 0) volume = 0; + if (volume > 1) volume = 1; + if (video != null) { + video.muted = (volume == 0); + video.volume = volume; + } + changeSetting("videovolume", volume); + e.preventDefault(); + } + }, false); + + // [play once] vs [loop] controls + function setupLoopControl(i) { + loopControls[i].addEventListener("click", function(e) { + loop = (i != 0); + thumb.href = thumb.href.replace(/([\?&])loop=\d+/, "$1loop=" + i); + if (video != null) { + video.loop = loop; + if (loop && video.currentTime >= video.duration) { + video.currentTime = 0; + } + } + loopControls[i].style.fontWeight = "bold"; + loopControls[1-i].style.fontWeight = "inherit"; + }, false); + } + + loopControls[0].textContent = "[play once]"; + loopControls[1].textContent = "[loop]"; + loopControls[1].style.fontWeight = "bold"; + for (var i = 0; i < 2; i++) { + setupLoopControl(i); + loopControls[i].style.whiteSpace = "nowrap"; + fileInfo.appendChild(document.createTextNode(" ")); + fileInfo.appendChild(loopControls[i]); + } +} + +function setupVideosIn(element) { + var thumbs = element.querySelectorAll("a.file"); + for (var i = 0; i < thumbs.length; i++) { + if (/\.webm$/.test(thumbs[i].pathname)) { + setupVideo(thumbs[i], thumbs[i].href); + } else { + var m = thumbs[i].search.match(/\bv=([^&]*)/); + if (m != null) { + var url = decodeURIComponent(m[1]); + if (/\.webm$/.test(url)) setupVideo(thumbs[i], url); + } + } + } +} + +if (window.addEventListener) window.addEventListener("load", function(e) { + // Insert menu from settings.js + if (typeof settingsMenu != "undefined") document.body.insertBefore(settingsMenu, document.body.firstChild); + + // Setup Javascript events for videos in document now + setupVideosIn(document); + + // Setup Javascript events for videos added by updater + if (window.MutationObserver) { + var observer = new MutationObserver(function(mutations) { + for (var i = 0; i < mutations.length; i++) { + var additions = mutations[i].addedNodes; + if (additions == null) continue; + for (var j = 0; j < additions.length; j++) { + var node = additions[j]; + if (node.nodeType == 1) { + setupVideosIn(node); + } + } + } + }); + observer.observe(document.body, {childList: true, subtree: true}); + } +}, false); + diff --git a/js/webm-settings.js b/js/webm-settings.js new file mode 100644 index 00000000..f67e42d6 --- /dev/null +++ b/js/webm-settings.js @@ -0,0 +1,81 @@ +/* This file is dedicated to the public domain; you may do as you wish with it. */ + +// Default settings +var defaultSettings = { + "videoexpand": true, + "videohover": false, + "videovolume": 1.0 +}; + +// Non-persistent settings for when localStorage is absent/disabled +var tempSettings = {}; + +// Scripts obtain settings by calling this function +function setting(name) { + if (localStorage) { + if (localStorage[name] === undefined) return defaultSettings[name]; + return JSON.parse(localStorage[name]); + } else { + if (tempSettings[name] === undefined) return defaultSettings[name]; + return tempSettings[name]; + } +} + +// Settings should be changed with this function +function changeSetting(name, value) { + if (localStorage) { + localStorage[name] = JSON.stringify(value); + } else { + tempSettings[name] = value; + } +} + +// Create settings menu +var settingsMenu = document.createElement("span"); +settingsMenu.className = "settings"; +settingsMenu.innerHTML = '<span>[WebM Settings]</span>' + + '<div style="display: none; text-align: left; position: absolute; right: 0px; margin-left: -999em; margin-top: -1px; padding-top: 1px;">' + + '<label><input type="checkbox" name="videoexpand">Expand videos inline</label><br>' + + '<label><input type="checkbox" name="videohover">Play videos on hover</label><br>' + + '<label><input type="range" name="videovolume" min="0" max="1" step="0.01" style="width: 4em; height: 1ex; vertical-align: middle; margin: 0px;">Default volume</label><br>' + + '</div>'; + +function refreshSettings() { + var settingsItems = settingsMenu.getElementsByTagName("input"); + for (var i = 0; i < settingsItems.length; i++) { + var control = settingsItems[i]; + if (control.type == "checkbox") { + control.checked = setting(control.name); + } else if (control.type == "range") { + control.value = setting(control.name); + } + } +} + +function setupControl(control) { + if (control.addEventListener) control.addEventListener("change", function(e) { + if (control.type == "checkbox") { + changeSetting(control.name, control.checked); + } else if (control.type == "range") { + changeSetting(control.name, control.value); + } + }, false); +} + +refreshSettings(); +var settingsItems = settingsMenu.getElementsByTagName("input"); +for (var i = 0; i < settingsItems.length; i++) { + setupControl(settingsItems[i]); +} + +if (settingsMenu.addEventListener) { + settingsMenu.addEventListener("mouseover", function(e) { + refreshSettings(); + settingsMenu.getElementsByTagName("span")[0].style.fontWeight = "bold"; + settingsMenu.getElementsByTagName("div")[0].style.display = "block"; + }, false); + settingsMenu.addEventListener("mouseout", function(e) { + settingsMenu.getElementsByTagName("span")[0].style.fontWeight = "normal"; + settingsMenu.getElementsByTagName("div")[0].style.display = "none"; + }, false); +} |
