Skip to content

Instantly share code, notes, and snippets.

@edudobay
Last active December 15, 2020 14:49
Show Gist options
  • Save edudobay/8cea2e2f2e670a0f24d5cd50c0133834 to your computer and use it in GitHub Desktop.
Save edudobay/8cea2e2f2e670a0f24d5cd50c0133834 to your computer and use it in GitHub Desktop.
Embed Google Docs into GitLab (user script)
// ==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