Instantly share code, notes, and snippets.
Last active
March 16, 2017 21:09
-
Star
0
(0)
You must be signed in to star a gist -
Fork
1
(1)
You must be signed in to fork a gist
-
Save gfscott/aec1603bfbcbbf784261 to your computer and use it in GitHub Desktop.
Related Link Creator
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
<!doctype html> | |
<html lang="en_CA"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Related Link Builder</title> | |
<style> | |
*, *:before, *:after { | |
box-sizing: border-box; | |
} | |
body { | |
max-width: 40em; | |
margin: 0 auto; | |
padding: 0; | |
} | |
hr { | |
margin: 2em 0; | |
border: 0; | |
border-top: solid 1px #ddd; | |
} | |
#url_wrap { | |
margin-top: 6em; | |
margin-bottom: 2em; | |
} | |
#url { | |
display: block; | |
margin: 0.5em 0; | |
width: 100%; | |
font-size: 1.4em; | |
} | |
#code { | |
display: block; | |
width: 100%; | |
height: 250px; | |
padding: 1em; | |
font-size: 1.2em; | |
font-family: monospace; | |
background-color: #444; | |
color: #eee; | |
border: 0; | |
} | |
button, | |
input[type="submit"] { | |
margin-top: 1rem; | |
padding: 0.5rem 1rem; | |
font-size: 1.4em; | |
background: dodgerblue; | |
border: none; | |
border-radius: 0.2em; | |
cursor: pointer; | |
color: #fff; | |
} | |
button:hover, | |
input[type="submit"]:hover, | |
input[type="submit"]:focus, | |
.zeroclipboard-is-hover { | |
background-color: crimson; | |
} | |
#copy.aftercopy:after { | |
position: absolute; | |
content: "Code has been copied to your clipboard!"; | |
margin-left: 2rem; | |
color: #777; | |
} | |
@-webkit-keyframes ball-scale-ripple-multiple { | |
0% { | |
-webkit-transform: scale(0.1); | |
transform: scale(0.1); | |
opacity: 1; } | |
70% { | |
-webkit-transform: scale(1); | |
transform: scale(1); | |
opacity: 0.7; } | |
100% { | |
opacity: 0.0; } } | |
@keyframes ball-scale-ripple-multiple { | |
0% { | |
-webkit-transform: scale(0.1); | |
transform: scale(0.1); | |
opacity: 1; } | |
70% { | |
-webkit-transform: scale(1); | |
transform: scale(1); | |
opacity: 0.7; } | |
100% { | |
opacity: 0.0; } } | |
.ball-scale-ripple-multiple { | |
position: relative; | |
-webkit-transform: translateY(-25px); | |
-ms-transform: translateY(-25px); | |
transform: translateY(-25px); } | |
.ball-scale-ripple-multiple > div:nth-child(0) { | |
-webkit-animation-delay: -0.8s; | |
animation-delay: -0.8s; } | |
.ball-scale-ripple-multiple > div:nth-child(1) { | |
-webkit-animation-delay: -0.6s; | |
animation-delay: -0.6s; } | |
.ball-scale-ripple-multiple > div:nth-child(2) { | |
-webkit-animation-delay: -0.4s; | |
animation-delay: -0.4s; } | |
.ball-scale-ripple-multiple > div:nth-child(3) { | |
-webkit-animation-delay: -0.2s; | |
animation-delay: -0.2s; } | |
.ball-scale-ripple-multiple > div { | |
-webkit-animation-fill-mode: both; | |
animation-fill-mode: both; | |
position: absolute; | |
top: -2px; | |
left: -26px; | |
width: 50px; | |
height: 50px; | |
border-radius: 100%; | |
border: 2px solid #777; | |
-webkit-animation: ball-scale-ripple-multiple 1.25s 0s infinite cubic-bezier(0.21, 0.53, 0.56, 0.8); | |
animation: ball-scale-ripple-multiple 1.25s 0s infinite cubic-bezier(0.21, 0.53, 0.56, 0.8); } | |
#loader { | |
margin: 2em 50% auto; | |
width: 100%; | |
} | |
.invisible { | |
/* By default stuff is invisible at the start and appears once the data is in */ | |
opacity: 0; | |
} | |
.invisible.fadein { | |
/* use a class to add transition only to objects that need fading */ | |
transition-property: opacity; | |
transition-duration: 0.3s; | |
} | |
.invisible.visible { | |
opacity: 1; | |
} | |
#preview > p { | |
color: #999; | |
} | |
</style> | |
</head> | |
<body> | |
<form id="url_wrap"> | |
<label for="url">Paste a URL:</label> | |
<input name="url" type="text" id="url"> | |
<input type="submit" value="Create"> | |
</form> | |
<div id="loader" class="invisible"> | |
<div class="ball-scale-ripple-multiple"> | |
<div></div><div></div><div></div><div></div> | |
</div> | |
</div> | |
<textarea id="code" class="invisible fadein"></textarea> | |
<button id="copy" class="invisible fadein" data-clipboard-target="#code">Copy This Code</button> | |
<div id="preview" class="invisible fadein"> | |
<hr> | |
<h3>Preview:</h3> | |
<h5>This is only an approximation! For instance, links will take on your site’s theme colours.</h5> | |
<p>...sapiente provident libero alias incidunt nesciunt molestiae quam saepe aliquid eaque ullam.</p> | |
<div id="preview_pane"></div> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum sed voluptas vitae saepe tenetur voluptatem dicta repellendus doloremque culpa asperiores aliquam rem, nemo ea, excepturi, fugit debitis recusandae numquam. Delectus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum sed, id a eos repellendus cum nobis nulla, ab, quae molestias provident dolor soluta fugit sequi iusto ipsam porro sint quo. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi distinctio, maiores numquam, ut laudantium autem qui sint. Distinctio suscipit dignissimos itaque, dicta. Quae tempore ipsa explicabo doloribus totam eaque deleniti!</p> | |
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa...</p> | |
<h5>Problems? Questions? Contact graham.scott in the Rogers email system.</h5> | |
</div> | |
<script src="https://cdn.rawgit.com/zenorocha/clipboard.js/v1.6.0/dist/clipboard.min.js"></script> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/zeroclipboard/2.2.0/ZeroClipboard.js"></script> --> | |
<script> | |
"use strict"; | |
var url_wrap, url, loader, code, copier, preview, previewPane; | |
url_wrap = document.getElementById("url_wrap"); | |
url = document.getElementById("url"); | |
loader = document.getElementById("loader"); | |
code = document.getElementById("code"); | |
copier = document.getElementById("copy"); | |
preview = document.getElementById("preview"); | |
previewPane = document.getElementById("preview_pane"); | |
// focus onload | |
window.onload = function(){ | |
url.focus(); | |
}; | |
// block form submission | |
url_wrap.onsubmit = function(e){ | |
e.preventDefault(); | |
}; | |
url.onchange = function() { | |
var link = url.value; | |
getMeta(link); | |
loader.classList.add("visible"); | |
} | |
// AJAX wrapper to fetch metadata | |
function getMeta( link ) { | |
var request = new XMLHttpRequest(); | |
var endpoint = "https://api.urlmeta.org/?url=" + link; | |
request.open("GET", endpoint, true); | |
request.onload = function(){ | |
if ( request.status >= 200 && request.status < 400 ) { | |
var data = JSON.parse(request.responseText); | |
thrash(data); | |
} else { | |
console.error("Server returned an error"); | |
} | |
}; | |
request.onerror = function() { | |
console.error("The server could not be contacted for some reason!"); | |
}; | |
request.send(); | |
} | |
// | |
function thrash( data ) { | |
if ( data.result.status === "OK" ) { | |
layout(data.meta); | |
} else if ( data.result.code = 2 ) { | |
error_noUrl(); | |
} else { | |
console.error("Error: " + data.result.reason + ". Code: " + data.result.code ); | |
} | |
layout(data); | |
} | |
function layout(obj) { | |
console.log(obj.title); | |
// note that obj is ONLY the meta data contained in data.meta, returned from the meta service. We want url, title, and image | |
// There's a standard string appended to page titles by default. Just lop it off the end of the title. | |
let titleJunk = " - Canadian Business - Your Source For Business News"; | |
obj.title = obj.title.replace(titleJunk, ""); | |
// Weird thing: The line directly above will throw an error because there are two instances of obj.title — one is the actual string we want, which replaces correctly. The other is a phantom "title" attribute that will be undefined and therefore throw an error. The string replacement occurs properly, however. | |
// UrlMeta | |
var output = '<style>.cbR{box-sizing:border-box;display:block;width:100%;margin:1em 0;border:1px solid #bbb;padding:.5em}@media (min-width:480px){.cbR{width:250px;margin:0 0 1em 1em;float:right}}</style><div class="cbR"><a href="' + obj.url + '" target="_blank"><img style="max-width:100%" src="' + obj.image + '" alt="" /></a><a href="' + obj.url + '" target="_blank"><strong>' + obj.title + '</strong></a></div>'; | |
// embedly | |
// var output = '<style>.cbR{box-sizing:border-box;display:block;width:100%;margin:1em 0;border:1px solid #bbb;padding:.5em}@media (min-width:480px){.cbR{width:250px;margin:0 0 1em 1em;float:right}}</style><div class="cbR"><a href="' + obj.url + '" target="_blank"><img style="max-width:100%" src="' + obj.thumbnail_url + '" alt="" /></a><a href="' + obj.url + '" target="_blank"><strong>' + obj.title + '</strong></a></div>'; | |
// output the markup | |
code.value = output; | |
// output the preview | |
previewPane.innerHTML = output; | |
// hide the loader again | |
loader.classList.remove("visible"); | |
// fade in all the previously hidden stuff; | |
code.classList.add("visible"); | |
copy.classList.add("visible"); | |
preview.classList.add("visible"); | |
} | |
function error_noUrl() { | |
console.error("This doesn’t appear to be a valid URL!"); | |
// This will be replaced with a better user-facing message | |
} | |
// Copy to clipboard | |
// Dependency: ClipboardJS | |
// https://clipboardjs.com/ | |
// https://github.com/zenorocha/clipboard.js | |
var clipboard = new Clipboard('#copy'); | |
clipboard.on("success", function(e){ | |
copy.classList.add("aftercopy"); | |
}); | |
// Copy to clipboard | |
// Dependency: ZeroClipboard | |
// | |
// DEPRECATED 2017-03-16 because let's not use flash any more | |
// | |
// ZeroClipboard.config( { swfPath: "https://cdnjs.cloudflare.com/ajax/libs/zeroclipboard/2.2.0/ZeroClipboard.swf" } ); | |
// | |
// var client = new ZeroClipboard( copy ); | |
// client.on("ready", function( event ){ | |
// | |
// // console.log("clipboard is ready"); | |
// | |
// client.on("copy", function( event ) { | |
// var clipboard = event.clipboardData; | |
// clipboard.setData("text/plain", code.value); | |
// }); | |
// | |
// client.on("aftercopy", function ( event ) { | |
// copy.classList.add("aftercopy"); | |
// }); | |
// | |
// }); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment