Skip to content

Instantly share code, notes, and snippets.

@o0101
Last active November 4, 2017 05:26
Show Gist options
  • Save o0101/3ef33431114be0fb28e7e37790d2e325 to your computer and use it in GitHub Desktop.
Save o0101/3ef33431114be0fb28e7e37790d2e325 to your computer and use it in GitHub Desktop.
(async function (){
try {
const {width,height} = getDOMRect();
const doc = document.implementation.createHTMLDocument('');
doc.write(document.head.outerHTML);
const dom = getSelectedDOMOrBody();
doc.write(dom.outerHTML);
doc.documentElement.setAttribute('xmlns', doc.documentElement.namespaceURI);
const page = `<article id=fantasticprogress style="z-index:1000000000;width:100vw;height:100vh;position: fixed;top:0;left:0;background:rgba(50,50,50,0.5);display:flex;justify-content:center;align-items:center;">
<span style="background:#af1;">Loading...</span><progress id=updatingprogressbar max=${document.styleSheets.length} value=0></progress></article>`;
document.body.insertAdjacentHTML('beforeEnd', page);
const styles = [];
for( let i = 0; i < document.styleSheets.length; i++ ) {
const ss = document.styleSheets[i];
if ( ss.cssRules ) {
for( let j = 0; j < ss.cssRules.length; j++ ) {
styles.push( ss.cssRules[j].cssText );
}
} else {
try {
const res = await fetch(ss.href);
const cssText = await res.text();
styles.push(cssText);
} catch(e) {
try {
const res = await fetch(`https://dompeg-proxy-90jseygqo65r.runkit.sh/?url=${btoa(ss.href)}`);
const cssText = await res.text();
styles.push(cssText);
} catch(e) {
console.warn(`Exception adding styles from ${ss.href}`, e, e.stack);
}
}
}
updatingprogressbar.value += 1;
}
Array.from( doc.querySelectorAll('noscript, link, script')).forEach( el => el.remove() );
stripComments(doc);
Array.from( doc.querySelectorAll('*[style]')).forEach( el => {
const styleText = el.getAttribute('style');
const uniq = (Math.random()+''+performance.now()).replace(/\./g,'x');
const className = `class${uniq}`;
const cssText = `.${className} {${ styleText }}`;
styles.push( cssText );
el.classList.add( className );
});
const styleElement = doc.createElement('style');
styleElement.innerText = styles.join('\n');
doc.documentElement.appendChild(styleElement);
const canvas = document.createElement('canvas');
Object.assign( canvas, {width,height});
const ctx = canvas.getContext('2d');
const data = `
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">
<foreignObject width="100%" height="100%">
${(new XMLSerializer).serializeToString(doc).slice(15)}
</foreignObject>
</svg>`;
const DOMURL = window.URL || window.webkitURL || window;
const img = new Image();
const svg = new Blob([data], {type: 'image/svg+xml'});
Object.assign( img, {width,height});
img.crossOrigin = "Anonymous";
img.onload = function() {
ctx.fillStyle = 'white';
ctx.fillRect( 0, 0, canvas.width, canvas.height );
ctx.drawImage(img, 0, 0);
const datauri = canvas.toDataURL('image/jpeg');
const anchor = document.createElement('a');
anchor.download = 'screen.jpg';
anchor.href = datauri;
anchor.target = "_new";
anchor.innerText = 'download screen.jpg';
anchor.addEventListener('click', e => {e.stopPropagation();anchor.remove();}, { capture: true });
document.body.appendChild(anchor);
Object.assign( anchor.style, {
position: 'fixed',
background:'white',
fontSize: '18px',
fontFamily: 'monospace',
color: 'blue',
top: 0,
left: 0,
zIndex: Number.MAX_SAFE_INTEGER
});
}
img.src = buildSvgImageUrl(data);
img.style.position = "absolute";
img.style.zIndex = "10000000";
img.style.backgroundColor = "white";
window.open(URL.createObjectURL(svg));
fantasticprogress.remove();
} catch(e) {
alert("Capture did not work. Please re-select or reload the page and try again. See the console for a copy of the error.");
console.warn("Capture did not work", e );
}
function buildSvgImageUrl(svg) {
const b64 = btoa(unescape(encodeURIComponent(svg)));
return "data:image/svg+xml;base64," + b64;
}
function stripComments(docNode){
const commentWalker = docNode.evaluate('//comment()', docNode, null, XPathResult.ANY_TYPE, null);
let comment = commentWalker.iterateNext();
const cuts = [];
while (comment) {
cuts.push(comment);
comment = commentWalker.iterateNext();
}
cuts.forEach( node => node.remove());
}
function getSelectedDOMOrBody() {
const sel = getSelection();
if ( ! sel || ! sel.rangeCount ) {
return document.body.cloneNode(true);
}
const df = sel.getRangeAt(0).cloneContents();
if ( df.childNodes.length > 1 ) {
const body = document.createElement('body');
body.appendChild(df);
return body;
} else if ( df.childNodes.length == 1 ) {
return df.childNodes[0];
}
}
function getDOMRect() {
const sel = getSelection();
if ( ! sel || ! sel.rangeCount ) {
const windowEl = document.scrollingElement || document.documentElement;
const {scrollWidth:width,scrollHeight: height} = windowEl;
return {width,height};
}
const {width,height} = sel.getRangeAt(0).cloneRange().getBoundingClientRect();
return {width: width+32, height: height+32};
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment