import html from 'nanohtml'; import { remoteFunction } from 'webextension-rpc'; import { createMediaFragmentIdentifier } from '../util/media-fragment-identifier'; function createPreciseUrl(url, selector) { const properUrl = url.split('#')[0]; let fragmentIdentifier; if (selector.type === 'FragmentSelector') { fragmentIdentifier = selector.value; } else { throw new Error('Unsupported selector type'); } return properUrl + '#' + fragmentIdentifier; } function describeMediaFragment({ start, end }) { const fragmentIdentifier = createMediaFragmentIdentifier({ start, end }); const selector = { type: 'FragmentSelector', conformsTo: 'http://www.w3.org/TR/media-frags/', value: fragmentIdentifier, }; return selector; } async function init() { let menuEl; function hideMenu() { if (!menuEl) return; menuEl.parentNode.removeChild(menuEl); menuEl = undefined; } function onContextMenu(event) { event.preventDefault(); const left = event.pageX; const top = event.pageY; const playlist = self.playlist; if (!playlist) { throw new Error('Player has not been initialised.'); } const trackDuration = playlist.duration; let { start, end } = playlist.getTimeSelection(); if (start === undefined) return; // Waveform Playlist tells us end=start when the selection is just a single line. if (end === start) end = undefined; // Round the numbers to two decimals. // Also, as Waveform Playlist might report a slightly negative number, first cap it to zero. start = Math.round(Math.max(0, start) * 100) / 100; if (end !== undefined) end = Math.round(Math.max(0, end) * 100) / 100; async function createBookmark() { const fileUrl = document.URL; const selector = describeMediaFragment({ start, end }); const bookmarkUrl = createPreciseUrl(fileUrl, selector); await remoteFunction('createBookmark')({ url: bookmarkUrl, start, end, trackDuration }); } hideMenu(); menuEl = html` `; document.body.appendChild(menuEl); } document.addEventListener('contextmenu', onContextMenu, false); document.addEventListener('click', event => { hideMenu(); }); } init();