-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Replace Gist links with embedded Gist #820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/features/embed-gist-inline.js
Outdated
| import select from 'select-dom'; | ||
|
|
||
| const gistRegex = /gist\.github\.com\/\w*?\/\w*/; | ||
| const isGist = link => gistRegex.test(link.href); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This checks the current location. Do you mean to recreate the host or path check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never mind. I misread the code.
src/features/embed-gist-inline.js
Outdated
|
|
||
| const createGistElement = gistData => { | ||
| const el = document.createElement('div'); | ||
| const style = `<link rel="stylesheet" href="https://assets-cdn.github.com/assets/gist-embed-3cc724162479db25e452fdf621f2349adef3e742b53552c2a93f82d28156cb96.css" />`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
" /> → ">
src/features/embed-gist-inline.js
Outdated
| const createGistElement = gistData => { | ||
| const el = document.createElement('div'); | ||
| const style = `<link rel="stylesheet" href="https://assets-cdn.github.com/assets/gist-embed-3cc724162479db25e452fdf621f2349adef3e742b53552c2a93f82d28156cb96.css" />`; | ||
| el.innerHTML = style + gistData.div; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to do any sanitizing here? Probably better not to use .innerHTML too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The data from the gist is sanitised already, are we planning in case a gist response is somehow compromised?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know. I just asked in case anyone could think of a case. I guess it's fine then.
src/features/embed-gist-inline.js
Outdated
| .all('.js-comment-body p a[href^="https://gist.github.com"]:only-child') | ||
| .filter(isGist); | ||
|
|
||
| gistLinks.forEach(async link => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a for-of loop
src/features/embed-gist-inline.js
Outdated
| const gistEl = createGistElement(gistData); | ||
| const linkParent = link.parentNode; | ||
| linkParent.parentNode.replaceChild(gistEl, linkParent); | ||
| } catch (e) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e → err
src/features/embed-gist-inline.js
Outdated
| const isGist = link => gistRegex.test(link.href); | ||
|
|
||
| const getJsonUrl = href => `${href}.json`.replace(/\.jso?n?\.json$/, '.json'); | ||
| const getGistData = href => fetch(getJsonUrl(href)).then(response => response.json()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use async/await.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⬆️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More context: #814
src/features/embed-gist-inline.js
Outdated
| const gistRegex = /gist\.github\.com\/\w*?\/\w*/; | ||
| const isGist = link => gistRegex.test(link.href); | ||
|
|
||
| const getJsonUrl = href => `${href}.json`.replace(/\.jso?n?\.json$/, '.json'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand what /\.jso?n?\.json$/ is doing. Like, why are we only replacing names that end with .js or .json? Can you show me an example URL? I think this would be clearer regardless /\.(js|json)\.json$/.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is for if the person links specifically the json or js version, so it won't create a link like https://gist.github.com/user/gist.js.json, it's probably unlikely for someone to be linking it but just in case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, makes sense. I still would like to use /\.(js|json)\.json$/ as it's more readable.
Can you also add a short comment above it to explain what it's doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think .js and .json links should be embedded, they are technically not the same content (web page vs embed code)
src/features/embed-gist-inline.js
Outdated
| const getGistData = href => fetch(getJsonUrl(href)).then(response => response.json()); | ||
|
|
||
| const createGistElement = gistData => { | ||
| const el = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to use a variable here. Just return it directly.
|
Some more minor nitpick and it's good I think: |
|
Why are we injecting the Gist instead of just loading the Gist embed in an iframe? |
|
I'll get to this as soon as I can, I haven't forgotten about it! |
|
I took a look at an iframe solution, my main worry is the height as is always the case with iframes, it's difficult to set the height of the iframe to be correct for the height of the content. I can deal with this if required but do you think we are gaining from this? |
|
It seems the linter does not like await in for of loops although (as far as I'm aware) that is correct usage. |
src/features/embed-gist-inline.js
Outdated
| @@ -1,30 +1,29 @@ | |||
| import { h } from 'dom-chef'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this removed? I think it’s required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good catch, my brain was still in iframe refactor mode when I deleted it
|
The linter complains because the loop stops at every await, which means that gists are loaded sequentially rather than in parallel. If you want to use await but load in parallel, extract the loop content into an async function and call it normally from inside the loop, don’t await the call. |
|
@sindresorhus is there an iframe version? My understanding is that this is the preferred injection method. Their official embed code is a script tag with document.write |
|
@sindresorhus this is the closest I got with an iframe, but it's sadly blocked by GH's CSP <iframe srcdoc="<script src="https://gist.github.com/jgierer12/06a8e3913ce4ae608c010b6f47efd257.js"></script>">But you're right, the current solution of injecting the code directly inline isn't working right because of conflicting styles.
However the Shadow DOM seems to work correctly and is quite easy to implement it: link.attachShadow({mode: 'open'}).append(gistEl);CSP also applies so it still requires the manual |
|
Thanks for the help with this @bfred-it |
source/features/embed-gist-inline.js
Outdated
| ); | ||
|
|
||
| async function embedGist(link) { | ||
| const response = await fetch(link.href + '.json'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use template literal here.
|
Looks great now :) Last thing, can you mention it in the "new feature" highlight in the readme and link to a screenshot showing it in action? https://github.com/sindresorhus/refined-github#new-features |
|
That's all complete now @sindresorhus |
|
Yay. Thanks for contributing this and for your patience through the review rounds :) |




Replaces links with an embedded gist and also injects the stylesheet as a link. Only replaces links that are on their own line and in a comment body of a pr or issue.
Fixes #494