| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- document.addEventListener('DOMContentLoaded', () => {
- const zoom = 0.25// From the pdf2htmlex parameter --zoom
- const zoomRatio = 1 / zoom
- const saveButton = document.getElementById('saveButton')
- const whiteoutButton = document.getElementById('whiteoutButton')
- const editTextButton = document.getElementById('editTextButton')
- const saveForm = document.getElementById('saveForm')
- const htmlInput = document.getElementById('htmlInput')
- const pageContainer = document.getElementById('page-container')
- let mode = null
- const toggleMode = newMode => {
- if (mode === newMode) newMode = null
- switch (mode) {
- case 'whiteout': disableWhiteout(); break;
- case 'editText': disableEditText(); break;
- }
- switch (newMode) {
- case 'whiteout': enableWhiteout(); break;
- case 'editText': enableEditText(); break;
- }
- mode = newMode
- }
- document.querySelectorAll('#page-container img').forEach(image => {
- image.addEventListener('click', () => {
- const selection = getSelection()
- selection.removeAllRanges()
- const range = document.createRange()
- range.selectNode(image)
- selection.addRange(range)
- console.log('selected?')
- })
- })
- saveButton.addEventListener('click', () => {
- htmlInput.value = document.documentElement.outerHTML
- saveForm.submit()
- })
- // Get screen to print ratio
- const localStyleSheets = Array.from(document.styleSheets).filter(x => !x.href)
- const pageOnePixelWidth = localStyleSheets.map(ss =>
- Array.from(ss.rules)
- .find(rule => rule.selectorText === '.w0' && rule.style.width.endsWith('px'))
- ).find(x => x).style.width.split('px')[0]
- const pageOnePointWidth = localStyleSheets.map(ss =>
- Array.from(ss.rules)
- .filter(rule => rule instanceof CSSMediaRule && rule.conditionText === 'print')
- .map(mediaRule =>
- Array.from(mediaRule.cssRules)
- .filter(rule => rule.selectorText === '.w0' && rule.style.width.endsWith('pt'))
- .find(x => x)
- ).find(x => x)
- ).find(x => x).style.width.split('pt')[0]
- const pixelsPerPoint = 1.3333333333333333
- const pageOnePrintPixelWidth = pageOnePointWidth * pixelsPerPoint
- const screenToPrintRatio = pageOnePrintPixelWidth / pageOnePixelWidth
- const printToScreenRatio = pageOnePixelWidth / pageOnePrintPixelWidth
- const myStyle = document.createElement('style')
- myStyle.type = 'text/css'
- myStyle.innerHTML = `
- @media screen {
- .replacement {
- zoom: ${printToScreenRatio};
- }
- }
- `
- document.head.appendChild(myStyle)
- // Whiteout
- let start = null
- const box = document.createElement('div')
- box.className = 'whiteout-box'
- whiteoutButton.addEventListener('click', () => toggleMode('whiteout'))
- const enableWhiteout = () => {
- whiteoutButton.classList.add('active')
- pageContainer.classList.add('whiteout')
- pageContainer.addEventListener('mousedown', whiteoutMouseDown)
- }
- const disableWhiteout = () => {
- whiteoutButton.classList.remove('active')
- pageContainer.classList.remove('whiteout')
- pageContainer.removeEventListener('mousedown', whiteoutMouseDown)
- }
- const whiteoutMouseDown = event => {
- start = {x: event.clientX, y: event.clientY}
- document.body.appendChild(box)
- drawBox(start, start)
- window.addEventListener('mousemove', whiteoutMouseMove)
- window.addEventListener('mouseup', whiteoutMouseUp)
- }
- const whiteoutMouseMove = event => {
- let end = {x: event.clientX, y: event.clientY}
- drawBox(rect(start, end))
- }
- const whiteoutMouseUp = event => {
- let end = {x: event.clientX, y: event.clientY}
- document.body.removeChild(box)
- const selection = rect(start, end)
- console.log('whiteout', selection)
- whiteout(selection)
- window.removeEventListener('mousemove', whiteoutMouseMove)
- window.removeEventListener('mouseup', whiteoutMouseUp)
- }
- const rect = (a, b) => {
- const left = Math.min(a.x, b.x)
- const top = Math.min(a.y, b.y)
- const right = Math.max(a.x, b.x)
- const bottom = Math.max(a.y, b.y)
- return new DOMRect(left, top, right - left, bottom - top)
- }
- const drawBox = rect => {
- box.style.cssText = `
- top: ${rect.top - 1}px;
- left: ${rect.left - 1}px;
- width: ${rect.width}px;
- height: ${rect.height}px;
- `
- }
- const intersects = (r1, r2) =>
- !(r2.left > r1.right ||
- r2.right < r1.left ||
- r2.top > r1.bottom ||
- r2.bottom < r1.top)
- const whiteout = rect => {
- const elements = []
- const walk = (element) => {
- let elementRect
- if (element instanceof HTMLImageElement) {
- elementRect = element.getBoundingClientRect()
- } else {
- const range = document.createRange()
- range.selectNodeContents(element)
- elementRect = range.getBoundingClientRect()
- }
- if (intersects(rect, elementRect)) {
- if (element.childNodes && element.childNodes.length) {
- Array.from(element.childNodes).forEach(walk)
- } else if (element instanceof Text && element.textContent.length > 1) {
- while (element.textContent.length) {
- const next = element.splitText(1)
- walk(element)
- element = next
- }
- } else {
- elements.push(element)
- }
- }
- }
- walk(pageContainer)
- elements.forEach(element => {
- if (element instanceof Text) {
- const range = document.createRange()
- range.selectNodeContents(element)
- const elementRect = range.getBoundingClientRect()
- const replacement = document.createElement('span')
- replacement.className = 'replacement'
- replacement.style.cssText = `
- width: ${elementRect.width * zoomRatio * screenToPrintRatio}px;
- display: inline-block;
- position: relative;
- `
- element.replaceWith(replacement)
- } else if (element instanceof HTMLImageElement) {
- const canvas = document.createElement('canvas')
- canvas.width = element.offsetWidth * zoomRatio
- canvas.height = element.offsetHeight * zoomRatio
- const ctx = canvas.getContext('2d')
- ctx.fillStyle = 'white'
- ctx.drawImage(element, 0, 0, element.offsetWidth * zoomRatio, element.offsetHeight * zoomRatio)
- const elementRect = element.getBoundingClientRect()
- ctx.fillRect(
- (rect.x - elementRect.x) * zoomRatio,
- (rect.y - elementRect.y) * zoomRatio,
- rect.width * zoomRatio,
- rect.height * zoomRatio
- )
- element.src = canvas.toDataURL()
- }
- })
- }
- // Edit Text
- editTextButton.addEventListener('click', () => toggleMode('editText'))
- const enableEditText = () => {
- editTextButton.classList.add('active')
- pageContainer.classList.add('editText')
- document.querySelectorAll('.pc').forEach(page => {
- page.setAttribute('contenteditable', 'true')
- })
- }
- const disableEditText = () => {
- editTextButton.classList.remove('active')
- pageContainer.classList.remove('editText')
- document.querySelectorAll('.pc').forEach(page => {
- page.setAttribute('contenteditable', 'false')
- })
- }
- })
|