Last active
December 15, 2020 14:49
-
-
Save edudobay/8cea2e2f2e670a0f24d5cd50c0133834 to your computer and use it in GitHub Desktop.
Embed Google Docs into GitLab (user script)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Embed Google Docs into GitLab | |
// @namespace http://github.com/edudobay/ | |
// @website https://gist.github.com/edudobay/8cea2e2f2e670a0f24d5cd50c0133834 | |
// @updateURL https://gist.github.com/edudobay/8cea2e2f2e670a0f24d5cd50c0133834/raw/GitLab-Embed-GoogleDocs.userscript.js | |
// @downloadURL https://gist.github.com/edudobay/8cea2e2f2e670a0f24d5cd50c0133834/raw/GitLab-Embed-GoogleDocs.userscript.js | |
// @version 0.2 | |
// @description The name says it all. | |
// @author https://github.com/edudobay | |
// @match https://gitlab.com/* | |
// @grant none | |
// ==/UserScript== | |
(function () { | |
'use strict'; | |
Promise.all([ | |
import('https://unpkg.com/preact?module'), | |
import('https://unpkg.com/htm?module'), | |
import('https://unpkg.com/csstag?module'), | |
]).then(([ | |
{ h, Component, render }, | |
{ default: htm }, | |
{ default: csstag, appendStyles }, | |
]) => { | |
// Initialize htm with Preact | |
const html = htm.bind(h) | |
const css = csstag.bind(null, { prefix: 'gdembed' }) | |
const s = css` | |
.root {} | |
.button { | |
box-sizing: border-box; | |
width: 2em; | |
height: 2em; | |
padding: 2px 8px; | |
margin-left: 8px; | |
background-color: transparent; | |
border: 1px solid #4f4f4f; | |
color: #dfdfdf; | |
border-radius: 4px; | |
font-size: 150%; | |
box-shadow: inset 0 0 0 1px #707070; | |
} | |
.button:hover { | |
box-shadow: inset 0 0 0 2px #919191,0 2px 2px 0 rgba(0,0,0,0.08); | |
background: #2e2e2e; | |
font-weight: 600; | |
} | |
.button:active { | |
box-shadow: inset 0 0 0 2px #a7a7a7,0 0 0 4px rgba(31,120,209,0.25); | |
outline: none; | |
background-color: #4f4f4f; | |
} | |
.controls { | |
text-align: right; | |
padding-bottom: 4px; | |
} | |
.embed { | |
width: 100%; | |
height: 600px; | |
} | |
.embed--collapsed { | |
height: 200px; | |
} | |
` | |
// CSS Utilities | |
function classes(...classNames) { | |
return classNames.filter(c => c).join(' ') | |
} | |
// Components | |
function MetaPanel({ retry }) { | |
return html` | |
<button type="button" onClick=${retry} class="btn js-pipelines-retry-button btn-retry btn-default btn-md gl-button btn-default-secondary btn-icon"> | |
<svg data-testid="repeat-icon" class="gl-icon s16"> | |
<use href="https://gitlab.com/assets/icons-795a2ef2fd636a0538bbef3b8d2787dd90927b42d7617fdda8620930016b333d.svg#repeat"></use> | |
</svg> | |
</button> | |
` | |
} | |
function Button({ label, action }) { | |
return html` | |
<button | |
type=button | |
class=${s.button} | |
onClick=${action} | |
>${label}</button>` | |
} | |
function EmbedControls({ collapse, expand }) { | |
return html` | |
<div class=${s.controls}> | |
<${Button} action=${collapse} label="−" /> | |
<${Button} action=${expand} label="+" /> | |
</div> | |
` | |
} | |
class EmbeddedDocument extends Component { | |
constructor() { | |
super() | |
this.state = { collapsed: false } | |
} | |
render({ url }, state) { | |
const collapse = () => this.setState({ collapsed: true }) | |
const expand = () => this.setState({ collapsed: false }) | |
return html` | |
<div class=${s.root}> | |
<${EmbedControls} ...${{ collapse, expand }} /> | |
<iframe src=${url} class=${classes(s.embed, state.collapsed && s['embed--collapsed'])} /> | |
</div>` | |
} | |
} | |
function replaceLink(documentLink) { | |
const root = document.createElement('div') | |
documentLink.replaceWith(root) | |
render(h(EmbeddedDocument, { url: documentLink.href }), root) | |
} | |
// Render! | |
appendStyles() | |
function renderEmbeds() { | |
const googleDocumentLinks = document.body.querySelectorAll('.md a[href^="https://docs.google.com/document/d/e/"]') | |
for (const documentLink of googleDocumentLinks) { | |
replaceLink(documentLink) | |
} | |
} | |
function renderMetaPanel() { | |
const firstButton = document.body.querySelector('.detail-page-header-actions > button') | |
const panel = document.createElement('div') | |
panel.style.float = 'left' | |
firstButton.parentNode.insertBefore(panel, firstButton) | |
render(h(MetaPanel, { retry: renderEmbeds }), panel) | |
} | |
function renderAll() { | |
renderMetaPanel() | |
renderEmbeds() | |
} | |
renderAll() | |
}) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment