Revisions
-
HT-7 revised this gist
23 minutes agoAug 12, 2023 . 1 changed file with 26 additions and 17 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -1,5 +1,3 @@ // == Dependencies == // == Dependencies ==
var mediaType; // for compatibility var mediaType; // for compatibility @@ -557,6 +555,12 @@ function timeUI() { timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); addStyle("#timerUI #timerUI_bottom_gradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; left:0; bottom:0; pointer-events:none; }", timerUI.div); addStyle("#timerUI #timerUI_bottom_gradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; left:0; bottom:0; pointer-events:none; }", timerUI.div);
// play/pause symbol appendChildWithID("button","timerUI_playback_status",timerUI.div ); timerUI.status = document.getElementById("timerUI_playback_status"); timerUI.status.innerHTML="■"; addStyle("#timerUI #timerUI_playback_status { display:block; position:fixed; cursor:pointer; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div);
// progress bar // progress bar appendChildWithID("div","timerUI_progress_bar",timerUI.div ); appendChildWithID("div","timerUI_progress_bar",timerUI.div ); timerUI.bar = document.getElementById("timerUI_progress_bar"); timerUI.bar = document.getElementById("timerUI_progress_bar"); @@ -567,23 +571,14 @@ function timeUI() { timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); addStyle("#timerUI #timerUI_buffer_bar, #timerUI .timerUI_buffer_segment { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; left:0; bottom:0; opacity:0.4; } #timerUI .timerUI_buffer_segment { opacity:1; }", timerUI.div); addStyle("#timerUI #timerUI_buffer_bar, #timerUI .timerUI_buffer_segment { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; left:0; bottom:0; opacity:0.4; } #timerUI .timerUI_buffer_segment { opacity:1; }", timerUI.div);
// timer // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); appendChildWithID("button","timerUI_media_timer",timerUI.div ); timerUI.time = document.getElementById("timerUI_media_timer"); timerUI.time = document.getElementById("timerUI_media_timer"); timerUI.time.innerHTML="00:00:00"; timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #timerUI_media_timer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:"+timerUI.font_pack+"; } #timerUI #timerUI_media_timer .timer_linefeed { display:none; }", timerUI.div); addStyle("#timerUI #timerUI_media_timer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:"+timerUI.font_pack+"; } #timerUI #timerUI_media_timer .timer_linefeed { display:none; }", timerUI.div);
// progress bar placeholder – put last to be at the top in stacking context // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); @@ -594,6 +589,12 @@ function timeUI() { addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive");
// media title appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;", timerUI.div);
timerUI.domainRules(); // load domain rules after initializing timer elements timerUI.domainRules(); // load domain rules after initializing timer elements
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar // update timer during playback every fifteenth of a second and while mouse is dragging progress bar @@ -632,15 +633,15 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); timerUI.update(); timerUI.updateBufferBar(true); } } }; }; /* function dragSeekBar(m){ // currently unused m = m || window.event; m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var dragSeekBarInterval = setInterval( function() { var dragSeekBarInterval = setInterval( function() { media_element.currentTime = media_element.duration * clickPos; media_element.currentTime = media_element.duration * clickPos; timerUI.update(); timerUI.update(); if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); } */ timerUI.bar_placeholder.addEventListener("mousedown", timerUI.clickSeekBar ); timerUI.bar_placeholder.addEventListener("mousedown", timerUI.clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); @@ -684,7 +685,10 @@ timerUI.domainRules = function() { } }
// activate light mode on wikis and Dailymotion due to bright backgrounds // activate light mode on wikis and Dailymotion due to bright backgrounds if ( isDomain("wiki") || isDomain("dailymotion.com") || isDomain("ghostarchive.org") || is_archive_library() ) { timerUI.light_mode_on(); timerUI.light_mode_on(); } }
@@ -717,7 +721,7 @@ timerUI.titleDomainRules = function() { } }
// Internet Archive library only, not Wayback Machine // Internet Archive library only, not Wayback Machine if ( is_archive_library() ) { // get media title from page title before first colon // get media title from page title before first colon timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) // after last slash (additional space prevents full URL from being matched) @@ -737,6 +741,11 @@ timerUI.titleDomainRules = function() { } } }; };
function is_archive_library() { // function to check if the current page is an Archive.org library page and not the Wayback Machine return (isDomain(/^(www.)?archive.org/) && ! isDomain("web.archive.org") ); // automatically returns true if the condition is met and false otherwise } function is_WaybackEmbed() { function is_WaybackEmbed() { // checks if the current page is media embedded on the Wayback Machine, for code deduplication. // checks if the current page is media embedded on the Wayback Machine, for code deduplication. if ( isDomain("web.archive.org") || isDomain("wayback.archive.org") && document.title=="Wayback Machine" && document.getElementsByTagName("iframe")[0] ) { if ( isDomain("web.archive.org") || isDomain("wayback.archive.org") && document.title=="Wayback Machine" && document.getElementsByTagName("iframe")[0] ) { -
HT-7 revised this gist
on Jul 10Jul 10, 2023 . 1 changed file with 122 additions and 26 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -58,8 +58,10 @@ function isDomain(domain) { } }
// symbols // symbols var media_symbol = {}; media_symbol.play = "▶︎ "; // thin space for alignment media_symbol.pause="❚ ❚"; // instead of "⏸" due to Edge browser putting an immutable blue box around it. media_symbol.stop="■";
// mousedown status // mousedown status var mousedown_status; var mousedown_status; @@ -162,6 +164,18 @@ var mediafileext = { "audio":[".mp3", ".wma", ".wav", ".ogg", ".opus", ".flac", ".oga", ".wma", ".aac", ".amr", ".alac", ".m4a"] "audio":[".mp3", ".wma", ".wav", ".ogg", ".opus", ".flac", ".oga", ".wma", ".aac", ".amr", ".alac", ".m4a"] }; };
// "replaceAll()" polyfill for pre-2020 browsers // based on: https://stackoverflow.com/a/1144788
function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string }
// renamed function to prevent interference with "replaceAll()" on browsers since 2020 function replaceAll_polyfill(str, find, replacement) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replacement); }
// == Main code == // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists if (! timerUI) var timerUI = new Object({}); // create parent object if none exists
@@ -177,6 +191,7 @@ timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.default_color = "rgb(49,136,255)"; // memorize default color timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.font_pack = "din, futura, 'noto sans', 'open sans', ubuntu, 'segoe ui', verdana, tahoma, roboto, 'roboto light', arial, helvetica, 'trebuchet ms' ,'bitstream vera sans', sans-serif, consolas, monospace"; timerUI.font_pack = "din, futura, 'noto sans', 'open sans', ubuntu, 'segoe ui', verdana, tahoma, roboto, 'roboto light', arial, helvetica, 'trebuchet ms' ,'bitstream vera sans', sans-serif, consolas, monospace"; timerUI.width_breakpoint = 768; // pixels timerUI.width_breakpoint = 768; // pixels @@ -205,7 +220,7 @@ timerUI.toggle.main = function() { timerUI.div.style.display = "block"; timerUI.div.style.display = "block"; console.log("timerUI on"); console.log("timerUI on"); } } if (timerUI.on) { timerUI.on = false; return false; } else { timerUI.on = true; return false; } } else { } else { console.warn(timerUI.msg.notimer); console.warn(timerUI.msg.notimer); timeUI(); timeUI(); @@ -223,7 +238,11 @@ timerUI.toggle.buffer = function() { timerUI.buffer_bar.style.display = "block"; timerUI.buffer_bar.style.display = "block"; console.log("timerUI buffer bar on"); console.log("timerUI buffer bar on"); } } if (timerUI.buffer_on) { timerUI.buffer_on = false; return false; } else { timerUI.buffer_on = true; return true; } } else { } else { console.warn(timerUI.msg.notimer); console.warn(timerUI.msg.notimer); timeUI(); timeUI(); @@ -241,7 +260,11 @@ timerUI.toggle.title = function() { timerUI.title.style.display = "block"; timerUI.title.style.display = "block"; console.log("timerUI title on"); console.log("timerUI title on"); } } if (timerUI.title_on) { timerUI.title_on = false; return false; } else { timerUI.title_on = true; return true; } } else { } else { console.warn(timerUI.msg.notimer); console.warn(timerUI.msg.notimer); timeUI(); timeUI(); @@ -256,6 +279,8 @@ timerUI.getTitle = function() { if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; else { // skipping this whole part if no custom title is specified else { // skipping this whole part if no custom title is specified timerUI.newTitle = document.title; timerUI.newTitle = document.title; // replace underscores with spaces timerUI.newTitle = replaceAll_polyfill(timerUI.newTitle, "_"," "); timerUI.titleDomainRules(); timerUI.titleDomainRules(); } } if (media_element) { if (media_element) { @@ -270,6 +295,7 @@ timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (! media_element.videoWidth) return "audio"; // Detects files that only contain audio, even if they have a video file extension. if (! media_element.videoWidth) return "audio"; // Detects files that only contain audio, even if they have a video file extension. if (media_element.videoWidth > 0) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected return "unknown"; // if nothing detected @@ -324,13 +350,16 @@ timerUI.update = function() { break; break; } }
if (media_element.paused) { timerUI.status.innerHTML=media_symbol.pause; } else { timerUI.status.innerHTML=media_symbol.play; } } else { timerUI.stop(); console.warn(timerUI.msg.nomedia); } }; }; timerUI.updateTitle = function() { if (timerUI.title) timerUI.title.innerHTML = timerUI.getTitle(); };
// update title on URL change // update title on URL change addEventListener('popstate', timerUI.updateTitle); addEventListener('popstate', timerUI.updateTitle); @@ -414,6 +443,12 @@ timerUI.set_buffer_segment = function(segment_number,start_pos,end_pos) {
// colors // colors timerUI.setColor = function(newColor) { timerUI.setColor = function(newColor) { if (! timerUI.bar) { /* prevent running function before timerUI is properly loaded into the DOM to prevent exception */ if (timerUI.debug_mode) console.debug("timerUI: setColor can not run before timerUI is properly loaded."); return false; } timerUI.previous_color = timerUI.color; // memorize previous setting newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor;
timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.backgroundColor=timerUI.color; @@ -423,8 +458,16 @@ timerUI.setColor = function(newColor) { timerUI.time.style.color=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; timerUI.title.style.color=timerUI.color;
// colour all buffer segments for (var count=0; count < timerUI.buffer_bar.childNodes.length; count++) { timerUI.buffer_bar.childNodes[count].style.backgroundColor=timerUI.color; } if (timerUI.debug_mode) console.debug("timerUI: color changed from "+timerUI.previous_color+" to "+timerUI.color); }; };
timerUI.setColor("default"); // prevent mixed colours if the code is run multiple times
timerUI.setGradient = function(newGradient) { timerUI.setGradient = function(newGradient) { newGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.9)" : timerUI.gradient = newGradient; newGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.9)" : timerUI.gradient = newGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; @@ -435,11 +478,55 @@ timerUI.setFont = function(newFont) { timerUI.title.style.fontFamily=newFont; timerUI.title.style.fontFamily=newFont; }; };
// light mode
timerUI.light_mode = false; // default
timerUI.light_mode_on = function() { timerUI.light_mode = true; timerUI.color_before_light_mode = timerUI.color; // improves visibility: if (timerUI.setColor) /* exists*/ { timerUI.setColor("lightblue"); } else { return false; /* error */ } if (timerUI.gradient_placeholder) /* exists*/ { timerUI.gradient_placeholder.style.backgroundColor="rgba(0, 0, 0, 0.5)"; } else { return false; /* error */ } };
timerUI.light_mode_off = function() { timerUI.light_mode = false; if (timerUI.setColor) /* exists*/ { timerUI.setColor("lightblue"); } else { return false; /* error */ } if (timerUI.gradient_placeholder) /* exists*/ { timerUI.gradient_placeholder.style.backgroundColor=""; // fall back to default } else { return false; /* error */ } };
timerUI.toggle.light_mode = function() { if ( ! timerUI.light_mode ) /* if light mode is deactivated */ { timerUI.light_mode_on(); return true; } else { timerUI.light_mode_off(); return false; } };
// "stop" icon
timerUI.stop = function() { timerUI.stop = function() { timerUI.status.innerHTML=media_symbol.stop; timerUI.bar.style.width=0; timerUI.bar.style.width=0; timerUI.buffer_bar.style.width=0; timerUI.buffer_bar.style.width=0; // appearance of stopped timer consistent with the show_remaining setting if (timerUI.show_remaining == 2) { timerUI.time.innerHTML=MStimer(undefined)+" / "+MStimer(undefined); } else { timerUI.time.innerHTML=HMStimer(undefined); } }; };
// Additional checks to ensure the player is detected // Additional checks to ensure the player is detected @@ -451,7 +538,6 @@ function timeUI() { // slightly different name to prevent naming collision with timerUI object // slightly different name to prevent naming collision with timerUI object
checkMediaType(); checkMediaType(); // add timerUI if it does not already exist // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists || timerUI.override_check ) { if ( ( ! document.getElementById("timerUI") ) && playerExists || timerUI.override_check ) {
@@ -462,30 +548,30 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); timerUI.div = document.getElementById("timerUI");
// button styling // button styling addStyle("#timerUI button { background:none; border:none; outline:none; line-height:unset; padding:0; margin:0; } #timerUI button:hover { filter: brightness(1.2); } #timerUI button:active { filter: brightness(0.6); }", timerUI.div); // to suppress button background and border on earlier browser versions // to suppress button background and border on earlier browser versions timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector
// background gradient // background gradient appendChildWithID("div","timerUI_bottom_gradient",timerUI.div ); appendChildWithID("div","timerUI_bottom_gradient",timerUI.div ); timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); addStyle("#timerUI #timerUI_bottom_gradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; left:0; bottom:0; pointer-events:none; }", timerUI.div);
// progress bar // progress bar appendChildWithID("div","timerUI_progress_bar",timerUI.div ); appendChildWithID("div","timerUI_progress_bar",timerUI.div ); timerUI.bar = document.getElementById("timerUI_progress_bar"); timerUI.bar = document.getElementById("timerUI_progress_bar"); addStyle("#timerUI #timerUI_progress_bar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; left:0; bottom:0; }", timerUI.div);
// buffer bar // buffer bar appendChildWithID("div","timerUI_buffer_bar",timerUI.div ); appendChildWithID("div","timerUI_buffer_bar",timerUI.div ); timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); addStyle("#timerUI #timerUI_buffer_bar, #timerUI .timerUI_buffer_segment { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; left:0; bottom:0; opacity:0.4; } #timerUI .timerUI_buffer_segment { opacity:1; }", timerUI.div);
// media title // media title appendChildWithID("div","timerUI_media_title",timerUI.div ); appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;", timerUI.div);
// timer // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); appendChildWithID("button","timerUI_media_timer",timerUI.div ); @@ -502,12 +588,13 @@ function timeUI() { // progress bar placeholder – put last to be at the top in stacking context // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("timerUI_progress_placeholder"); timerUI.bar_placeholder = document.getElementById("timerUI_progress_placeholder"); addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; left:0; bottom:0; opacity:0.2; }", timerUI.div);
// responsive - at bottom to be able to override CSS properties without !important flag. // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive");
timerUI.domainRules(); // load domain rules after initializing timer elements
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar // update timer during playback every fifteenth of a second and while mouse is dragging progress bar timerUI.interval.update = setInterval( timerUI.interval.update = setInterval( @@ -535,7 +622,7 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); timerUI.update(); timerUI.updateBufferBar(true); }; };
// clickable progress bar (experimental) - "clickPos" has no "timerUI." notation because it is inside the main function. timerUI.clickSeekBar = function(m){ timerUI.clickSeekBar = function(m){ if (media_element) { if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; @@ -596,6 +683,11 @@ timerUI.domainRules = function() { customTitleElement = document.getElementById("media-title"); // for unlisted videos (Dailymotion only displays the video title in the HTML page title for public videos) customTitleElement = document.getElementById("media-title"); // for unlisted videos (Dailymotion only displays the video title in the HTML page title for public videos) } }
// activate light mode on wikis and Dailymotion due to bright backgrounds if ( isDomain("wiki") || isDomain("dailymotion.com") || isDomain("ghostarchive.org") ) { timerUI.light_mode_on(); }
// media embedded on Wayback Machine // media embedded on Wayback Machine if ( is_WaybackEmbed() ) { if ( is_WaybackEmbed() ) { tmp = document.getElementsByTagName("iframe")[0]; // iframe in temporary variable to deduplicate code tmp = document.getElementsByTagName("iframe")[0]; // iframe in temporary variable to deduplicate code @@ -618,19 +710,23 @@ timerUI.titleDomainRules = function() { // Match both normal dash "-" and ndash "–", since the German-language wikis use the latter. // Match both normal dash "-" and ndash "–", since the German-language wikis use the latter. timerUI.newTitle = decodeURI(timerUI.newTitle.substring(0,timerUI.newTitle.search(/(-|–)(?:.(?!(-|–)))+$/)-1 ) ); timerUI.newTitle = decodeURI(timerUI.newTitle.substring(0,timerUI.newTitle.search(/(-|–)(?:.(?!(-|–)))+$/)-1 ) ); } } // remove "File:" prefix on wikis and if ( isDomain("wiki") ) { if ( isDomain("wiki") ) { if (document.title.search(/^File:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(5); if (document.title.search(/^File:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(5); if (document.title.search(/^Datei:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(6); if (document.title.search(/^Datei:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(6); } }
// Internet Archive library only, not Wayback Machine // Internet Archive library only, not Wayback Machine if ( isDomain(/^(www.)?archive.org/) && ! isDomain("web.archive.org") ) { // get media title from page title before first colon // get media title from page title before first colon timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) // after last slash (additional space prevents full URL from being matched) timerUI.archive_org_title = document.title.substring(0,document.title.search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); if (timerUI.archive_org_title.length > 0) /* only append " - " if a title exists. */ { /* only append " - " if a title exists. */ if (timerUI.newTitle != "") { timerUI.newTitle += " - "; } timerUI.newTitle += timerUI.archive_org_title; } // trim after second-last colon, -1 to remove space at end // trim after second-last colon, -1 to remove space at end
timerUI.newTitle=decodeURI(timerUI.newTitle); // prevent spaces from turning into "%20". timerUI.newTitle=decodeURI(timerUI.newTitle); // prevent spaces from turning into "%20". @@ -655,4 +751,4 @@ function is_WaybackEmbed() {
// == Master function == // == Master function == timeUI(); -
HT-7 revised this gist
on Mar 14Mar 14, 2023 . 1 changed file with 1 addition and 3 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -655,6 +655,4 @@ function is_WaybackEmbed() {
// == Master function == // == Master function == timeUI(); -
HT-7 revised this gist
on Mar 14Mar 14, 2023 . 1 changed file with 11 additions and 8 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -158,8 +158,8 @@ function togglePlay(media_element) {
// media file extension list // media file extension list var mediafileext = { var mediafileext = { "video":[".mp4", ".mpg", ".mpeg", ".mts", ".mt2s", ".m4v", ".ts", ".ogv", ".wmv", ".3gp", ".3gpp", ".webm"], "audio":[".mp3", ".wma", ".wav", ".ogg", ".opus", ".flac", ".oga", ".wma", ".aac", ".amr", ".alac", ".m4a"] }; };
// == Main code == // == Main code == @@ -260,7 +260,7 @@ timerUI.getTitle = function() { } } if (media_element) { if (media_element) { timerUI.updateFileIcon(); timerUI.updateFileIcon(); return timerUI.file_icon+" "+timerUI.newTitle; } else { } else { return "TimerUI – designed for home cinemas"; return "TimerUI – designed for home cinemas"; } } @@ -269,17 +269,18 @@ timerUI.getTitle = function() { timerUI.guessMediaType = function() { timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (! media_element.videoWidth) return "audio"; // Detects files that only contain audio, even if they have a video file extension. if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected return "unknown"; // if nothing detected }; };
timerUI.updateFileIcon = function() { timerUI.updateFileIcon = function() { timerUI.file_icon = timerUI.guessMediaType(); switch(timerUI.file_icon) { case "video": timerUI.file_icon = "🎞️"; break; case "audio": timerUI.file_icon = "♫"; break; case "unknown": timerUI.file_icon = "📄"; break; } } }; };
@@ -655,3 +656,5 @@ function is_WaybackEmbed() {
// == Master function == // == Master function == timeUI(); timeUI();
} -
HT-7 revised this gist
on Nov 5, 2022Nov 5, 2022 . 1 changed file with 71 additions and 31 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -6,13 +6,18 @@ var mediaType; // for compatibility var playerExists = false; // is set to true below if player exists var playerExists = false; // is set to true below if player exists var checkMediaType_enabled = true; // for debugging purposes var checkMediaType_enabled = true; // for debugging purposes var media_element = {}; // declaring as object var media_element = {}; // declaring as object var tmp="",count=0; // initiating temporary variables used inside functions and loops
function checkMediaType() { function checkMediaType() { // checks whether it is a video or an audio tag // checks whether it is a video or an audio tag if ( checkMediaType_enabled ) { if ( checkMediaType_enabled ) { var mediaTypeBeforeCheck = mediaType; var mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = true; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = true; mediaType = "audio"; } var mediaTypeAfterCheck = mediaType; var mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. // Only show media type in console if it has changed. @@ -173,7 +178,7 @@ timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.font_pack = "din, futura, 'noto sans', 'open sans', ubuntu, 'segoe ui', verdana, tahoma, roboto, 'roboto light', arial, helvetica, 'trebuchet ms' ,'bitstream vera sans', sans-serif, consolas, monospace"; timerUI.width_breakpoint = 768; // pixels timerUI.width_breakpoint = 768; // pixels
// console notifications and warnings (possibly to be expanded) // console notifications and warnings (possibly to be expanded) @@ -244,7 +249,10 @@ timerUI.toggle.title = function() { }; };
timerUI.getTitle = function() { timerUI.getTitle = function() { if (! timerUI.domainRules_checked) /* only check domain rules once */ { timerUI.domainRules(); timerUI.domainRules(); timerUI.domainRules_checked = true; } if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; else { // skipping this whole part if no custom title is specified else { // skipping this whole part if no custom title is specified timerUI.newTitle = document.title; timerUI.newTitle = document.title; @@ -373,15 +381,16 @@ timerUI.update_multi_buffer = function() { timerUI.generate_buffer_segments = function() { timerUI.generate_buffer_segments = function() { timerUI.buffer_bar.innerHTML=""; // reset to re-generate segments timerUI.buffer_bar.innerHTML=""; // reset to re-generate segments for (count=0; count < media_element.buffered.length; count++) { for (count=0; count < media_element.buffered.length; count++) { timerUI.append_buffer_segment( timerUI.get_buffer_range(count).start_pos, timerUI.get_buffer_range(count).end_pos ); } } timerUI.select_segments = timerUI.buffer_bar.getElementsByClassName("timerUI_buffer_segment"); timerUI.select_segments = timerUI.buffer_bar.getElementsByClassName("timerUI_buffer_segment"); timerUI.segment_count = timerUI.select_segments.length; timerUI.segment_count = timerUI.select_segments.length; }; };
timerUI.append_buffer_segment = function(start_pos,end_pos) { timerUI.append_buffer_segment = function(start_pos,end_pos) { timerUI.buffer_bar.appendChild(document.createElement("div") ); timerUI.buffer_bar.appendChild(document.createElement("div") ); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.style="left:"+start_pos+"%;width:"+(end_pos-start_pos)+"%;background-color:"+timerUI.color+";"; timerUI.buffer_bar.lastElementChild.style="left:"+start_pos+"%;width:"+(end_pos-start_pos)+"%;background-color:"+timerUI.color+";"; @@ -580,38 +589,69 @@ function timeUI() { timerUI.domainRules = function() { timerUI.domainRules = function() { if (isDomain("dailymotion.com") && document.location.pathname.search(/^\/embed\//) < 0 ) { if (isDomain("dailymotion.com") && document.location.pathname.search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. // Dailymotion watch page, excluding embed page. customMediaElement( document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0] ); customTitleElement = document.getElementById("media-title"); // for unlisted videos (Dailymotion only displays the video title in the HTML page title for public videos) } }
// media embedded on Wayback Machine if ( is_WaybackEmbed() ) { tmp = document.getElementsByTagName("iframe")[0]; // iframe in temporary variable to deduplicate code customMediaElement( tmp.contentWindow.document.getElementsByTagName("video")[0] ); // dark background for improved video visibility tmp.contentWindow.document.body.style.backgroundColor="#222"; } }; };
timerUI.titleDomainRules = function() { timerUI.titleDomainRules = function() { // custom domain rules for title // custom domain rules for title if ( isDomain("youtube.com") || isDomain("dailymotion.com") || isDomain("wikimedia.org") || isDomain("wikipedia.org") || isDomain("wikiversity.org") || isDomain("wikibooks.org") || isDomain("mediawiki.org") ) { // negative lookahead regular expression – trim after last dash // Match both normal dash "-" and ndash "–", since the German-language wikis use the latter. timerUI.newTitle = decodeURI(timerUI.newTitle.substring(0,timerUI.newTitle.search(/(-|–)(?:.(?!(-|–)))+$/)-1 ) ); } // remove "File:" prefix on wikis if ( isDomain("wiki") ) { if (document.title.search(/^File:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(5); if (document.title.search(/^Datei:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(6); }
// Internet Archive library only, not Wayback Machine if ( isDomain("archive.org") && ! isDomain("web.archive.org") ) { // get media title from page title before first colon timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) if (timerUI.newTitle != "") { timerUI.newTitle += " - "; } timerUI.newTitle += document.title.substring(0,document.title.search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); // trim after second-last colon, -1 to remove space at end
timerUI.newTitle=decodeURI(timerUI.newTitle); // prevent spaces from turning into "%20". } if ( is_WaybackEmbed() ) { // Already generated by the browser inside the iframe. How convenient. Otherwise, a regular expression that matches the part after the last slash in the URL, and a decodeURI would have to be used. timerUI.newTitle = tmp.contentWindow.document.title; } }; };
function is_WaybackEmbed() { // checks if the current page is media embedded on the Wayback Machine, for code deduplication. if ( isDomain("web.archive.org") || isDomain("wayback.archive.org") && document.title=="Wayback Machine" && document.getElementsByTagName("iframe")[0] ) { // separate check for ID of iframe to avoid reference error if (document.getElementsByTagName("iframe")[0].id=="playback") { return true; } } else { return false; } }
// == Master function == // == Master function == timeUI(); -
HT-7 revised this gist
on Oct 9, 2022Oct 9, 2022 . 1 changed file with 32 additions and 54 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -37,11 +37,11 @@ function checkFileExtension(ext) { if (typeof(ext) == "string") { if (typeof(ext) == "string") { ext = ext.toLowerCase(); // case-insensitive ext = ext.toLowerCase(); // case-insensitive // string // string if (document.location.href.search(new RegExp(ext+"$", "i")) > -1) return true; else return false; } else if (typeof(ext) == "object") { } else if (typeof(ext) == "object") { // array – check against multiple strings // array – check against multiple strings for (var count=0; count < ext.length; count++) { for (var count=0; count < ext.length; count++) { if (document.location.href.search(new RegExp(ext[count]+"$", "i")) > -1) return true; if (count == ext.length-1) return false; // if no matches after going through them all if (count == ext.length-1) return false; // if no matches after going through them all } } } } @@ -167,10 +167,8 @@ timerUI.override_check = false; timerUI.on = true; timerUI.on = true; timerUI.buffer_on = true; timerUI.buffer_on = true; timerUI.multiBuffer = true; // multiple buffer segments timerUI.multiBuffer = true; // multiple buffer segments timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. @@ -182,7 +180,7 @@ timerUI.width_breakpoint = 768; // pixels timerUI.msg = { timerUI.msg = { "notimer": "timerUI: No timer found; checking for media element again. Please try again.", "notimer": "timerUI: No timer found; checking for media element again. Please try again.", "nomedia": "timerUI: no media element found on page. Stopping." "nomedia": "timerUI: no media element found on page. Stopping." };
// text containers (no const for compatibility) // text containers (no const for compatibility) var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_linefeed = "<span class=timer_linefeed><br /></span>"; @@ -191,6 +189,7 @@ var timer_slash = " <span class=timer_slash>/</span> "; // functions // functions timerUI.toggle = {}; timerUI.toggle = {}; timerUI.toggle.main = function() { timerUI.toggle.main = function() { // show and hide if (timerUI.div) { if (timerUI.div) { timerUI.update(); timerUI.update(); if (timerUI.on) { if (timerUI.on) { @@ -257,15 +256,15 @@ timerUI.getTitle = function() { } else { } else { return "TimerUI – designed for home cinemas"; return "TimerUI – designed for home cinemas"; } } };
timerUI.guessMediaType = function() { timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.search(/^\/video\//) > -1) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected return "unknown"; // if nothing detected };
timerUI.updateFileIcon = function() { timerUI.updateFileIcon = function() { timerUI.fileIcon = timerUI.guessMediaType(); timerUI.fileIcon = timerUI.guessMediaType(); @@ -274,15 +273,15 @@ timerUI.updateFileIcon = function() { case "audio": timerUI.fileIcon = "♫"; break; case "audio": timerUI.fileIcon = "♫"; break; case "unknown": timerUI.fileIcon = "📄"; break; case "unknown": timerUI.fileIcon = "📄"; break; } } };
timerUI.adaptTitleWidth = function() { timerUI.adaptTitleWidth = function() { if (media_element.duration > 3600 && timerUI.show_remaining == 2 && window.innerWidth > timerUI.width_breakpoint) if (media_element.duration > 3600 && timerUI.show_remaining == 2 && window.innerWidth > timerUI.width_breakpoint) timerUI.title.style.maxWidth = "calc(100% - 670px)"; timerUI.title.style.maxWidth = "calc(100% - 670px)"; else else timerUI.title.style.maxWidth = "calc(100% - 400px)"; timerUI.title.style.maxWidth = "calc(100% - 400px)"; };
window.addEventListener('resize', function() { window.addEventListener('resize', function() { if (window.innerWidth < timerUI.width_breakpoint) timerUI.title.removeAttribute("style"); if (window.innerWidth < timerUI.width_breakpoint) timerUI.title.removeAttribute("style"); @@ -320,17 +319,9 @@ timerUI.update = function() { timerUI.status.innerHTML=symbol_play timerUI.status.innerHTML=symbol_play : timerUI.status.innerHTML=symbol_pause; : timerUI.status.innerHTML=symbol_pause;
} else { timerUI.stop(); console.warn(timerUI.msg.nomedia); } }; }; timerUI.updateTitle = function() { if (timerUI.title) timerUI.title.innerHTML = timerUI.getTitle(); };
// update title on URL change // update title on URL change addEventListener('popstate', timerUI.updateTitle); addEventListener('popstate', timerUI.updateTitle); @@ -388,18 +379,19 @@ timerUI.generate_buffer_segments = function() { timerUI.segment_count = timerUI.select_segments.length; timerUI.segment_count = timerUI.select_segments.length; }; };
timerUI.append_buffer_segment = function(start_pos,end_pos) { if (!start_pos) start_pos=timerUI.get_buffer_range(segment_number).start_pos; if (!end_pos) end_pos=timerUI.get_buffer_range(segment_number).end_pos; timerUI.buffer_bar.appendChild(document.createElement("div") ); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.style="left:"+start_pos+"%;width:"+(end_pos-start_pos)+"%;background-color:"+timerUI.color+";"; }; };
timerUI.get_buffer_range = function(segment_number) { timerUI.get_buffer_range = function(segment_number) { return { start_pos: media_element.buffered.start(segment_number) / media_element.duration * 100, end_pos: media_element.buffered.end(segment_number) / media_element.duration * 100 }; // object with start and end percentages }; };
timerUI.set_buffer_segment = function(segment_number,start_pos,end_pos) { timerUI.set_buffer_segment = function(segment_number,start_pos,end_pos) { @@ -421,9 +413,6 @@ timerUI.setColor = function(newColor) { timerUI.time.style.color=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; }; };
timerUI.setGradient = function(newGradient) { timerUI.setGradient = function(newGradient) { @@ -486,7 +475,7 @@ function timeUI() { appendChildWithID("div","timerUI_media_title",timerUI.div ); appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;");
// timer // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); appendChildWithID("button","timerUI_media_timer",timerUI.div ); @@ -506,12 +495,8 @@ function timeUI() { addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div);
// responsive - at bottom to be able to override CSS properties without !important flag. // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive");
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar // update timer during playback every fifteenth of a second and while mouse is dragging progress bar @@ -540,25 +525,16 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); timerUI.update(); timerUI.updateBufferBar(true); }; };
// clickable progress bar (experimental) - no "timerUI." notation because inside main function // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ timerUI.clickSeekBar = function(m){ if (media_element) { if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; // go to beginning if clicked in first percentile if (clickPos < 0.01 ) media_element.currentTime = 0; else media_element.currentTime = media_element.duration * clickPos; timerUI.update(); timerUI.updateBufferBar(true); timerUI.update(); timerUI.updateBufferBar(true); } } }; function dragSeekBar(m){ // currently unused function dragSeekBar(m){ // currently unused m = m || window.event; m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; @@ -602,7 +578,7 @@ function timeUI() {
// == Custom domain rules == // == Custom domain rules == timerUI.domainRules = function() { timerUI.domainRules = function() { if (isDomain("dailymotion.com") && document.location.pathname.search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); customTitleElement = document.getElementById("media-title"); // for unlisted customTitleElement = document.getElementById("media-title"); // for unlisted @@ -627,11 +603,13 @@ timerUI.titleDomainRules = function() { } }
if ( isDomain("archive.org") && ! isDomain("web.archive.org") ) { if ( isDomain("archive.org") && ! isDomain("web.archive.org") ) { timerUI.newTitle = (document.location.href+"").substring((document.location.href+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) // after last slash (additional space prevents full URL from being matched) if (timerUI.newTitle != "") { timerUI.newTitle += " - "; } timerUI.newTitle += document.title.substring(0,document.title.search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); // trim after second-last colon, -1 to remove space at end // trim after second-last colon, -1 to remove space at end
decodeURI(timerUI.newTitle); // prevent spaces from turning into "%20". } } }; };
-
HT-7 revised this gist
on Jun 1, 2022Jun 1, 2022 . 1 changed file with 30 additions and 2 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -167,8 +167,10 @@ timerUI.override_check = false; timerUI.on = true; timerUI.on = true; timerUI.buffer_on = true; timerUI.buffer_on = true; timerUI.multiBuffer = true; // multiple buffer segments timerUI.multiBuffer = true; // multiple buffer segments timerUI.left_mode = 1; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.interval = {}; timerUI.css = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. @@ -320,7 +322,15 @@ timerUI.update = function() {
} else { timerUI.stop(); console.warn(timerUI.msg.nomedia) } } else { timerUI.stop(); console.warn(timerUI.msg.nomedia) } }; };
timerUI.leftPlaybackControls
timerUI.updateTitle = function() { if (timerUI.title) { switch(timerUI.left_mode) { case 1: timerUI.title.innerHTML = timerUI.getTitle(); case 2: timerUI.leftPlaybackControls(); case 3: timerUI.left_hidden(); } }
// update title on URL change // update title on URL change addEventListener('popstate', timerUI.updateTitle); addEventListener('popstate', timerUI.updateTitle); @@ -411,6 +421,9 @@ timerUI.setColor = function(newColor) { timerUI.time.style.color=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; timerUI.title.style.color=timerUI.color;
// additional colors timerUI.css.colors.innerHTML = "#timerUI .timerUI_buffer_segment { background-color:"+timerUI.color+"; }"; }; };
timerUI.setGradient = function(newGradient) { timerUI.setGradient = function(newGradient) { @@ -493,8 +506,12 @@ function timeUI() { addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div);
// responsive - at bottom to be able to override CSS properties without !important flag. // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%; } } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.css.responsive=timerUI.div.lastElementChild;
appendChildWithID("style","timerUI_colors",timerUI.div); timerUI.css.colors=document.getElementById("timerUI_colors");
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar // update timer during playback every fifteenth of a second and while mouse is dragging progress bar @@ -523,6 +540,17 @@ function timeUI() { timerUI.update(); timerUI.updateBufferBar(true); timerUI.update(); timerUI.updateBufferBar(true); }; };
// toggle between elapsed, remaining, and elapsed/total time timerUI.title.onclick = function() { switch(timerUI.left_mode) { case 1: timerUI.left_mode = 2; break; case 2: timerUI.left_mode = 3; break; case 3: timerUI.left_mode = 1; break; } timerUI.update(); timerUI.updateBufferBar(true); };
// clickable progress bar (experimental) - no "timerUI." notation because inside main function // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ timerUI.clickSeekBar = function(m){ if (media_element) { if (media_element) { -
HT-7 revised this gist
on Jun 1, 2022Jun 1, 2022 . 1 changed file with 113 additions and 46 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -1,4 +1,4 @@ // TimerUI – for home cinemas
// == Dependencies == // == Dependencies ==
@@ -40,9 +40,9 @@ function checkFileExtension(ext) { if (document.location.toString().search(new RegExp(ext+"$", "i")) > -1) return true; else return false; if (document.location.toString().search(new RegExp(ext+"$", "i")) > -1) return true; else return false; } else if (typeof(ext) == "object") { } else if (typeof(ext) == "object") { // array – check against multiple strings // array – check against multiple strings for (var count=0; count < ext.length; count++) { if (document.location.toString().search(new RegExp(ext[count]+"$", "i")) > -1) return true; if (count == ext.length-1) return false; // if no matches after going through them all } } } } } } @@ -162,8 +162,11 @@ if (! timerUI) var timerUI = new Object({}); // create parent object if none exi
// default system variables // default system variables timerUI.debug_mode = false; timerUI.debug_mode = false; timerUI.override_check = false;
timerUI.on = true; timerUI.on = true; timerUI.buffer_on = true; timerUI.buffer_on = true; timerUI.multiBuffer = true; // multiple buffer segments timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. @@ -184,7 +187,8 @@ var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; var timer_slash = " <span class=timer_slash>/</span> ";
// functions // functions timerUI.toggle = {}; timerUI.toggle.main = function() { if (timerUI.div) { if (timerUI.div) { timerUI.update(); timerUI.update(); if (timerUI.on) { if (timerUI.on) { @@ -202,9 +206,9 @@ timerUI.toggle = function() { } } }; };
timerUI.toggle.buffer = function() { if (timerUI.div) { if (timerUI.div) { timerUI.update(); timerUI.updateBufferBar(true); if (timerUI.buffer_on) { if (timerUI.buffer_on) { timerUI.buffer_bar.style.display = "none"; timerUI.buffer_bar.style.display = "none"; console.log("timerUI buffer bar off"); console.log("timerUI buffer bar off"); @@ -220,9 +224,9 @@ timerUI.toggleBuffer = function() { } } }; };
timerUI.toggle.title = function() { if (timerUI.div) { if (timerUI.div) { timerUI.update(); timerUI.updateBufferBar(true); if (timerUI.title_on) { if (timerUI.title_on) { timerUI.title.style.display = "none"; timerUI.title.style.display = "none"; console.log("timerUI title off"); console.log("timerUI title off"); @@ -245,8 +249,12 @@ timerUI.getTitle = function() { timerUI.newTitle = document.title; timerUI.newTitle = document.title; timerUI.titleDomainRules(); timerUI.titleDomainRules(); } } if (media_element) { timerUI.updateFileIcon(); return timerUI.fileIcon+" "+timerUI.newTitle; } else { return "TimerUI – designed for home cinemas"; } } }
timerUI.guessMediaType = function() { timerUI.guessMediaType = function() { @@ -281,10 +289,8 @@ window.addEventListener('resize', function() { timerUI.update = function() { timerUI.update = function() { if (media_element) { if (media_element) { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%";
// buffer bar update formerly located here; removed from the scope of this function
switch(timerUI.show_remaining) { switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" @@ -322,19 +328,79 @@ addEventListener('popstate', timerUI.updateTitle); // update title fallback // update title fallback timerUI.interval.updateTitle = setInterval(timerUI.updateTitle, 2000); timerUI.interval.updateTitle = setInterval(timerUI.updateTitle, 2000);
// buffer bar timerUI.updateBufferBar = function(override_paused) { if (media_element && timerUI.buffer_on && (!media_element.paused || override_paused) ) { timerUI.multiBuffer ? timerUI.update_multi_buffer() : timerUI.single_segment_buffer(); } };
// single-segment buffer bar timerUI.single_segment_buffer = function() { if (timerUI.buffer_bar.innerHTML!="") { timerUI.buffer_bar.style=""; timerUI.buffer_bar.innerHTML=""; } // reset after switching from multi-segment buffer bar // find out first buffer segment after current playback position media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; // media_element.buffered.length is zero until player is initialized // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if ( timerUI.buffer_segment > 0) { while (media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime && timerUI.buffer_segment > 1 ) { while (media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime && timerUI.buffer_segment > 1 ) { timerUI.update_single_buffer(); timerUI.buffer_segment-- ; timerUI.buffer_segment-- ; } } } } }; };
timerUI.update_single_buffer = function() { if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" timerUI.buffer_bar.style.width=media_element.buffered.end(timerUI.buffer_segment) / media_element.duration * 100 + "%"; } else { timerUI.buffer_bar.style.width="0%"; } };
// multi-segment buffer bar – highlight all buffered parts timerUI.update_multi_buffer = function() { if (timerUI.buffer_bar.style.length < 1) { timerUI.buffer_bar.style.width="100%"; timerUI.buffer_bar.style.backgroundColor="rgba(0,0,0,0)"; } if (media_element.buffered.length > 0) { timerUI.generate_buffer_segments(); } else { timerUI.buffer_bar.style.width="0%"; } };
timerUI.generate_buffer_segments = function() { timerUI.buffer_bar.innerHTML=""; // reset to re-generate segments for (count=0; count < media_element.buffered.length; count++) { timerUI.append_buffer_segment(timerUI.get_buffer_range(count) ); } timerUI.select_segments = timerUI.buffer_bar.getElementsByClassName("timerUI_buffer_segment"); timerUI.segment_count = timerUI.select_segments.length; };
timerUI.append_buffer_segment = function([start_pos,end_pos]) { // array function timerUI.buffer_bar.appendChild(document.createElement("div")); timerUI.buffer_bar.lastElementChild.classList.add("timerUI_buffer_segment"); timerUI.buffer_bar.lastElementChild.style="left:"+start_pos+"%;width:"+(end_pos-start_pos)+"%;"; };
timerUI.get_buffer_range = function(segment_number) { return [ media_element.buffered.start(segment_number) / media_element.duration * 100, media_element.buffered.end(segment_number) / media_element.duration * 100 ]; // array with start and end percentages };
timerUI.set_buffer_segment = function(segment_number,start_pos,end_pos) { var selection=timerUI.buffer_bar.getElementsByClassName("timerUI_buffer_segment"); selection[segment_number].style.left = start_pos / media_element.duration * 100 + "%"; selection[segment_number].style.width = (end_pos-start_pos) / media_element.duration * 100 + "%"; };
// colors timerUI.setColor = function(newColor) { timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor;
@@ -375,7 +441,7 @@ function timeUI() { checkMediaType(); checkMediaType(); timerUI.domainRules(); // load domain rules timerUI.domainRules(); // load domain rules // add timerUI if it does not already exist // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists || timerUI.override_check ) {
// Adding elements // Adding elements
@@ -384,50 +450,50 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); timerUI.div = document.getElementById("timerUI");
// button styling // button styling addStyle("#timerUI button { background:none; border:none; outline:none; line-height:unset; } #timerUI button:hover { filter: brightness(1.2); } #timerUI button:active { filter: brightness(0.6); }", timerUI.div); // to suppress button background and border on earlier browser versions // to suppress button background and border on earlier browser versions timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector
// background gradient // background gradient appendChildWithID("div","timerUI_bottom_gradient",timerUI.div ); timerUI.gradient_placeholder = document.getElementById("timerUI_bottom_gradient"); addStyle("#timerUI #timerUI_bottom_gradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; bottom:0; pointer-events:none; }", timerUI.div);
// progress bar // progress bar appendChildWithID("div","timerUI_progress_bar",timerUI.div ); timerUI.bar = document.getElementById("timerUI_progress_bar"); addStyle("#timerUI #timerUI_progress_bar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div);
// buffer bar // buffer bar appendChildWithID("div","timerUI_buffer_bar",timerUI.div ); timerUI.buffer_bar = document.getElementById("timerUI_buffer_bar"); addStyle("#timerUI #timerUI_buffer_bar, #timerUI .timerUI_buffer_segment { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; } #timerUI .timerUI_buffer_segment { opacity:1; }", timerUI.div);
// media title // media title appendChildWithID("div","timerUI_media_title",timerUI.div ); timerUI.title = document.getElementById("timerUI_media_title"); timerUI.title.innerHTML = timerUI.getTitle(); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #timerUI_media_title { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;")
// timer // timer appendChildWithID("button","timerUI_media_timer",timerUI.div ); timerUI.time = document.getElementById("timerUI_media_timer"); timerUI.time.innerHTML="00:00:00"; timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #timerUI_media_timer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:"+timerUI.font_pack+"; } #timerUI #timerUI_media_timer .timer_linefeed { display:none; }", timerUI.div);
// play/pause symbol // play/pause symbol appendChildWithID("button","timerUI_playback_status",timerUI.div ); timerUI.status = document.getElementById("timerUI_playback_status"); timerUI.status.innerHTML="■"; timerUI.status.innerHTML="■"; addStyle("#timerUI #timerUI_playback_status { display:block; position:fixed; cursor:pointer; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div);
// progress bar placeholder – put last to be at the top in stacking context // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","timerUI_progress_placeholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("timerUI_progress_placeholder"); addStyle("#timerUI #timerUI_progress_placeholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div);
// responsive - at bottom to be able to override CSS properties without !important flag. // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_media_timer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #timerUI_playback_status { bottom:10pt; } } @media (max-width:500px) { #timerUI #timerUI_media_timer .timer_linefeed { display:inline; } #timerUI #timerUI_media_timer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #timerUI_buffer_bar { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #timerUI_buffer_bar { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive");
@@ -440,11 +506,11 @@ function timeUI() { ); );
// Longer interval for buffer bar to minimize CPU usage // Longer interval for buffer bar to minimize CPU usage timerUI.interval.buffer = setInterval(timerUI.updateBufferBar, 1000);
// play and pause toggle // play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUI.update(); timerUI.updateBufferBar(true); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay();
// toggle between elapsed, remaining, and elapsed/total time // toggle between elapsed, remaining, and elapsed/total time @@ -454,14 +520,15 @@ function timeUI() { case 1: timerUI.show_remaining = 2; timerUI.adaptTitleWidth(); break; case 1: timerUI.show_remaining = 2; timerUI.adaptTitleWidth(); break; case 2: timerUI.show_remaining = 0; timerUI.adaptTitleWidth(); break; case 2: timerUI.show_remaining = 0; timerUI.adaptTitleWidth(); break; } } timerUI.update(); timerUI.updateBufferBar(true); }; };
// clickable progress bar (experimental) - no "timerUI." notation because inside main function // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ timerUI.clickSeekBar = function(m){ if (media_element) { if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; media_element.currentTime = media_element.duration * clickPos; timerUI.update(); timerUI.updateBufferBar(true); } } } } function dragSeekBar(m){ // currently unused function dragSeekBar(m){ // currently unused -
HT-7 revised this gist
on May 24, 2022May 24, 2022 . 1 changed file with 223 additions and 69 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -28,8 +28,28 @@ function customMediaElement(custom_media_element) { if (custom_media_element) { if (custom_media_element) { playerExists = true; playerExists = true; media_element = custom_media_element; media_element = custom_media_element; console.log("customMediaElement: Custom media element set. Reset using checkMediaType_enabled=true."); } else { console.error("customMediaElement: No such media element found."); } } var customTitleElement;
function checkFileExtension(ext) { if (typeof(ext) == "string") { ext = ext.toLowerCase(); // case-insensitive // string if (document.location.toString().search(new RegExp(ext+"$", "i")) > -1) return true; else return false; } else if (typeof(ext) == "object") { // array – check against multiple strings for (var a=0; a < ext.length; a++) { if (document.location.toString().search(new RegExp(ext[a]+"$", "i")) > -1) return true; if (a == ext.length-1) return false; // if no matches after going through them all } } }
function isDomain(domain) { // Using .search() instead of .includes() to improve browser compatibility. if (window.location.hostname.search(domain) >= 0) return true; else return false; } }
// symbols // symbols @@ -55,29 +75,27 @@ function addStyle(new_style,parent_element) { } }
// time variables // time variables var media_time = {};
// HH:MM:SS timer // HH:MM:SS timer function HMStimer_core(seconds) { function HMStimer_core(seconds) {
// hours // hours media_time.HH = Math.floor( seconds/3600 ); // leading zero // leading zero if ( seconds < 36000 ) media_time.HH = "0" + media_time.HH;
// minutes // minutes media_time.MM = Math.floor( seconds/60%60 ); // leading zero // leading zero if ( seconds%3600 < 600 ) media_time.MM = "0" + media_time.MM;
// seconds // seconds media_time.SS = Math.floor( seconds%60 ); // leading zero // leading zero if ( seconds%60 < 10 ) media_time.SS = "0" + media_time.SS;
return media_time.HH+":"+media_time.MM+":"+media_time.SS; } }
function HMStimer(seconds) { function HMStimer(seconds) { @@ -95,16 +113,16 @@ function HMStimer(seconds) { function MStimer_core(seconds) { function MStimer_core(seconds) {
// minutes // minutes media_time.MM = Math.floor( seconds/60 ); // leading zero // leading zero if ( seconds%3600 < 600 ) media_time.MM = "0" + media_time.MM;
// seconds // seconds media_time.SS = Math.floor( seconds%60 ); // leading zero // leading zero if ( seconds%60 < 10 ) media_time.SS = "0" + media_time.SS;
return media_time.MM+":"+media_time.SS; } }
function MStimer(seconds) { function MStimer(seconds) { @@ -128,23 +146,44 @@ Object.prototype.togglePlay = function togglePlay() {
// new function without object prototype for compatibility // new function without object prototype for compatibility function togglePlay(media_element) { function togglePlay(media_element) { if (media_element) { // validate media element first to avoid errors media_element.paused ? media_element.play() : media_element.pause(); } } }
// media file extension list var mediafileext = { "video":[".mp4",".mpg",".mpeg",".mts",".mt2s",".m4v",".ts",".ogv",".wmv",".3gp",".3gpp"], "audio":[".mp3",".wma",".wav",".ogg",".opus",".flac",".oga",".wma",".aac",".amr",".alac",".m4a"] };
// == Main code == // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists if (! timerUI) var timerUI = new Object({}); // create parent object if none exists
// default system variables timerUI.debug_mode = false; timerUI.on = true; timerUI.buffer_on = true; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.interval = {}; timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.9)"; // using RGBA instead of hexadecimal for compatibility. timerUI.font_pack = "din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace"; timerUI.width_breakpoint = 768; // pixels
// console notifications and warnings (possibly to be expanded) timerUI.msg = { "notimer": "timerUI: No timer found; checking for media element again. Please try again.", "nomedia": "timerUI: no media element found on page. Stopping." }
// text containers (no const for compatibility) var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> ";
// functions timerUI.toggle = function() { timerUI.toggle = function() { if (timerUI.div) { if (timerUI.div) { timerUI.update(); timerUI.update(); @@ -158,7 +197,7 @@ timerUI.toggle = function() { } } timerUI.on ? timerUI.on = false : timerUI.on = true; timerUI.on ? timerUI.on = false : timerUI.on = true; } else { } else { console.warn(timerUI.msg.notimer); timeUI(); timeUI(); } } }; }; @@ -176,14 +215,71 @@ timerUI.toggleBuffer = function() { } } timerUI.buffer_on ? timerUI.buffer_on = false : timerUI.buffer_on = true; timerUI.buffer_on ? timerUI.buffer_on = false : timerUI.buffer_on = true; } else { } else { console.warn(timerUI.msg.notimer); timeUI(); timeUI(); } } }; };
timerUI.toggleTitle = function() { if (timerUI.div) { timerUI.update(); if (timerUI.title_on) { timerUI.title.style.display = "none"; console.log("timerUI title off"); } if (! timerUI.title_on ) { timerUI.title.style.display = "block"; console.log("timerUI title on"); } timerUI.title_on ? timerUI.title_on = false : timerUI.title_on = true; } else { console.warn(timerUI.msg.notimer); timeUI(); } };
timerUI.getTitle = function() { timerUI.domainRules(); if (customTitleElement) timerUI.newTitle = customTitleElement.innerHTML; else { // skipping this whole part if no custom title is specified timerUI.newTitle = document.title; timerUI.titleDomainRules(); } timerUI.updateFileIcon(); return timerUI.fileIcon+" "+timerUI.newTitle; }
timerUI.guessMediaType = function() { if (isDomain("youtube.com") || isDomain("dailymotion.com") ) return "video"; if (document.location.pathname.toString().search(/^\/video\//) > -1) return "video"; if (checkFileExtension(mediafileext.video) ) return "video"; if (checkFileExtension(mediafileext.audio) ) return "audio"; return "unknown"; // if nothing detected }
timerUI.updateFileIcon = function() { timerUI.fileIcon = timerUI.guessMediaType(); switch(timerUI.fileIcon) { case "video": timerUI.fileIcon = "🎞️"; break; case "audio": timerUI.fileIcon = "♫"; break; case "unknown": timerUI.fileIcon = "📄"; break; } }
timerUI.adaptTitleWidth = function() { if (media_element.duration > 3600 && timerUI.show_remaining == 2 && window.innerWidth > timerUI.width_breakpoint) timerUI.title.style.maxWidth = "calc(100% - 670px)"; else timerUI.title.style.maxWidth = "calc(100% - 400px)"; }
window.addEventListener('resize', function() { if (window.innerWidth < timerUI.width_breakpoint) timerUI.title.removeAttribute("style"); } );
timerUI.update = function() { timerUI.update = function() { if (media_element) { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; if (media_element.buffered.length > 0) { if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" // prevent "DOMException: Index or size is negative or greater than the allowed amount" @@ -215,19 +311,28 @@ timerUI.update = function() { media_element.paused == false ? media_element.paused == false ? timerUI.status.innerHTML=symbol_play timerUI.status.innerHTML=symbol_play : timerUI.status.innerHTML=symbol_pause; : timerUI.status.innerHTML=symbol_pause;
} else { timerUI.stop(); console.warn(timerUI.msg.nomedia) } }; }; timerUI.updateTitle = function() { if (timerUI.title) timerUI.title.innerHTML = timerUI.getTitle(); }
// update title on URL change addEventListener('popstate', timerUI.updateTitle);
// update title fallback timerUI.interval.updateTitle = setInterval(timerUI.updateTitle, 2000);
timerUI.updateBufferSegment = function() { if (media_element) { // find out first buffer segment after current playback position // find out first buffer segment after current playback position media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; // media_element.buffered.length is zero until player is initialized // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if ( timerUI.buffer_on && timerUI.buffer_segment > 0) { while (media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime && timerUI.buffer_segment > 1 ) { timerUI.buffer_segment-- ; timerUI.buffer_segment-- ; } } } } } }; };
timerUI.setColor = function(newColor) { timerUI.setColor = function(newColor) { @@ -239,46 +344,48 @@ timerUI.setColor = function(newColor) { // (deprecated due to new buffer bar) timerUI.bar_placeholder.style.backgroundColor=timerUI.color; // (deprecated due to new buffer bar) timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.title.style.color=timerUI.color; }; };
timerUI.setGradient = function(newGradient) { timerUI.setGradient = function(newGradient) { newGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.9)" : timerUI.gradient = newGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; }; };
timerUI.setFont = function(newFont) { timerUI.setFont = function(newFont) { timerUI.time.style.fontFamily=newFont; timerUI.time.style.fontFamily=newFont; timerUI.title.style.fontFamily=newFont; };
timerUI.stop = function() { timerUI.status.innerHTML="■"; timerUI.bar.style.width=0; timerUI.buffer_bar.style.width=0; timerUI.time.innerHTML=HMStimer(undefined); }; };
// Additional checks to ensure the player is detected // Additional checks to ensure the player is detected window.onclick = function() { checkMediaType();timeUI(); }; window.onclick = function() { checkMediaType();timeUI(); }; window.addEventListener("keydown", function() { checkMediaType();timeUI(); } ); window.addEventListener("keydown", function() { checkMediaType();timeUI(); } );
function timeUI() { function timeUI() { // slightly different name to prevent naming collision with timerUI object
checkMediaType(); checkMediaType(); timerUI.domainRules(); // load domain rules // add timerUI if it does not already exist // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists ) { if ( ( ! document.getElementById("timerUI") ) && playerExists ) {
// Adding elements // Adding elements
// parent element // parent element appendChildWithID("div","timerUI"); appendChildWithID("div","timerUI"); timerUI.div = document.getElementById("timerUI"); timerUI.div = document.getElementById("timerUI");
// button styling // button styling addStyle("#timerUI button { background:none; border:none; outline:none; line-height:unset; } #timerUI button:hover { filter: brightness(1.2); } #timerUI button:active { filter: brightness(0.6); }", timerUI.div); // to suppress button background and border on earlier browser versions timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector
// background gradient // background gradient @@ -296,11 +403,17 @@ function timeUI() { timerUI.buffer_bar = document.getElementById("bufferBar"); timerUI.buffer_bar = document.getElementById("bufferBar"); addStyle("#timerUI #bufferBar { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; }", timerUI.div); addStyle("#timerUI #bufferBar { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; }", timerUI.div);
// media title appendChildWithID("div","mediaTitle",timerUI.div ); timerUI.title = document.getElementById("mediaTitle"); timerUI.title.innerHTML = timerUI.getTitle(); addStyle("#timerUI #mediaTitle { position:fixed; text-shadow: 0 0 5px black; display:inline; display:-webkit-box; bottom:15pt; left:2pt; color:"+timerUI.color+"; font-family:"+timerUI.font_pack+"; font-size:20pt; width:60%; max-width:calc(100% - 500px); text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; vertical-align: bottom;")
// timer // timer appendChildWithID("button","playTimer",timerUI.div ); appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); timerUI.time = document.getElementById("playTimer"); timerUI.time.innerHTML="00:00:00"; timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #playTimer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:"+timerUI.font_pack+"; } #playTimer .timer_linefeed { display:none; }", timerUI.div);
// play/pause symbol // play/pause symbol appendChildWithID("button","playStatus",timerUI.div ); appendChildWithID("button","playStatus",timerUI.div ); @@ -311,24 +424,23 @@ function timeUI() { // progress bar placeholder – put last to be at the top in stacking context // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); appendChildWithID("div","progBarPlaceholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); addStyle("#timerUI #progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div);
// responsive - at bottom to be able to override CSS properties without !important flag. // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #playTimer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #playStatus { bottom:10pt; } } @media (max-width:500px) { #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash { display:none; } } @media (max-width:"+timerUI.width_breakpoint+"px) { #timerUI #mediaTitle { font-size:10pt; -webkit-line-clamp: 3; max-width:60%;} } @media (max-width:480px) { #timerUI #mediaTitle { display: none; } } ", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive");
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar // update timer during playback every fifteenth of a second and while mouse is dragging progress bar timerUI.interval.update = setInterval( function() { if ( function() { if ( ( media_element /* exists? */ && timerUI.update_during_seek && mousedown_status ) || ( media_element && timerUI.on && ! media_element.paused ) ) timerUI.update(); }, 1000/15 ); );
// Longer interval for buffer bar to minimize CPU usage // Longer interval for buffer bar to minimize CPU usage timerUI.interval.buffer = setInterval(timerUI.updateBufferSegment, 1000);
// play and pause toggle // play and pause toggle @@ -339,16 +451,18 @@ function timeUI() { timerUI.time.onclick = function() { timerUI.time.onclick = function() { switch(timerUI.show_remaining) { switch(timerUI.show_remaining) { case 0: timerUI.show_remaining = 1; break; case 0: timerUI.show_remaining = 1; break; case 1: timerUI.show_remaining = 2; timerUI.adaptTitleWidth(); break; case 2: timerUI.show_remaining = 0; timerUI.adaptTitleWidth(); break; } } timerUI.update(); timerUI.update(); }; };
// clickable progress bar (experimental) - no "timerUI." notation because inside main function // clickable progress bar (experimental) - no "timerUI." notation because inside main function timerUI.clickSeekBar = function(m){ if (media_element) { var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; } } } function dragSeekBar(m){ // currently unused function dragSeekBar(m){ // currently unused m = m || window.event; m = m || window.event; @@ -359,7 +473,7 @@ function timeUI() { if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); }, 200); } } timerUI.bar_placeholder.addEventListener("mousedown", timerUI.clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar );
@@ -372,19 +486,59 @@ function timeUI() { window.addEventListener("keyup", function() { setTimeout(timerUI.update, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUI.update, 200); } );
// prevent detaching from player on sites with playlists such as Internet Archive // prevent detaching from player on sites with playlists such as Internet Archive timerUI.interval.checkMedia = setInterval( checkMediaType,1000 );
// prevent indicating "▶" after playback finished // prevent indicating "▶" after playback finished timerUI.interval.checkPaused = setInterval( function() { if ( media_element /* exists? */ && media_element.paused && ! timerUI.pause_checked) { timerUI.update(); timerUI.pause_checked = true; timerUI.update(); timerUI.pause_checked = true; if (timerUI.debug_mode) console.debug("timerUI: checking paused status: "+media_element.paused); } else if ( media_element && ! media_element.paused ) { timerUI.pause_checked = false; } // to avoid redundant checks while paused },1000 ); },1000 );
} else { } else { // warn in console that no player exists; prevent repetition // warn in console that no player exists; prevent repetition if (! playerExists && ! timerUI.noMediaWarned) { console.warn(timerUI.msg.nomedia); timerUI.noMediaWarned = true; } } } } }
// == Custom domain rules == timerUI.domainRules = function() { if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); customTitleElement = document.getElementById("media-title"); // for unlisted } };
timerUI.titleDomainRules = function() { // custom domain rules for title if ( isDomain("youtube.com") || isDomain("dailymotion.com") || isDomain("wikimedia.org") || isDomain("wikipedia.org") || isDomain("wikiversity.org") || isDomain("wikibooks.org") || isDomain("mediawiki.org") ) { // negative lookahead regular expression – trim after last dash // Match both normal dash "-" and ndash "–", since the German-language wikis use the latter. timerUI.newTitle = decodeURI(timerUI.newTitle.substring(0,timerUI.newTitle.search(/(-|–)(?:.(?!(-|–)))+$/)-1 ) ); } // remove "File:" prefix on wikis if ( isDomain("wiki") ) { if (document.title.search(/^File:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(5); if (document.title.search(/^Datei:/) == 0 ) timerUI.newTitle = timerUI.newTitle.substring(6); }
if ( isDomain("archive.org") && ! isDomain("web.archive.org") ) { timerUI.newTitle = (document.location.toString()+"").substring((document.location.toString()+" ").search(/\/(?:.(?!\/))+\/?$/)+1 ); // after last slash (additional space prevents full URL from being matched) if (timerUI.newTitle != "") { timerUI.newTitle += " - " }; timerUI.newTitle += document.title.toString().substring(0,document.title.toString().search(/:(?:.(?!:))+(?:.(?!:))+/)-1 ); // trim after second-last colon, -1 to remove space at end } };
// == Master function == timeUI(); -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 19 additions and 17 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -33,9 +33,8 @@ function customMediaElement(custom_media_element) { } }
// symbols // symbols var symbol_play = "▶︎ "; // thin space for alignment var symbol_pause="❚ ❚"; // instead of "⏸" due to Edge browser putting an immutable blue box around it.
// mousedown status // mousedown status var mousedown_status; var mousedown_status; @@ -225,7 +224,7 @@ timerUI.updateBufferSegment = function() { // media_element.buffered.length is zero until player is initialized // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if (timerUI.buffer_on && timerUI.buffer_segment > 0) { if (timerUI.buffer_on && timerUI.buffer_segment > 0) { while ( media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime && timerUI.buffer_segment > 0 ) { timerUI.buffer_segment-- ; timerUI.buffer_segment-- ; } } } } @@ -279,7 +278,7 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); timerUI.div = document.getElementById("timerUI");
// button styling // button styling addStyle("#timerUI button { background:unset; border:unset; outline:unset; line-height:unset; }", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector
// background gradient // background gradient @@ -301,7 +300,7 @@ function timeUI() { appendChildWithID("button","playTimer",timerUI.div ); appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); timerUI.time = document.getElementById("playTimer"); timerUI.time.innerHTML="00:00:00"; timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #playTimer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; text-shadow: 0 0 20px black; line-height:60pt; bottom:10pt; right:30pt; text-align:right; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; } #playTimer .timer_linefeed { display:none; }", timerUI.div);
// play/pause symbol // play/pause symbol appendChildWithID("button","playStatus",timerUI.div ); appendChildWithID("button","playStatus",timerUI.div ); @@ -315,7 +314,7 @@ function timeUI() { addStyle("#progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div); addStyle("#progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div);
// responsive - at bottom to be able to override CSS properties without !important flag. // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:768px) { #timerUI #playTimer { font-size:30pt; line-height:24pt; bottom:15pt; } #timerUI #playStatus { bottom:10pt; } } @media (max-width:500px) { #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash { display:none; } }", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive");
@@ -368,21 +367,24 @@ function timeUI() {
// == Patches == // == Patches ==
// prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUI.update, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUI.update, 200); } );
// prevent detaching from player on sites with playlists such as Internet Archive timerUI.checkMediaInterval = setInterval( checkMediaType,1000 );
// prevent indicating "▶" after playback finished timerUI.checkPausedInterval = setInterval( function() { if (media_element.paused && ! timerUI.pause_checked) { timerUI.update(); timerUI.pause_checked = true; } else { timerUI.pause_checked = false; } },1000 ); },1000 );
} else { } else { // warn in console that no player exists; prevent repetition if (! playerExists && ! timerUI.noMediaWarned) { if (! playerExists && ! timerUI.noMediaWarned) { console.warn("timerUI: no media element found on page."); timerUI.noMediaWarned = true; } } } } } } -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 8 additions and 3 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -32,6 +32,11 @@ function customMediaElement(custom_media_element) { } else { console.error("timerUI: No such media element found."); } } else { console.error("timerUI: No such media element found."); } } }
// symbols var symbol_play = "▶︎"; var symbol_pause = "⏸︎"; // "︎" is necessary to prevent the symbols from being rendered as clip art icons bundled by vendors of browsers and devices.
// mousedown status // mousedown status var mousedown_status; var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true; } ); window.addEventListener("mousedown", function(){mousedown_status=true; } ); @@ -209,8 +214,8 @@ timerUI.update = function() { } }
media_element.paused == false ? media_element.paused == false ? timerUI.status.innerHTML=symbol_play : timerUI.status.innerHTML=symbol_pause; }; };
@@ -372,7 +377,7 @@ function timeUI() {
// prevent indicating "▶" after playback finished // prevent indicating "▶" after playback finished timerUI.checkPaused = setInterval( function() { timerUI.checkPaused = setInterval( function() { if (media_element.paused && timerUI.status.innerHTML!=symbol_pause) timerUI.update(); },1000 ); },1000 ); } else { } else { // warn in console that no player exists; prevent repetition // warn in console that no player exists; prevent repetition -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 40 additions and 4 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -144,7 +144,7 @@ if (! timerUI) var timerUI = new Object({}); // create parent object if none exi timerUI.toggle = function() { timerUI.toggle = function() { if (timerUI.div) { if (timerUI.div) { timerUI.update(); timerUI.update(); if (timerUI.on) { timerUI.div.style.display = "none"; timerUI.div.style.display = "none"; console.log("timerUI off"); console.log("timerUI off"); } } @@ -159,14 +159,32 @@ timerUI.toggle = function() { } } }; };
timerUI.toggleBuffer = function() { if (timerUI.div) { timerUI.update(); if (timerUI.buffer_on) { timerUI.buffer_bar.style.display = "none"; console.log("timerUI buffer bar off"); } if (! timerUI.buffer_on ) { timerUI.buffer_bar.style.display = "block"; console.log("timerUI buffer bar on"); } timerUI.buffer_on ? timerUI.buffer_on = false : timerUI.buffer_on = true; } else { console.warn("timerUI: No timer found; checking for media element again. Please try again."); timeUI(); } };
var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; var timer_slash = " <span class=timer_slash>/</span> "; timerUI.update = function() { timerUI.update = function() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; if (media_element.buffered.length > 0) { if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" // prevent "DOMException: Index or size is negative or greater than the allowed amount" timerUI.buffer_bar.style.width=media_element.buffered.end(timerUI.buffer_segment) / media_element.duration * 100 + "%"; } else { timerUI.buffer_bar.style.width="0%"; }
switch(timerUI.show_remaining) { switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" @@ -195,6 +213,19 @@ timerUI.update = function() { : timerUI.status.innerHTML="⏸"; : timerUI.status.innerHTML="⏸"; }; };
timerUI.updateBufferSegment = function() { // find out first buffer segment after current playback position media_element.buffered.length > 0 ? timerUI.buffer_segment=media_element.buffered.length-1 : timerUI.buffer_segment=0; // media_element.buffered.length is zero until player is initialized // prevent timerUI.buffer_segment from going negative, as it would cause a DOMException error if (timerUI.buffer_on && timerUI.buffer_segment > 0) { while ( media_element.buffered.end(timerUI.buffer_segment-1) > media_element.currentTime ) { timerUI.buffer_segment-- ; } } };
timerUI.setColor = function(newColor) { timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor;
@@ -229,6 +260,7 @@ function timeUI() {
// Declaring variables // Declaring variables timerUI.on = true; timerUI.on = true; timerUI.buffer_on = true; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.update_during_seek = true; // update timer while dragging seek bar @@ -258,7 +290,7 @@ function timeUI() { // buffer bar // buffer bar appendChildWithID("div","bufferBar",timerUI.div ); appendChildWithID("div","bufferBar",timerUI.div ); timerUI.buffer_bar = document.getElementById("bufferBar"); timerUI.buffer_bar = document.getElementById("bufferBar"); addStyle("#timerUI #bufferBar { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; }", timerUI.div);
// timer // timer appendChildWithID("button","playTimer",timerUI.div ); appendChildWithID("button","playTimer",timerUI.div ); @@ -291,6 +323,10 @@ function timeUI() { }, 1000/15 }, 1000/15 ); );
// Longer interval for buffer bar to minimize CPU usage timerUI.updateBufferInterval = setInterval(timerUI.updateBufferSegment, 1000);
// play and pause toggle // play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUI.update(); }; timerUI.status.onclick = function() { togglePlay(media_element); timerUI.update(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 11 additions and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -163,6 +163,10 @@ var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; var timer_slash = " <span class=timer_slash>/</span> "; timerUI.update = function() { timerUI.update = function() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; if (media_element.buffered.length > 0) { // prevent "DOMException: Index or size is negative or greater than the allowed amount" timerUI.buffer_bar.style.width=media_element.buffered.end(media_element.buffered.length-1) / media_element.duration * 100 + "%"; }
switch(timerUI.show_remaining) { switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" @@ -195,8 +199,9 @@ timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor; newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor;
timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.backgroundColor=timerUI.color; timerUI.buffer_bar.style.backgroundColor=timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; // (deprecated due to new buffer bar) timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; }; }; @@ -250,6 +255,11 @@ function timeUI() { timerUI.bar = document.getElementById("progBar"); timerUI.bar = document.getElementById("progBar"); addStyle("#timerUI #progBar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div); addStyle("#timerUI #progBar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div);
// buffer bar appendChildWithID("div","bufferBar",timerUI.div ); timerUI.buffer_bar = document.getElementById("bufferBar"); addStyle("#timerUI #bufferBar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:75%; bottom:0; opacity:0.4; }", timerUI.div);
// timer // timer appendChildWithID("button","playTimer",timerUI.div ); appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); timerUI.time = document.getElementById("playTimer"); -
HT-7 revised this gist
on May 20, 2022May 20, 2022 . 1 changed file with 46 additions and 41 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -5,11 +5,11 @@ var mediaType; // for compatibility var mediaType; // for compatibility var playerExists = false; // is set to true below if player exists var playerExists = false; // is set to true below if player exists var checkMediaType_enabled = true; // for debugging purposes var checkMediaType_enabled = true; // for debugging purposes var media_element = {}; // declaring as object
function checkMediaType() { function checkMediaType() { // checks whether it is a video or an audio tag // checks whether it is a video or an audio tag if ( checkMediaType_enabled ) { var mediaTypeBeforeCheck = mediaType; var mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = true; mediaType = "video"; } if (document.getElementsByTagName("video")[0]) { playerExists = true; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = true; mediaType = "audio"; } if (document.getElementsByTagName("audio")[0]) { playerExists = true; mediaType = "audio"; } @@ -18,7 +18,7 @@ function checkMediaType() { // Only show media type in console if it has changed. // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; media_element = document.getElementsByTagName(mediaType)[0]; // Set back to false if no player is found after using customMediaElement. media_element ? playerExists=true : playerExists=false; media_element ? playerExists=true : playerExists=false; } } } } @@ -28,14 +28,10 @@ function customMediaElement(custom_media_element) { if (custom_media_element) { if (custom_media_element) { playerExists = true; playerExists = true; media_element = custom_media_element; media_element = custom_media_element; console.log("timerUI: Custom media element set. Reset using checkMediaType_enabled=true."); } else { console.error("timerUI: No such media element found."); } } }
// mousedown status // mousedown status var mousedown_status; var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true; } ); window.addEventListener("mousedown", function(){mousedown_status=true; } ); @@ -137,35 +133,35 @@ function isDomain(domain) { if (window.location.hostname.search(domain) >= 0) return true; else return false; if (window.location.hostname.search(domain) >= 0) return true; else return false; } }
if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//) < 0 ) { // Dailymotion watch page, excluding embed page. // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]); }
// == Main code == // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists if (! timerUI) var timerUI = new Object({}); // create parent object if none exists
timerUI.toggle = function() { if (timerUI.div) { if (timerUI.div) { timerUI.update(); if (timerUI.on ) { timerUI.div.style.display = "none"; timerUI.div.style.display = "none"; console.log("timerUI off"); console.log("timerUI off"); } } if (! timerUI.on ) { timerUI.div.style.display = "block"; timerUI.div.style.display = "block"; console.log("timerUI on"); console.log("timerUI on"); } } timerUI.on ? timerUI.on = false : timerUI.on = true; } else { } else { console.warn("timerUI: No timer found; checking for media element again. Please try again."); console.warn("timerUI: No timer found; checking for media element again. Please try again."); timeUI(); timeUI(); } } };
var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; var timer_slash = " <span class=timer_slash>/</span> "; timerUI.update = function() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%"; timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%";
switch(timerUI.show_remaining) { switch(timerUI.show_remaining) { @@ -193,34 +189,38 @@ function timerUpdate() { media_element.paused == false ? media_element.paused == false ? timerUI.status.innerHTML="▶" timerUI.status.innerHTML="▶" : timerUI.status.innerHTML="⏸"; : timerUI.status.innerHTML="⏸"; };
timerUI.setColor = function(newColor) { newColor == "default" ? timerUI.color="rgb(49,136,255)" /* #38F */ : timerUI.color = newColor;
timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; };
timerUI.setGradient = function(newGradient) { newGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.7)" : timerUI.gradient = newGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; };
timerUI.setFont = function(newFont) { timerUI.time.style.fontFamily=newFont; };
// Additional checks to ensure the player is detected window.onclick = function() { checkMediaType();timeUI(); }; window.addEventListener("keydown", function() { checkMediaType();timeUI(); } );
timeUI(); // slightly different name to prevent naming collision with timerUI object
function timeUI() { function timeUI() {
checkMediaType(); checkMediaType(); // add timerUI if it does not already exist // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists ) {
// Declaring variables // Declaring variables timerUI.on = true; timerUI.on = true; @@ -277,12 +277,12 @@ function timeUI() { function() { if ( function() { if ( ( timerUI.update_during_seek && mousedown_status ) ( timerUI.update_during_seek && mousedown_status ) || ( timerUI.on && ! media_element.paused ) || ( timerUI.on && ! media_element.paused ) ) timerUI.update(); }, 1000/15 }, 1000/15 ); );
// play and pause toggle // play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUI.update(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay();
// toggle between elapsed, remaining, and elapsed/total time // toggle between elapsed, remaining, and elapsed/total time @@ -292,41 +292,46 @@ function timeUI() { case 1: timerUI.show_remaining = 2; break; case 1: timerUI.show_remaining = 2; break; case 2: timerUI.show_remaining = 0; break; case 2: timerUI.show_remaining = 0; break; } } timerUI.update(); }; };
// clickable progress bar (experimental) - no "timerUI." notation because inside main function function clickSeekBar(m){ function clickSeekBar(m){ var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; media_element.currentTime = media_element.duration * clickPos; } } function dragSeekBar(m){ // currently unused m = m || window.event; m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var dragSeekBarInterval = setInterval( function() { var dragSeekBarInterval = setInterval( function() { media_element.currentTime = media_element.duration * clickPos; media_element.currentTime = media_element.duration * clickPos; timerUI.update(); if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); }, 200); } } timerUI.bar_placeholder.addEventListener("mousedown", clickSeekBar ); timerUI.bar_placeholder.addEventListener("mousedown", clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar );
timerUI.update();
// == Patches == // == Patches ==
// prevent missing out on pausing from inside a site's existing player // prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUI.update, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUI.update, 200); } );
// prevent detaching from player on sites with playlists such as Internet Archive // prevent detaching from player on sites with playlists such as Internet Archive timerUI.checkMediaInterval = setInterval( checkMediaType,1000 ); timerUI.checkMediaInterval = setInterval( checkMediaType,1000 );
// prevent indicating "▶" after playback finished // prevent indicating "▶" after playback finished timerUI.checkPaused = setInterval( function() { timerUI.checkPaused = setInterval( function() { if (media_element.paused && timerUI.status.innerHTML!="⏸") timerUI.update(); },1000 ); },1000 ); } else { // warn in console that no player exists; prevent repetition if (! playerExists && ! timerUI.noMediaWarned) { console.warn("timerUI: no media element found on page."); timerUI.noMediaWarned = true; } } } } -
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -173,8 +173,8 @@ function timerUpdate() { case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: case 2: if (media_element.duration < 3600 || isNaN(media_element.duration) ) { // show hours if duration exceeds one hour timerUI.time.innerHTML= timerUI.time.innerHTML= MStimer(media_element.currentTime) MStimer(media_element.currentTime) + timer_linefeed + timer_linefeed -
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 6 additions and 5 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -158,7 +158,7 @@ function timerToggle() { } } timerUI.on == false ? timerUI.on = true : timerUI.on = false; timerUI.on == false ? timerUI.on = true : timerUI.on = false; } else { } else { console.warn("timerUI: No timer found; checking for media element again. Please try again."); timeUI(); timeUI(); } } } } @@ -173,8 +173,8 @@ function timerUpdate() { case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: case 2: if (media_element.duration < 6000 || isNaN(media_element.duration) ) { // show hours if duration exceeds 100 minutes timerUI.time.innerHTML= timerUI.time.innerHTML= MStimer(media_element.currentTime) MStimer(media_element.currentTime) + timer_linefeed + timer_linefeed @@ -199,6 +199,7 @@ function timerColor(setColor) { setColor == "default" ? timerUI.color="rgb(49,136,255)" : timerUI.color = setColor; setColor == "default" ? timerUI.color="rgb(49,136,255)" : timerUI.color = setColor;
timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar.style.boxShadow="0 0 30px 0 "+timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; @@ -247,7 +248,7 @@ function timeUI() { // progress bar // progress bar appendChildWithID("div","progBar",timerUI.div ); appendChildWithID("div","progBar",timerUI.div ); timerUI.bar = document.getElementById("progBar"); timerUI.bar = document.getElementById("progBar"); addStyle("#timerUI #progBar { display:block; position:fixed; background-color:"+timerUI.color+"; box-shadow: 0 0 30px 0px "+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div);
// timer // timer appendChildWithID("button","playTimer",timerUI.div ); appendChildWithID("button","playTimer",timerUI.div ); @@ -284,7 +285,7 @@ function timeUI() { timerUI.status.onclick = function() { togglePlay(media_element); timerUpdate(); }; timerUI.status.onclick = function() { togglePlay(media_element); timerUpdate(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay(); // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay();
// toggle between elapsed, remaining, and elapsed/total time timerUI.time.onclick = function() { timerUI.time.onclick = function() { switch(timerUI.show_remaining) { switch(timerUI.show_remaining) { case 0: timerUI.show_remaining = 1; break; case 0: timerUI.show_remaining = 1; break; -
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 30 additions and 25 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -3,31 +3,32 @@ // == Dependencies == // == Dependencies ==
var mediaType; // for compatibility var mediaType; // for compatibility var playerExists = false; // is set to true below if player exists var checkMediaType_enabled = true; // for debugging purposes var media_element = {};
function checkMediaType() { function checkMediaType() { if ( checkMediaType_enabled == true ) { // checks whether it is a video or an audio tag // checks whether it is a video or an audio tag var mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = true; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = true; mediaType = "audio"; } var mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; media_element = document.getElementsByTagName(mediaType)[0]; // Set back to 0 if no player is found after using customMediaElement. // Set back to 0 if no player is found after using customMediaElement. media_element ? playerExists=true : playerExists=false; } } } }
function customMediaElement(custom_media_element) { function customMediaElement(custom_media_element) { checkMediaType_enabled = false; if (custom_media_element) { if (custom_media_element) { playerExists = true; media_element = custom_media_element; media_element = custom_media_element; console.log("Custom media element set. Reset using checkMediaType_enabled=true."); } else { console.error("No such media element found."); } } else { console.error("No such media element found."); } } }
@@ -37,8 +38,8 @@ window.addEventListener("keydown", function() { checkMediaType();timeUI(); } );
// mousedown status // mousedown status var mousedown_status; var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true; } ); window.addEventListener("mouseup", function(){mousedown_status=false; } );
function appendChildWithID(tagName,tagID,parent_element) { function appendChildWithID(tagName,tagID,parent_element) { // default parent element to document.body if unspecified // default parent element to document.body if unspecified @@ -53,6 +54,10 @@ function addStyle(new_style,parent_element) { parent_element.lastElementChild.innerHTML = new_style; parent_element.lastElementChild.innerHTML = new_style; } }
// time variables var time_HH = 0; var time_MM = 0; var time_SS = 0;
// HH:MM:SS timer // HH:MM:SS timer function HMStimer_core(seconds) { function HMStimer_core(seconds) { @@ -143,15 +148,15 @@ if (! timerUI) var timerUI = new Object({}); // create parent object if none exi function timerToggle() { function timerToggle() { if (timerUI.div) { if (timerUI.div) { timerUpdate(); timerUpdate(); if (timerUI.on == true) { timerUI.div.style.display = "none"; timerUI.div.style.display = "none"; console.log("timerUI off"); console.log("timerUI off"); } } if (timerUI.on == false) { timerUI.div.style.display = "block"; timerUI.div.style.display = "block"; console.log("timerUI on"); console.log("timerUI on"); } } timerUI.on == false ? timerUI.on = true : timerUI.on = false; } else { } else { console.log("No timer found; checking for media element again. Please try again."); console.log("No timer found; checking for media element again. Please try again."); timeUI(); timeUI(); @@ -185,7 +190,7 @@ function timerUpdate() { break; break; } }
media_element.paused == false ? timerUI.status.innerHTML="▶" timerUI.status.innerHTML="▶" : timerUI.status.innerHTML="⏸"; : timerUI.status.innerHTML="⏸"; } } @@ -214,13 +219,13 @@ function timeUI() {
checkMediaType(); checkMediaType(); // add timerUI if it does not already exist // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == true ) {
// Declaring variables // Declaring variables timerUI.on = true; timerUI.div = {}; // unset yet, declaring to prevent reference errors timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = true; // update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.7)"; // using RGBA instead of hexadecimal for compatibility. timerUI.gradient = "rgba(0,0,0,0.7)"; // using RGBA instead of hexadecimal for compatibility.
@@ -231,7 +236,7 @@ function timeUI() { timerUI.div = document.getElementById("timerUI"); timerUI.div = document.getElementById("timerUI");
// button styling // button styling addStyle("#timerUI button \{ background:unset; border:unset; outline:unset; line-height:unset; \}", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector
// background gradient // background gradient @@ -259,10 +264,10 @@ function timeUI() { // progress bar placeholder – put last to be at the top in stacking context // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); appendChildWithID("div","progBarPlaceholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); addStyle("#progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div);
// responsive - at bottom to be able to override CSS properties without !important flag. // responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:768px) \{ #timerUI #playTimer \{ font-size:30pt; line-height:24pt; bottom:15pt; \} #timerUI #playStatus \{ bottom:10pt; \} \} @media (max-width:500px) \{ #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash \{ display:none; \} \}", timerUI.div); timerUI.div.lastElementChild.classList.add("timerUI_responsive"); timerUI.div.lastElementChild.classList.add("timerUI_responsive");
@@ -285,7 +290,7 @@ function timeUI() { case 0: timerUI.show_remaining = 1; break; case 0: timerUI.show_remaining = 1; break; case 1: timerUI.show_remaining = 2; break; case 1: timerUI.show_remaining = 2; break; case 2: timerUI.show_remaining = 0; break; case 2: timerUI.show_remaining = 0; break; } timerUpdate(); timerUpdate(); }; };
-
HT-7 revised this gist
on May 19, 2022May 19, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -222,7 +222,7 @@ function timeUI() { timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = 1; // 1: update timer while dragging seek bar timerUI.update_during_seek = 1; // 1: update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgba(0,0,0,0.7)"; // using RGBA instead of hexadecimal for compatibility.
// Adding elements // Adding elements
-
HT-7 revised this gist
on May 18, 2022May 18, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -254,7 +254,7 @@ function timeUI() { appendChildWithID("button","playStatus",timerUI.div ); appendChildWithID("button","playStatus",timerUI.div ); timerUI.status = document.getElementById("playStatus"); timerUI.status = document.getElementById("playStatus"); timerUI.status.innerHTML="■"; timerUI.status.innerHTML="■"; addStyle("#timerUI #playStatus { display:block; position:fixed; cursor:pointer; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div);
// progress bar placeholder – put last to be at the top in stacking context // progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); appendChildWithID("div","progBarPlaceholder",timerUI.div ); -
HT-7 revised this gist
on May 18, 2022May 18, 2022 . 1 changed file with 233 additions and 192 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -7,28 +7,28 @@ var playerExists = 0; // is set to 1 below if player exists var checkMediaType_enabled = 1; // for debugging purposes var checkMediaType_enabled = 1; // for debugging purposes
function checkMediaType() { function checkMediaType() { if ( checkMediaType_enabled == 1 ) { // checks whether it is a video or an audio tag mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = 1; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = 1; mediaType = "audio"; } mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; // Set back to 0 if no player is found after using customMediaElement. media_element ? playerExists=1 : playerExists=0; } } }
function customMediaElement(custom_media_element) { function customMediaElement(custom_media_element) { checkMediaType_enabled = 0; if (custom_media_element) { playerExists = 1; media_element = custom_media_element; console.log("Custom media element set. Reset using checkMediaType_enabled=1."); } else { console.error("No such media element found."); } } }
// Additional checks to ensure the player is detected // Additional checks to ensure the player is detected @@ -41,75 +41,75 @@ window.addEventListener("mousedown", function(){mousedown_status=true} ); window.addEventListener("mouseup", function(){mousedown_status=false} ); window.addEventListener("mouseup", function(){mousedown_status=false} );
function appendChildWithID(tagName,tagID,parent_element) { function appendChildWithID(tagName,tagID,parent_element) { // default parent element to document.body if unspecified if (parent_element === undefined) parent_element = document.body; parent_element.appendChild(document.createElement(tagName)); // add div parent_element.lastElementChild.id=tagID; // give it ID } }
function addStyle(new_style,parent_element) { function addStyle(new_style,parent_element) { if (parent_element === undefined) parent_element = document.body; parent_element.appendChild(document.createElement("style")); // add style parent_element.lastElementChild.innerHTML = new_style; } }
// HH:MM:SS timer // HH:MM:SS timer function HMStimer_core(seconds) { function HMStimer_core(seconds) {
// hours time_HH = Math.floor( seconds/3600 ); // leading zero if ( seconds < 36000 ) time_HH = "0" + time_HH;
// minutes time_MM = Math.floor( seconds/60%60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM;
// seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS;
return time_HH+":"+time_MM+":"+time_SS; } }
function HMStimer(seconds) { function HMStimer(seconds) { if (seconds >= 0) return HMStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+HMStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –:– –";
} }
// MM:SS timer // MM:SS timer function MStimer_core(seconds) { function MStimer_core(seconds) {
// minutes time_MM = Math.floor( seconds/60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM;
// seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS;
return time_MM+":"+time_SS; } }
function MStimer(seconds) { function MStimer(seconds) { if (seconds >= 0) return MStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+MStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –";
} }
@@ -123,163 +123,204 @@ Object.prototype.togglePlay = function togglePlay() {
// new function without object prototype for compatibility // new function without object prototype for compatibility function togglePlay(media_element) { function togglePlay(media_element) { media_element.paused ? media_element.play() : media_element.pause(); } }
// == Custom domain rules == // == Custom domain rules == function isDomain(domain) { function isDomain(domain) { // Using .search() instead of .includes() to improve browser compatibility. if (window.location.hostname.search(domain) >= 0) return true; else return false; } }
if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//)==(-1) ) if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//)==(-1) ) // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]);
// == Main code == // == Main code == if (! timerUI) var timerUI = new Object({}); // create parent object if none exists
function timerToggle() { function timerToggle() { if (timerUI.div) { timerUpdate(); if (timerUI.on == 1) { timerUI.div.style.display = "none"; console.log("timerUI off"); } if (timerUI.on == 0) { timerUI.div.style.display = "block"; console.log("timerUI on"); } timerUI.on == 0 ? timerUI.on = 1 : timerUI.on = 0; } else { console.log("No timer found; checking for media element again. Please try again."); timeUI(); } } }
var timer_linefeed = "<span class=timer_linefeed><br /></span>"; var timer_slash = " <span class=timer_slash>/</span> "; function timerUpdate() { function timerUpdate() { timerUI.bar.style.width=media_element.currentTime / media_element.duration * 100 + "%";
switch(timerUI.show_remaining) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" case 0: timerUI.time.innerHTML=HMStimer(media_element.currentTime); break; case 1: timerUI.time.innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 3600 || isNaN(media_element.duration) ) { // show hours if duration exceeds one hour timerUI.time.innerHTML= MStimer(media_element.currentTime) + timer_linefeed + timer_slash + MStimer(media_element.duration); } else { timerUI.time.innerHTML= HMStimer(media_element.currentTime) + timer_linefeed + timer_slash + HMStimer(media_element.duration); } break; }
media_element.paused == 0 ? timerUI.status.innerHTML="▶" : timerUI.status.innerHTML="⏸"; } }
function timerColor(setColor) { function timerColor(setColor) { setColor == "default" ? timerUI.color="rgb(49,136,255)" : timerUI.color = setColor;
timerUI.bar.style.backgroundColor=timerUI.color; timerUI.bar_placeholder.style.backgroundColor=timerUI.color; timerUI.time.style.color=timerUI.color; timerUI.status.style.color=timerUI.color; } }
function timerGradient(setGradient) { setGradient == "default" ? timerUI.gradient="rgba(0,0,0,0.7)" : timerUI.gradient = setGradient; timerUI.gradient_placeholder.style.backgroundImage="linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) )"; } }
function timerFont(setFont) { timerUI.time.style.fontFamily=setFont; }
timeUI(); timeUI();
function timeUI() { function timeUI() {
checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == 1 ) {
// Declaring variables timerUI.on = 1; timerUI.div; // unset yet, declaring to prevent reference errors timerUI.show_remaining = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. timerUI.update_during_seek = 1; // 1: update timer while dragging seek bar timerUI.color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. timerUI.gradient = "rgb(0,0,0,0.7)"; // #38F – using RGB for compatibility.
// Adding elements
// parent element appendChildWithID("div","timerUI"); timerUI.div = document.getElementById("timerUI");
// button styling addStyle("#timerUI button \{ background:unset; border:unset; outline:unset; line-height:unset; \}", timerUI.div) timerUI.div.lastElementChild.classList.add("timerUI_buttons"); // label to improve visibility in page inspector
// background gradient appendChildWithID("div","bottomGradient",timerUI.div ); timerUI.gradient_placeholder = document.getElementById("bottomGradient"); addStyle("#timerUI #bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top,"+timerUI.gradient+", rgba(0,0,0,0) ); opacity:1; height:80pt; width:100%; bottom:0; pointer-events:none; }", timerUI.div);
// progress bar appendChildWithID("div","progBar",timerUI.div ); timerUI.bar = document.getElementById("progBar"); addStyle("#timerUI #progBar { display:block; position:fixed; background-color:"+timerUI.color+"; height:8pt; width:50%; bottom:0; }", timerUI.div);
// timer appendChildWithID("button","playTimer",timerUI.div ); timerUI.time = document.getElementById("playTimer"); timerUI.time.innerHTML="00:00:00"; addStyle("#timerUI #playTimer { display:block; color:"+timerUI.color+"; position:fixed; cursor:pointer; font-size:50pt; line-height:60pt; bottom:10pt; right:25pt; text-align:right; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; } #playTimer .timer_linefeed { display:none; }", timerUI.div);
// play/pause symbol appendChildWithID("button","playStatus",timerUI.div ); timerUI.status = document.getElementById("playStatus"); timerUI.status.innerHTML="■"; addStyle("#timerUI #playStatus { display:block; position:fixed; color:"+timerUI.color+"; font-size:24pt; line-height:40pt; bottom:30pt; right:3pt; font-family:none; }", timerUI.div);
// progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI.div ); timerUI.bar_placeholder = document.getElementById("progBarPlaceholder"); addStyle("#progBarPlaceholder { display:block; position:fixed; cursor:pointer; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }", timerUI.div)
// responsive - at bottom to be able to override CSS properties without !important flag. addStyle("@media (max-width:768px) \{ #timerUI #playTimer \{ font-size:30pt; line-height:24pt; bottom:15pt; \} #timerUI #playStatus \{ bottom:10pt; \} \} @media (max-width:500px) \{ #playTimer .timer_linefeed { display:inline; } #timerUI #playTimer .timer_slash \{ display:none; \} \}", timerUI.div) timerUI.div.lastElementChild.classList.add("timerUI_responsive");
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar timerUI.updateInterval = setInterval( function() { if ( ( timerUI.update_during_seek && mousedown_status ) || ( timerUI.on && ! media_element.paused ) ) timerUpdate(); }, 1000/15 );
// play and pause toggle timerUI.status.onclick = function() { togglePlay(media_element); timerUpdate(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay();
// toggle between elapsed and remaining time timerUI.time.onclick = function() { switch(timerUI.show_remaining) { case 0: timerUI.show_remaining = 1; break; case 1: timerUI.show_remaining = 2; break; case 2: timerUI.show_remaining = 0; break; }; timerUpdate(); };
// clickable progress bar (experimental) function clickSeekBar(m){ var clickPos = m.clientX / timerUI.bar_placeholder.offsetWidth; media_element.currentTime = media_element.duration * clickPos; } function dragSeekBar(m){ m = m || window.event; var clickPos = m.pageX / timerUI.bar_placeholder.offsetWidth; var dragSeekBarInterval = setInterval( function() { media_element.currentTime = media_element.duration * clickPos; timerUpdate(); if (! mousedown_status) { clearInterval(dragSeekBarInterval); return; } }, 200); } timerUI.bar_placeholder.addEventListener("mousedown", clickSeekBar ); // (incomplete) timerUI.bar_placeholder.addEventListener("mousemove", dragSeekBar ); // (obsolete) timerUI.bar_placeholder.addEventListener("mouseup", clickSeekBar );
timerUpdate();
// == Patches ==
// prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUpdate, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUpdate, 200); } );
// prevent detaching from player on sites with playlists such as Internet Archive timerUI.checkMediaInterval = setInterval( checkMediaType,1000 );
// prevent indicating "▶" after playback finished timerUI.checkPaused = setInterval( function() { if (media_element.paused && timerUI.status.innerHTML!="⏸") timerUpdate(); },1000 ); } } } } -
HT-7 revised this gist
on May 15, 2022May 15, 2022 . 1 changed file with 48 additions and 29 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -141,14 +141,21 @@ if (isDomain("dailymotion.com") && document.location.pathname.toString().search(
var timerUI_on = 1; var timerUI_on = 1; var timerUI_id; // unset yet, declaring to prevent reference errors var timerUI_id; // unset yet, declaring to prevent reference errors var show_remaining_time = 0; // 0: show elapsed time. 1: show remaining time. 2: show elapsed and total. var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility.
function timerToggle() { function timerToggle() { if (timerUI_id) { if (timerUI_id) { timerUpdate(); if (timerUI_on == 1) { timerUI_id.style.display = "none"; console.log("timerUI off"); } if (timerUI_on == 0) { timerUI_id.style.display = "block"; console.log("timerUI on"); } timerUI_on == 0 ? timerUI_on = 1 : timerUI_on = 0; timerUI_on == 0 ? timerUI_on = 1 : timerUI_on = 0; } else { } else { console.log("No timer found; checking for media element again. Please try again.") console.log("No timer found; checking for media element again. Please try again.") @@ -181,12 +188,13 @@ function timerUpdate() { } }
function timerColor(setColor) { function timerColor(setColor) { setColor == "default" ? timeUI_color="rgb(49,136,255)" : timeUI_color = setColor;
document.getElementById("progBar").style.backgroundColor=timeUI_color; document.getElementById("progBarPlaceholder").style.backgroundColor=timeUI_color; document.getElementById("playTimer").style.color=timeUI_color; document.getElementById("playStatus").style.color=timeUI_color; document.getElementById("bottomGradient").style.backgroundImage="linear-gradient(to top,"+timeUI_color+", rgba(0,0,0,0) )"; } }
function timerFont(setFont) { function timerFont(setFont) { @@ -207,31 +215,34 @@ function timeUI() { // add timerUI if it does not already exist // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == 1 ) { if ( ( ! document.getElementById("timerUI") ) && playerExists == 1 ) {
// Adding elements
// parent element appendChildWithID("div","timerUI"); var timerUI_id = document.getElementById("timerUI");
// background gradient appendChildWithID("div","bottomGradient",timerUI_id ); addStyle("#bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top, "+timeUI_color+", rgba(0,0,0,0) ); opacity:0.2; height:80pt; width:100%; bottom:0; pointer-events:none; }");
// progress bar appendChildWithID("div","progBar",timerUI_id ); addStyle("#progBar { display:block; position:fixed; background-color:"+timeUI_color+"; height:8pt; width:50%; bottom:0; }");
// timer appendChildWithID("div","playTimer",timerUI_id ); document.getElementById("playTimer").innerHTML="00:00:00"; addStyle("#playTimer { display:block; color:"+timeUI_color+"; position:fixed; font-size:50pt; bottom:0; line-height:80pt; right:25pt; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; }");
// play/pause symbol appendChildWithID("div","playStatus",timerUI_id ); document.getElementById("playStatus").innerHTML="■"; addStyle("#playStatus { display:block; color:"+timeUI_color+"; position:fixed; font-size:24pt; line-height:40pt; bottom:30pt; right:4pt; font-family:none; }");
// progress bar placeholder – put last to be at the top in stacking context appendChildWithID("div","progBarPlaceholder",timerUI_id ); addStyle("#progBarPlaceholder { display:block; position:fixed; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }")
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar // update timer during playback every fifteenth of a second and while mouse is dragging progress bar var timerUpdateInterval = setInterval( var timerUpdateInterval = setInterval( @@ -261,6 +272,14 @@ function timeUI() { timerUpdate(); timerUpdate(); }; };
// clickable progress bar (experimental) function clickSeekBar(m){ var clickPos = m.clientX / document.getElementById("progBarPlaceholder").offsetWidth; media_element.currentTime = media_element.duration * clickPos; } document.getElementById("progBarPlaceholder").addEventListener("mousedown", clickSeekBar ); document.getElementById("progBarPlaceholder").addEventListener("mouseup", clickSeekBar );
timerUpdate(); timerUpdate(); } } } } -
HT-7 revised this gist
on May 15, 2022May 15, 2022 . 1 changed file with 53 additions and 30 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -40,14 +40,17 @@ var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true} ); window.addEventListener("mousedown", function(){mousedown_status=true} ); window.addEventListener("mouseup", function(){mousedown_status=false} ); window.addEventListener("mouseup", function(){mousedown_status=false} );
function appendChildWithID(tagName,tagID,parent_element) { // default parent element to document.body if unspecified if (parent_element === undefined) var parent_element = document.body; parent_element.appendChild(document.createElement(tagName)); // add div parent_element.lastElementChild.id=tagID; // give it ID } }
function addStyle(new_style,parent_element) { if (parent_element === undefined) var parent_element = document.body; parent_element.appendChild(document.createElement("style")); // add style parent_element.lastElementChild.innerHTML = new_style; } }
@@ -136,30 +139,45 @@ if (isDomain("dailymotion.com") && document.location.pathname.toString().search(
// == Main code == // == Main code ==
var timerUI_on = 1; var timerUI_id; // unset yet, declaring to prevent reference errors var show_remaining_time = 0; // 0: show elapsed time. 1: show remaining time. 2: show both. var show_remaining_time = 0; // 0: show elapsed time. 1: show remaining time. 2: show both. var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility. var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility.
function timerToggle() { if (timerUI_id) { if (timerUI_on == 1) timerUI_id.style.display = "none"; if (timerUI_on == 0) timerUI_id.style.display = "block"; timerUpdate(); timerUI_on == 0 ? timerUI_on = 1 : timerUI_on = 0; } else { console.log("No timer found; checking for media element again. Please try again.") timeUI(); } } }
function timerUpdate() { if (timerUI_on == 1) { document.getElementById("progBar").style.width=media_element.currentTime / media_element.duration * 100 + "%";
switch(show_remaining_time) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" case 0: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime); break; case 1: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 3600 || isNaN(media_element) ) { // show hours if duration exceeds one hour document.getElementById("playTimer").innerHTML=MStimer(media_element.currentTime)+" / "+MStimer(media_element.duration); } else { document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime)+" / "+HMStimer(media_element.duration); } break; }
media_element.paused == 0 ? document.getElementById("playStatus").innerHTML="▶" : document.getElementById("playStatus").innerHTML="⏸"; } } }
function timerColor(setColor) { function timerColor(setColor) { @@ -181,32 +199,37 @@ window.addEventListener("keyup", function() { setTimeout(timerUpdate, 200); } );
timeUI(); timeUI(); var timerUI_id = document.getElementById("timerUI");
function timeUI() { function timeUI() {
checkMediaType(); checkMediaType(); // add timerUI if it does not already exist // add timerUI if it does not already exist if ( ( ! document.getElementById("timerUI") ) && playerExists == 1 ) {
// parent element appendChildWithID("div","timerUI"); var timerUI_id = document.getElementById("timerUI");
// background gradient // background gradient appendChildWithID("div","bottomGradient",timerUI_id ); addStyle("#bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top, "+timeUI_color+", rgba(0,0,0,0) ); opacity:0.2; height:80pt; width:100%; bottom:0; pointer-events:none; }"); addStyle("#bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top, "+timeUI_color+", rgba(0,0,0,0) ); opacity:0.2; height:80pt; width:100%; bottom:0; pointer-events:none; }");
// progress bar // progress bar appendChildWithID("div","progBar",timerUI_id ); addStyle("#progBar { display:block; position:fixed; background-color:"+timeUI_color+"; height:8pt; width:50%; bottom:0; }"); addStyle("#progBar { display:block; position:fixed; background-color:"+timeUI_color+"; height:8pt; width:50%; bottom:0; }");
// progress bar placeholder // progress bar placeholder appendChildWithID("div","progBarPlaceholder",timerUI_id ); addStyle("#progBarPlaceholder { display:block; position:fixed; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }") addStyle("#progBarPlaceholder { display:block; position:fixed; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }")
// timer // timer appendChildWithID("div","playTimer",timerUI_id ); document.getElementById("playTimer").innerHTML="00:00:00"; document.getElementById("playTimer").innerHTML="00:00:00"; addStyle("#playTimer { display:block; color:"+timeUI_color+"; position:fixed; font-size:50pt; bottom:0; line-height:80pt; right:25pt; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; }"); addStyle("#playTimer { display:block; color:"+timeUI_color+"; position:fixed; font-size:50pt; bottom:0; line-height:80pt; right:25pt; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; }");
// play/pause symbol // play/pause symbol appendChildWithID("div","playStatus",timerUI_id ); document.getElementById("playStatus").innerHTML="■"; document.getElementById("playStatus").innerHTML="■"; addStyle("#playStatus { display:block; color:"+timeUI_color+"; position:fixed; font-size:24pt; line-height:40pt; bottom:30pt; right:4pt; font-family:none; }"); addStyle("#playStatus { display:block; color:"+timeUI_color+"; position:fixed; font-size:24pt; line-height:40pt; bottom:30pt; right:4pt; font-family:none; }");
-
HT-7 created this gist
on May 14, 2022May 14, 2022 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Original file line Diff line number Diff line change @@ -0,0 +1,243 @@ // TimerUI
// == Dependencies ==
var mediaType; // for compatibility var playerExists = 0; // is set to 1 below if player exists var checkMediaType_enabled = 1; // for debugging purposes
function checkMediaType() { if ( checkMediaType_enabled == 1 ) { // checks whether it is a video or an audio tag mediaTypeBeforeCheck = mediaType; if (document.getElementsByTagName("video")[0]) { playerExists = 1; mediaType = "video"; } if (document.getElementsByTagName("audio")[0]) { playerExists = 1; mediaType = "audio"; } mediaTypeAfterCheck = mediaType; if (mediaTypeBeforeCheck != mediaTypeAfterCheck) // Only show media type in console if it has changed. console.log("Detected media type: " + mediaType); media_element = document.getElementsByTagName(mediaType)[0]; // Set back to 0 if no player is found after using customMediaElement. media_element ? playerExists=1 : playerExists=0; } }
function customMediaElement(custom_media_element) { checkMediaType_enabled = 0; if (custom_media_element) { playerExists = 1; media_element = custom_media_element; console.log("Custom media element set. Reset using checkMediaType_enabled=1."); } else { console.error("No such media element found."); } }
// Additional checks to ensure the player is detected window.onclick = function() { checkMediaType();timeUI(); }; window.addEventListener("keydown", function() { checkMediaType();timeUI(); } );
// mousedown status var mousedown_status; window.addEventListener("mousedown", function(){mousedown_status=true} ); window.addEventListener("mouseup", function(){mousedown_status=false} );
function appendChildWithID(tagName,tagID) { document.body.appendChild(document.createElement(tagName)); // add div document.body.lastElementChild.id=tagID; // give it ID }
function addStyle(new_style) { document.body.appendChild(document.createElement("style")); // add style document.body.lastElementChild.innerHTML = new_style; }
// HH:MM:SS timer function HMStimer_core(seconds) {
// hours time_HH = Math.floor( seconds/3600 ); // leading zero if ( seconds < 36000 ) time_HH = "0" + time_HH;
// minutes time_MM = Math.floor( seconds/60%60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM;
// seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS;
return time_HH+":"+time_MM+":"+time_SS; }
function HMStimer(seconds) { if (seconds >= 0) return HMStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+HMStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –:– –";
}
// MM:SS timer function MStimer_core(seconds) {
// minutes time_MM = Math.floor( seconds/60 ); // leading zero if ( seconds%3600 < 600 ) time_MM = "0" + time_MM;
// seconds time_SS = Math.floor( seconds%60 ); // leading zero if ( seconds%60 < 10 ) time_SS = "0" + time_SS;
return time_MM+":"+time_SS; }
function MStimer(seconds) { if (seconds >= 0) return MStimer_core(seconds); // zero or positive if (seconds < 0) // negative { seconds = seconds * (-1); return "-"+MStimer_core(seconds); } if (seconds == undefined || isNaN(seconds) ) return "– –:– –";
}
// implements togglePlay(); – deprecated due to compatibility issues on YouTube (broken site) and Dailymotion ("not a function" error through iframe'd player). /* Object.prototype.togglePlay = function togglePlay() { return this.paused ? this.play() : this.pause(); }; */
// new function without object prototype for compatibility function togglePlay(media_element) { media_element.paused ? media_element.play() : media_element.pause(); }
// == Custom domain rules == function isDomain(domain) { // Using .search() instead of .includes() to improve browser compatibility. if (window.location.hostname.search(domain) >= 0) return true; else return false; }
if (isDomain("dailymotion.com") && document.location.pathname.toString().search(/^\/embed\//)==(-1) ) // Dailymotion watch page, excluding embed page. customMediaElement(document.getElementById("player-body").contentWindow.document.getElementsByTagName("video")[0]);
// == Main code ==
var show_remaining_time = 0; // 0: show elapsed time. 1: show remaining time. 2: show both. var timer_update_during_seek = 1; // 1: update timer while dragging seek bar var timeUI_color = "rgb(49,136,255)"; // #38F – using RGB for compatibility.
function timerUpdate() { document.getElementById("progBar").style.width=media_element.currentTime / media_element.duration * 100 + "%";
switch(show_remaining_time) { // 0: "HH:MM:SS" 1: "-HH:MM:SS" 2: "MM:SS / MM:SS" or "HH:MM:SS / HH:MM:SS" case 0: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime); break; case 1: document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime-media_element.duration); break; case 2: if (media_element.duration < 3600 || isNaN(media_element) ) { // show hours if duration exceeds one hour document.getElementById("playTimer").innerHTML=MStimer(media_element.currentTime)+" / "+MStimer(media_element.duration); } else { document.getElementById("playTimer").innerHTML=HMStimer(media_element.currentTime)+" / "+HMStimer(media_element.duration); } break; }
media_element.paused == 0 ? document.getElementById("playStatus").innerHTML="▶" : document.getElementById("playStatus").innerHTML="⏸"; }
function timerColor(setColor) { timeUI_color = setColor; // for debugging document.getElementById("progBar").style.backgroundColor=setColor; document.getElementById("progBarPlaceholder").style.backgroundColor=setColor; document.getElementById("playTimer").style.color=setColor; document.getElementById("playStatus").style.color=setColor; document.getElementById("bottomGradient").style.backgroundImage="linear-gradient(to top,"+setColor+", rgba(0,0,0,0) )"; }
function timerFont(setFont) { document.getElementById("playTimer").style.fontFamily=setFont; }
// patch: prevent missing out on pausing from inside a site's existing player window.addEventListener("mouseup", function() { setTimeout(timerUpdate, 200); } ); window.addEventListener("keyup", function() { setTimeout(timerUpdate, 200); } );
timeUI();
function timeUI() {
checkMediaType(); // add timerUI if it does not already exist if ( ( ! document.getElementById("progBar") ) && playerExists == 1 ) {
// background gradient appendChildWithID("div","bottomGradient"); addStyle("#bottomGradient { display:block; position:fixed; background-image:linear-gradient(to top, "+timeUI_color+", rgba(0,0,0,0) ); opacity:0.2; height:80pt; width:100%; bottom:0; pointer-events:none; }");
// progress bar appendChildWithID("div","progBar"); addStyle("#progBar { display:block; position:fixed; background-color:"+timeUI_color+"; height:8pt; width:50%; bottom:0; }");
// progress bar placeholder appendChildWithID("div","progBarPlaceholder"); addStyle("#progBarPlaceholder { display:block; position:fixed; background-color:grey; height:8pt; width:100%; bottom:0; opacity:0.2; }")
// timer appendChildWithID("div","playTimer"); document.getElementById("playTimer").innerHTML="00:00:00"; addStyle("#playTimer { display:block; color:"+timeUI_color+"; position:fixed; font-size:50pt; bottom:0; line-height:80pt; right:25pt; font-weight:400; font-family:din,futura,'noto sans',ubuntu,'segoe ui',verdana,tahoma,roboto,'roboto light',arial,helvetica,'trebuchet ms',sans-serif,consolas,monospace; }");
// play/pause symbol appendChildWithID("div","playStatus"); document.getElementById("playStatus").innerHTML="■"; addStyle("#playStatus { display:block; color:"+timeUI_color+"; position:fixed; font-size:24pt; line-height:40pt; bottom:30pt; right:4pt; font-family:none; }");
// update timer during playback every fifteenth of a second and while mouse is dragging progress bar var timerUpdateInterval = setInterval( function() { if ( ( timer_update_during_seek && mousedown_status ) || ! media_element.paused) timerUpdate(); } , 1000/15 );
// patch: prevent detaching from player on sites with playlists such as Internet Archive var checkMediaInterval = setInterval( checkMediaType,1000 );
// patch: prevent showing "▶" after playback finished var checkPaused = setInterval( function() { if (media_element.paused && document.getElementById("playStatus").innerHTML!="⏸") timerUpdate(); },1000 );
// play and pause toggle document.getElementById("playStatus").onclick = function() { togglePlay(media_element); timerUpdate(); }; // former code with object prototype caused compatibility issues on various sites: media_element.togglePlay();
// toggle between elapsed and remaining time document.getElementById("playTimer").onclick = function() { switch(show_remaining_time) { case 0: show_remaining_time = 1; break; case 1: show_remaining_time = 2; break; case 2: show_remaining_time = 0; break; }; timerUpdate(); };
timerUpdate(); } }