-
Notifications
You must be signed in to change notification settings - Fork 2
/
preload.js
80 lines (71 loc) · 2.89 KB
/
preload.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Canvas-based Google Docs:
// After May 2021, Google Docs makes a slow transition from HTML rendering to canvas rendering
// We monkey patch key canvas methods to detect invisible lines and style them as dotted lines instead
const clazz = 'google-docs-utility-override' // duplicated in content.js
var elt = document.createElement('script')
elt.innerHTML = `
(() => { // don't leak
// Monkey patch the getContext method
const orig = window.HTMLCanvasElement.prototype.getContext
window.HTMLCanvasElement.prototype.getContext = function () {
try {
const context = orig.apply(this, arguments)
let cache = {} // don't redraw more than one overlapping line
// Called to before redrawing; forget about overlapping lines so as to redraw
const clearRect = context.clearRect
context.clearRect = function () {
clearRect.apply(context, arguments)
cache = {}
}
const rect = context.rect
context.rect = function () {
// i.e. if the lines are small and don't reach the end of the page and the plugin is enabled
if (context.lineWidth === 1 && arguments[0] > 5 && document.body.classList.contains('${clazz}')) { // 5 being the edge of the page
// Keep previous state
const lineDashOffset = context.lineDashOffset
const strokeStyle = context.strokeStyle
const lineDash = context.getLineDash()
// Set dotted line
context.setLineDash([4, 2])
context.strokeStyle = '#00000038'
context.beginPath()
const [x, y, w, h] = arguments
const combos = [
[[x, y], [x + w, y]],
[[x, y], [x, y + h]],
[[x + w, y], [x + w, y + h]],
[[x, y + h], [x + w, y + h]]
]
combos.forEach(([a, b], i) => {
const s = 10 // sensitivity: some lines are very close to one another
// TODO: find overlapping lines of different height
const key = JSON.stringify([a.map(e => Math.round(e / s) * s), b.map(e => Math.round(e / s) * s)])
if (!cache[key]) { // don't draw overlapping lines
if (i <= 1){
// The top and left sides of rectangles are offsetted by 1
context.moveTo(...a.map(e => e - 1))
context.lineTo(...b.map(e => e - 1))
} else {
context.moveTo(...a)
context.lineTo(...b)
}
cache[key] = true
}
})
context.stroke()
context.closePath()
// Reset the context
context.setLineDash(lineDash)
context.lineDashOffset = lineDashOffset
context.strokeStyle = strokeStyle
}
rect.apply(context, arguments)
}
return context
} catch (e) {
console.error(e)
}
}
})()
`
;(document.head || document.documentElement).appendChild(elt)