Skip to content

Commit

Permalink
Merge pull request #52 from N1ck/fix-extension-injection
Browse files Browse the repository at this point in the history
  • Loading branch information
N1ck authored Nov 29, 2022
2 parents 1192352 + 4a99c96 commit 62acf8d
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 37 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@
},
"dependencies": {
"@giphy/js-fetch-api": "^1.7.0",
"code-tag": "^1.1.0",
"debounce-fn": "^1.0.0",
"delegate": "^3.2.0",
"dom-chef": "^3.3.0",
"github-injection": "^1.0.1",
"github-injection": "^1.1.0",
"masonry-layout": "^4.2.2",
"mem": "^8.1.1",
"onetime": "^2.0.1",
Expand Down
26 changes: 26 additions & 0 deletions src/lib/caller-id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Lovingly copied from https://github.com/refined-github/refined-github/blob/main/source/helpers/caller-id.ts
import hashString from './hash-string.js'

/**
Get unique ID by using the line:column of the call (or its parents) as seed. Every call from the same place will return the same ID, as long as the index is set to the parents that matters to you.
@param ancestor Which call in the stack should be used as key. 0 means the exact line where getCallerID is called. Defaults to 1 because it's usually used inside a helper.
*/
export default function getCallerID(ancestor = 1) {
/* +1 because the first line comes from this function */
return hashString(getStackLine(new Error('Get stack').stack, ancestor + 1))
}

export function getStackLine(stack, line) {
return (
stack
// Remove non-stacktrace line from array (missing in Firefox) #6032
.replace('Error: Get stack\n', '')
.split('\n')
.at(line) ?? warn(stack, line)
)
}

function warn(stack, line) {
console.warn('The stack doesn’t have the line', {line, stack})
return Math.random().toString(16)
}
10 changes: 10 additions & 0 deletions src/lib/hash-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Lovingly copied from https://github.com/refined-github/refined-github/blob/main/source/helpers/hash-string.ts
export default function hashString(string) {
let hash = 0

for (const character of string) {
hash = (hash << 5) - hash + character.codePointAt(0)
}

return String(Math.trunc(hash))
}
54 changes: 54 additions & 0 deletions src/lib/selector-observer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Lovingly copied from https://github.com/refined-github/refined-github/blob/main/source/helpers/selector-observer.tsx
// eslint-disable-next-line no-unused-vars
import React from 'dom-chef'
import {css} from 'code-tag'
import onetime from 'onetime'

import getCallerID from './caller-id.js'

const animation = 'rgh-selector-observer'
const getListener = (seenMark, selector, callback) =>
function (event) {
const target = event.target
// The target can match a selector even if the animation actually happened on a ::before pseudo-element, so it needs an explicit exclusion here
if (target.classList.contains(seenMark) || !target.matches(selector)) {
return
}

// Removes this specific selector’s animation once it was seen
target.classList.add(seenMark)

callback(target)
}

const registerAnimation = onetime(() => {
document.head.append(<style>{`@keyframes ${animation} {}`}</style>)
})

export default function observe(selectors, listener, {signal} = {}) {
if (signal?.aborted) {
return
}

const selector = String(selectors) // Array#toString() creates a comma-separated string
const seenMark = 'rgh-seen-' + getCallerID()

registerAnimation()

const rule = document.createElement('style')

rule.textContent = css`
:where(${String(selector)}):not(.${seenMark}) {
animation: 1ms ${animation};
}
`
document.body.prepend(rule)
signal?.addEventListener('abort', () => {
rule.remove()
})
window.addEventListener(
'animationstart',
getListener(seenMark, selector, listener),
{signal}
)
}
57 changes: 25 additions & 32 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ import LoadingIndicator from './components/loading-indicator.js'
import GiphyToolbarItem from './components/giphy-toolbar-item.js'
import Giphy from './lib/giphy.js'

import {
onDiffFileLoad,
onCommentEdit
} from './lib/github-events/on-fragment-load.js'
import observe from './lib/selector-observer.js'

// Create a new Giphy Client
const giphyClient = new Giphy('Mpy5mv1k9JRY2rt7YBME2eFRGNs7EGvQ')
Expand Down Expand Up @@ -65,7 +62,6 @@ async function watchGiphyModals(element) {
columnWidth: 145,
gutter: 10,
transitionDuration: '0.2s'
// FitWidth: true
},
2000
),
Expand All @@ -82,6 +78,7 @@ function addToolbarButton() {
'form:not(.ghg-has-giphy-field) markdown-toolbar'
)) {
const form = toolbar.closest('form')

const reviewChangesModal = toolbar.closest(
'#review-changes-modal .SelectMenu-modal'
)
Expand Down Expand Up @@ -111,8 +108,16 @@ function addToolbarButton() {
if (toolbarGroup) {
// Append the Giphy button to the toolbar
// cloneNode is necessary, without it, it will only be appended to the last toolbarGroup
toolbarGroup.append(GiphyToolbarItem.cloneNode(true))
const clonedNode = GiphyToolbarItem.cloneNode(true)
toolbarGroup.append(clonedNode)
select('.ghg-giphy-results', clonedNode)

form.classList.add('ghg-has-giphy-field')

// Clears the gif search input field and results.
// We have to do this because when navigating, github will refuse to
// load the giphy URLs as it violates their Content Security Policy.
resetGiphyModals()
}
})
}
Expand All @@ -122,11 +127,7 @@ function addToolbarButton() {
* Watches for comments that might be dynamically added, then adds the button the the WYSIWYG when they are.
*/
function observeDiscussion() {
const discussionTimeline = select('.js-discussion')

observeEl(discussionTimeline, () => {
addToolbarButton()
})
observe('md-task-list', () => addToolbarButton())
}

/**
Expand Down Expand Up @@ -207,7 +208,6 @@ function getFormattedGif(gif) {
)

// Generate a random pastel colour to use as an image placeholder

const hsl = `hsl(${360 * Math.random()}, ${25 + 70 * Math.random()}%,${
85 + 10 * Math.random()
}%)`
Expand Down Expand Up @@ -245,18 +245,19 @@ function appendResults(resultsContainer, gifs) {
resultsContainer.append(img)
}

// eslint-disable-next-line no-new
new Masonry(
resultsContainer,
{
itemSelector: '.ghg-giphy-results div',
columnWidth: 145,
gutter: 10,
transitionDuration: '0.2s'
// FitWidth: true
},
2000
)
setTimeout(() => {
// eslint-disable-next-line no-new
new Masonry(
resultsContainer,
{
itemSelector: '.ghg-giphy-results div',
columnWidth: 145,
gutter: 10,
transitionDuration: '0.2s'
},
10
)
})
}

/**
Expand Down Expand Up @@ -361,14 +362,6 @@ const listenOnce = onetime(listen)
// GitHubInjection fires when there's a pjax:end event
// on github, this happens when a page is loaded
gitHubInjection(() => {
addToolbarButton()
listenOnce()
observeDiscussion()
onDiffFileLoad(addToolbarButton)
onCommentEdit(addToolbarButton)

// Clears all gif search input fields and results.
// We have to do this because when navigating, github will refuse to
// load the giphy URLs as it violates their Content Security Policy.
resetGiphyModals()
})
13 changes: 9 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1974,6 +1974,11 @@ clone@^2.1.1:
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=

code-tag@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-tag/-/code-tag-1.1.0.tgz#8dc979c2bd2e2ac44d5a799abd07953e39cadf3d"
integrity sha512-qqvyRC9Fmnqy/1nK2Jz6FIk6F24nliVIVtQFg0r7PuZCZHfWO/c7eZHVlPxFKRSnOSIUUf/jrF1FG8j67FinPg==

collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz"
Expand Down Expand Up @@ -3492,10 +3497,10 @@ get-value@^2.0.3, get-value@^2.0.6:
resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz"
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=

github-injection@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/github-injection/-/github-injection-1.0.1.tgz"
integrity sha1-+tS+5nuYiZPFJ1VhAahxOCRe0Nw=
github-injection@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/github-injection/-/github-injection-1.1.0.tgz#3804bcb65cfdc302df49c8a5152bd43ac00aa95f"
integrity sha512-XoypofQSVTLaMlMlcp52Y6v+E58FhonB2iK2FzlBPRP/XxrnfJa4rEDgiD5phiki2jeW5oaP+tcwplbiiA3rMg==

glob-parent@^3.1.0:
version "3.1.0"
Expand Down

0 comments on commit 62acf8d

Please sign in to comment.