// ==UserScript== | |
// @name geekVideoSeek | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description try to take over the world! | |
// @author You | |
// @match https://u.geekbang.org/lesson/* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// Your code here... | |
const pat = /((?:\d{1,2}\W*[::]\ ?\W*)?\d{1,2}\W*[::]\ ?\W*\d{1,2})\W*-/g | |
function waitForResult(func, interval = 1000, maxTrials = 10) { | |
return new Promise((resolve, reject) => { | |
let trial = 1 | |
function wait() { | |
const res = func() | |
if (res) { | |
resolve(res) | |
return | |
} | |
trial++ | |
if (trial >= maxTrials) { | |
reject(new Error('max trials exceeded')) | |
return | |
} | |
setTimeout(wait, interval) | |
} | |
wait() | |
}) | |
} | |
function toSeconds(text) { | |
return text.split(/[::]/).reduce((acc, val) => acc * 60 + Number(val), 0) | |
} | |
function seekVideo(seconds) { | |
const video = document.querySelector('video') | |
video.currentTime = seconds | |
} | |
function createButton(text) { | |
const res = document.createElement('button') | |
res.innerText = text | |
res.setAttribute('style', [ | |
'background: none;', | |
'border: none;', | |
'padding: 0;', | |
'color: #069;', | |
'text-decoration: underline;', | |
'cursor: pointer;', | |
'display: block;', | |
].join(' ')) | |
return res | |
} | |
waitForResult(() => { | |
const res = [...document.querySelectorAll('li, p')] | |
.filter(e => e.innerText.match(pat) !== null) | |
if (res.length > 0) return res | |
}) | |
.then(res => { | |
for (const e of res) { | |
const str = e.innerText | |
e.innerText = '' | |
const matches = [...str.matchAll(pat)] | |
const startIndices = matches.map(m => m.index).concat(str.length) | |
for (let i = 0; i < matches.length; i++) { | |
const seconds = toSeconds(matches[i][1]) | |
const caption = str.substring(startIndices[i], startIndices[i + 1]) | |
const btn = createButton(caption) | |
btn.onclick = () => seekVideo(seconds) | |
e.appendChild(btn) | |
} | |
} | |
}) | |
.catch(err => { | |
console.error(err) | |
}) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment