Last active
December 13, 2015 17:19
-
-
Save bonau/4947222 to your computer and use it in GitHub Desktop.
Assign filename in data URI
This file contains hidden or 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
| <!-- | |
| [Assign filename in data URI] | |
| Compatibility: Google Chrome 14 | |
| Origin from: http://html5-demos.appspot.com/static/a.download.html | |
| --> | |
| <!DOCTYPE html> | |
| <!-- | |
| Copyright 2011 Google Inc. | |
| Licensed under the Apache License, Version 2.0 (the "License"); | |
| you may not use this file except in compliance with the License. | |
| You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| Author: Eric Bidelman (ericbidelman@chromium.org) | |
| --> | |
| <html> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta http-equiv="X-UA-Compatible" content="chrome=1" /> | |
| <title>a[download]</title> | |
| <link href='http://fonts.googleapis.com/css?family=Droid+Sans' rel='stylesheet' type='text/css'> | |
| <style> | |
| ::selection { | |
| color: #eee; | |
| background: darkred; | |
| } | |
| html, body { | |
| height: 100%; | |
| overflow: hidden; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| body { | |
| color: #222; | |
| font-family: 'Droid Sans', arial, sans-serif; | |
| -webkit-font-smoothing: antialiased; | |
| background: -moz-radial-gradient(farthest-side, rgba(0,0,0,0) 90%, rgba(0,0,0,0.2) 150%) #fff; | |
| background: -webkit-gradient(radial, center center, 500, center center, 1400, from(rgba(0,0,0,0)), to(rgba(0,0,0,0.6))) #fff; | |
| display: -webkit-box; | |
| -webkit-box-orient: vertical; | |
| -webkit-box-align: center; | |
| -webkit-box-pack: center; | |
| display: -moz-box; | |
| -moz-box-orient: vertical; | |
| -moz-box-align: center; | |
| -moz-box-pack: center; | |
| display: -o-box; | |
| -o-box-orient: vertical; | |
| -o-box-align: center; | |
| -o-box-pack: center; | |
| width: 100%; /* for FF */ | |
| } | |
| body > section { | |
| position: relative; | |
| } | |
| a { | |
| color: #555; | |
| } | |
| a[data-disabled] { | |
| color: #ccc; | |
| text-decoration: line-through; | |
| } | |
| textarea { | |
| font-size: 100%; | |
| padding: 10px; | |
| border-radius: 5px; | |
| border: 1px solid #ccc; | |
| -webkit-box-shadow: 0 3px 7px #ccc inset; | |
| -moz-box-shadow: 0 3px 7px #ccc inset; | |
| -o-box-shadow: 0 3px 7px #ccc inset; | |
| -ms-box-shadow: 0 3px 7px #ccc inset; | |
| box-shadow: 0 3px 7px #ccc inset; | |
| outline: none; | |
| width: 500px; | |
| height: 100px; | |
| resize: none; | |
| } | |
| button { | |
| display: inline-block; | |
| background: -webkit-gradient(linear, 0% 40%, 0% 70%, from(#F9F9F9), to(#E3E3E3)); | |
| background: -webkit-linear-gradient(#F9F9F9 40%, #E3E3E3 70%); | |
| background: -moz-linear-gradient(#F9F9F9 40%, #E3E3E3 70%); | |
| background: -ms-linear-gradient(#F9F9F9 40%, #E3E3E3 70%); | |
| background: -o-linear-gradient(#F9F9F9 40%, #E3E3E3 70%); | |
| background: linear-gradient(#F9F9F9 40%, #E3E3E3 70%); | |
| border: 1px solid #999; | |
| -webkit-border-radius: 3px; | |
| -ms-border-radius: 3px; | |
| -o-border-radius: 3px; | |
| border-radius: 3px; | |
| padding: 5px 8px; | |
| outline: none; | |
| white-space: nowrap; | |
| -webkit-user-select: none; | |
| -moz-user-select: none; | |
| user-select: none; | |
| cursor: pointer; | |
| text-shadow: 1px 1px #fff; | |
| font-weight: 700; | |
| font-size: 10pt; | |
| } | |
| button:hover { | |
| border-color: black; | |
| } | |
| button:active { | |
| background: -webkit-gradient(linear, 0% 40%, 0% 70%, from(#E3E3E3), to(#F9F9F9)); | |
| background: -webkit-linear-gradient(#E3E3E3 40%, #F9F9F9 70%); | |
| background: -moz-linear-gradient(#E3E3E3 40%, #F9F9F9 70%); | |
| background: -ms-linear-gradient(#E3E3E3 40%, #F9F9F9 70%); | |
| background: -o-linear-gradient(#E3E3E3 40%, #F9F9F9 70%); | |
| background: linear-gradient(#E3E3E3 40%, #F9F9F9 70%); | |
| } | |
| ul { | |
| margin: 0; | |
| padding: 0; | |
| } | |
| li { | |
| list-style: none; | |
| } | |
| ul :last-child { | |
| margin-top: 10px; | |
| } | |
| details { | |
| position: absolute; | |
| top: 1em; | |
| left: 1em; | |
| margin: 1em 0; | |
| cursor: pointer; | |
| padding: 10px; | |
| background: #fff; | |
| border: 1px solid rgba(0,0,0,0.3); | |
| border-radius: 5px; | |
| max-width: 600px; | |
| font-size: 10pt; | |
| z-index: 100; | |
| } | |
| details > div { | |
| margin: 10px 0; | |
| } | |
| details blockquote { | |
| font-style: italic; | |
| } | |
| input[type="text"] { | |
| font-size: inherit; | |
| padding: 5px 7px; | |
| border-radius: 5px; | |
| border: 1px solid #ccc; | |
| outline: none; | |
| vertical-align: middle; | |
| } | |
| [contenteditable] { | |
| width: 500px; | |
| height: 200px; | |
| padding: 10px; | |
| border-radius: 5px; | |
| box-shadow: 0 3px 5px #ccc inset, 0 -1px 1px #ccc inset; | |
| margin-bottom: 1em; | |
| background: url('roughness_less.png') 50% 50%; | |
| } | |
| [contenteditable], | |
| input[type="text"] { | |
| -webkit-transition: all 0.2s ease-in-out; | |
| -moz-transition: all 0.2s ease-in-out; | |
| -o-transition: all 0.2s ease-in-out; | |
| -ms-transition: all 0.2s ease-in-out; | |
| transition: all 0.2s ease-in-out; | |
| color: #aaa; | |
| } | |
| [contenteditable]:hover, | |
| [contenteditable]:focus, | |
| input[type="text"]:hover, | |
| input[type="text"]:focus { | |
| outline: none; | |
| color: black; | |
| } | |
| aside:hover { | |
| opacity: 1; | |
| } | |
| aside { | |
| position: absolute; | |
| background: rgba(0,0,0,0.7); | |
| color: white; | |
| padding: 10px; | |
| border-radius: 5px; | |
| font-size: 10pt; | |
| width: 200px; | |
| display: inline-block; | |
| text-shadow: 1px 1px 1px black; | |
| top: 0; | |
| left: 0; | |
| opacity: 0; | |
| -webkit-transition: all 0.1s ease-in-out; | |
| -moz-transition: all 0.1s ease-in-out; | |
| -o-transition: all 0.1s ease-in-out; | |
| -ms-transition: all 0.1s ease-in-out; | |
| transition: all 0.1s ease-in-out; | |
| } | |
| aside:before { | |
| content: ''; | |
| width: 15px; | |
| height: 15px; | |
| background: -webkit-linear-gradient(45deg, rgba(0, 0, 0, 0.7) 50%, transparent 50%); | |
| background: -moz-linear-gradient(45deg, rgba(0, 0, 0, 0.7) 50%, transparent 50%); | |
| -webkit-transform: rotateZ(45deg); | |
| -moz-transform: rotateZ(45deg); | |
| -ms-transform: rotateZ(45deg); | |
| -o-transform: rotateZ(45deg); | |
| transform: rotateZ(45deg); | |
| left: -8px; | |
| top: 45px; | |
| position: absolute; | |
| } | |
| aside a { | |
| color: inherit; | |
| } | |
| output:hover + aside { | |
| opacity: 1; | |
| } | |
| #download-help { | |
| top: 200px; | |
| left: 420px; | |
| } | |
| h1 { | |
| color: #aaa; | |
| font-weight: normal; | |
| text-align: center; | |
| margin: 0 0 1.5em 0; | |
| font-size: 175%; | |
| line-height: 1.5; | |
| } | |
| h1 a { | |
| color: inherit; | |
| text-decoration: none; | |
| } | |
| h1 a:hover { | |
| padding-bottom: 3px; | |
| border-bottom: 2px solid #eee; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <details> | |
| <summary>What is this?</summary> | |
| <div> | |
| <p>A demo of the HTML5 <code>download</code> attribute. | |
| When used on an anchor, this attribute signifies that the resource it points to should be downloaded | |
| by the browser rather than navigating to it.</p> | |
| <p>'Create file' creates a .txt file from the <code>contenteditable</code> region's content. This is done | |
| by using <code>window.URL.createObjectURL()</code>. That generated file can be named and saved to | |
| the user's machine by setting the <code>download</code> attribute on a link.</p> | |
| <p><b>Browser support</b>: right now, only Chrome dev channel (14.0.835.15+) supports this attribute.</p> | |
| </div> | |
| </details> | |
| <h1>Navigating to a <a href="http://www.google.com/intl/en_com/images/srpr/logo2w.png" target="_blank">something</a> isn't cool. | |
| You know what's cool?<br> | |
| Telling the browser to <a href="http://www.google.com/intl/en_com/images/srpr/logo2w.png" download="MyGLogo">download it</a>.</h1> | |
| <section> | |
| <div id="container"> | |
| <div contenteditable>My epic novel that I don't want to lose.</div> | |
| <input type="text" value="MyFile.txt" placeholder="filename.txt"> | |
| <button onclick="downloadFile()">Create file</button> <output></output> | |
| <aside id="download-help"> | |
| <ul> | |
| <li>This link was created using a <code>blob:</code> URL | |
| ( <a href="http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers-bloburis" target="_blank">huh?</a> ). | |
| It contains the <code>download</code> attribute, which means clicking it will | |
| force the browser to download the resource rather than navigating to it.</li> | |
| <li>In Chrome, you can also drag this link out of the browser tab and the file | |
| will be saved. ( <a href="http://www.thecssninja.com/javascript/gmail-dragout" target="_blank">huh?</a> )</li> | |
| </ul> | |
| </aside> | |
| </div> | |
| </section> | |
| <script> | |
| var container = document.querySelector('#container'); | |
| var typer = container.querySelector('[contenteditable]'); | |
| var output = container.querySelector('output'); | |
| const MIME_TYPE = 'text/plain'; | |
| // Rockstars use event delegation! | |
| document.body.addEventListener('dragstart', function(e) { | |
| var a = e.target; | |
| if (a.classList.contains('dragout')) { | |
| e.dataTransfer.setData('DownloadURL', a.dataset.downloadurl); | |
| } | |
| }, false); | |
| document.body.addEventListener('dragend', function(e) { | |
| var a = e.target; | |
| if (a.classList.contains('dragout')) { | |
| cleanUp(a); | |
| } | |
| }, false); | |
| document.addEventListener('keydown', function(e) { | |
| if (e.keyCode == 27) { // Esc | |
| document.querySelector('details').open = false; | |
| } else if (e.shiftKey && e.keyCode == 191) { // shift + ? | |
| document.querySelector('details').open = true; | |
| } | |
| }, false); | |
| var cleanUp = function(a) { | |
| a.textContent = 'Downloaded'; | |
| a.dataset.disabled = true; | |
| // Need a small delay for the revokeObjectURL to work properly. | |
| setTimeout(function() { | |
| window.URL.revokeObjectURL(a.href); | |
| }, 1500); | |
| }; | |
| var downloadFile = function() { | |
| window.URL = window.webkitURL || window.URL; | |
| window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || | |
| window.MozBlobBuilder || window.Blob; // window.BlobBuilder is now deprecated | |
| var prevLink = output.querySelector('a'); | |
| if (prevLink) { | |
| window.URL.revokeObjectURL(prevLink.href); | |
| output.innerHTML = ''; | |
| } | |
| var bb = new BlobBuilder([typer.textContent], {type: MIME_TYPE}); | |
| var a = document.createElement('a'); | |
| a.download = container.querySelector('input[type="text"]').value; | |
| a.href = window.URL.createObjectURL(bb); | |
| a.textContent = 'Download ready'; | |
| a.dataset.downloadurl = [MIME_TYPE, a.download, a.href].join(':'); | |
| a.draggable = true; // Don't really need, but good practice. | |
| a.classList.add('dragout'); | |
| output.appendChild(a); | |
| a.onclick = function(e) { | |
| if ('disabled' in this.dataset) { | |
| return false; | |
| } | |
| cleanUp(this); | |
| }; | |
| // uncomment this to download directly | |
| /* | |
| var evt = document.createEvent("MouseEvents"); | |
| evt.initMouseEvent("click", true, true, window, | |
| 0, 0, 0, 0, 0, false, false, false, false, 0, null); | |
| var allowDefault = a.dispatchEvent(evt); | |
| */ | |
| }; | |
| </script> | |
| <script> | |
| var _gaq = _gaq || []; | |
| _gaq.push(['_setAccount', 'UA-22014378-1']); | |
| _gaq.push(['_trackPageview']); | |
| (function() { | |
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | |
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | |
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | |
| })(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment