Skip to content

Commit

Permalink
add note part
Browse files Browse the repository at this point in the history
  • Loading branch information
DrRingo committed May 27, 2024
1 parent bd03d23 commit e8d05ec
Show file tree
Hide file tree
Showing 5 changed files with 2,999 additions and 1 deletion.
9 changes: 9 additions & 0 deletions bin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Try it here: https://topaz.github.io/paste/

This is a no-datastore, client-side paste service. It turns text into [LZMA](https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm)-compressed, [Base64](https://en.wikipedia.org/wiki/Base64)-encoded URLs.

For example, here's [the service hosting (a version of) its own HTML](https://topaz.github.io/paste/#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).

Because the entire paste is inside the URL, there's no risk of losing your data because a 3rd-party service vanished or deleted old pastes. If you have the URL, you have the pasted data.

Uses [LZMA-JS](https://github.com/LZMA-JS/LZMA-JS) (© 2016 Nathan Rugg <[email protected]>).
169 changes: 169 additions & 0 deletions bin/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8"/>
<title>paste</title>
<style>
* {
box-sizing: border-box;
font-family: monospace;
font-size: 1.1em;
}
#plaintext {
width: 100%;
height: 100%;
padding: .5em;
border: 0;
margin: 0;
resize: none;
color: #eeeeee;
background: #000000;
}
body.invert #plaintext {
color: #000000;
background: #eeeeee;
}
#plaintext-wrapper {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 2em;
}
#nav {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 2em;
line-height: 2em;
text-align: right;
vertical-align: middle;
background: #333333;
color: #ffffff;
white-space: nowrap;
}
body.invert #nav {
background: #aaaaaa;
color: #000000;
}
#nav .nav-left {
float: left;
}
#nav a {
display: inline-block;
padding: 0 .5em;
text-decoration: none;
color: inherit;
cursor: pointer;
}
#nav a:hover {
background: #666666;
}
body.invert #nav a:hover {
background: #999999;
}
#nav #text-offer-value {
border: 1px solid #999999;
background: transparent;
width: calc(100vw - 11em);
text-overflow: ellipsis;
color: inherit;
margin-right: 5px;
}
#nav .nav-text-offer { display:none; }
#nav.text-offer .nav-default { display:none; }
#nav.text-offer .nav-text-offer { display:inline; }
</style>
<script src="lzma.js"></script>
<script>
var matches;
var lzma = new LZMA("lzma_worker.js");

document.addEventListener('DOMContentLoaded', function(){
document.getElementById("plaintext").focus();

if (matches = /(?:^|\;)invert\=([01])(?:\;|$)/.exec(document.cookie)) {
if (matches[1] === '1') {
document.body.classList.add("invert");
}
}

var base64 = location.hash.substr(1);
if (base64.length == 0) return;

if (!fetch) {
alert("Your browser does not support this page. Sorry! :(");
return;
}

fetch("data:application/octet-stream;base64,"+base64).then(r => r.blob()).then(function(blob){
var reader = new FileReader();
reader.onload = function(){
var compressed_data = Array.from(new Uint8Array(reader.result));
lzma.decompress(compressed_data, function(plaintext, error){
if (error) {
alert("Failed to decompress data: "+error);
return;
}

document.getElementById("plaintext").value = plaintext;
});
};
reader.readAsArrayBuffer(blob);
});
});

function url_generate(format) {
var plaintext = document.getElementById("plaintext").value;
lzma.compress(plaintext, 1, function(compressed, error){
if (error) {
alert("Failed to compress data: "+error);
return;
}

var reader = new FileReader();
reader.onload = function(){
var base64 = reader.result.substr(reader.result.indexOf(",")+1);
var url = "https://"+location.host+location.pathname+"#"+base64;
var result;
if (format === 'markdown') {
result = "[paste]("+url+")";
} else {
result = url;
}
text_offer(result);
};
reader.readAsDataURL(new Blob([new Uint8Array(compressed)]));
});
}

function text_offer(text) {
document.getElementById("text-offer-value").value = text;
document.getElementById("nav").classList.add("text-offer");
}

function text_offer_copy() {
var input = document.getElementById("text-offer-value");
input.select();
document.execCommand('copy');
text_offer_cancel();
}

function text_offer_cancel() {
document.getElementById("text-offer-value").value = "";
document.getElementById("nav").classList.remove("text-offer");
}

function invert() {
var pref = document.body.classList.contains("invert") ? 0 : 1;
document.cookie = "invert="+pref+";max-age=63072000";
document.body.classList[pref?"add":"remove"]("invert");
}
</script>
</head>
<body>
<div id="plaintext-wrapper"><textarea id="plaintext" spellcheck="false"></textarea></div>
<div id="nav"><span class="nav-default"><a class="nav-left" href="https://github.com/topaz/paste">[github]</a><a class="nav-left" onclick="invert()">[invert colors]</a><a onclick="url_generate('raw')">[generate url]</a><a onclick="url_generate('markdown')">[generate markdown link]</a></span><span class="nav-text-offer"><input id="text-offer-value"/><a onclick="text_offer_copy()">[copy]</a><a onclick="text_offer_cancel()">[cancel]</a></span></div>
</body>
</html>
153 changes: 153 additions & 0 deletions bin/lzma.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
//! © 2015 Nathan Rugg <[email protected]> | MIT
/// See LICENSE for more details.

// jshint bitwise:true, curly:true, eqeqeq:true, forin:true, immed:true, latedef:true, newcap:true, noarg:true, noempty:true, nonew:true, onevar:true, plusplus:true, quotmark:double, undef:true, unused:strict, browser: true, node: true

/// Does the environment support web workers? If not, let's load the worker manually (without polluting the global scope).
if (typeof Worker === "undefined" || (typeof location !== "undefined" && location.protocol === "file:")) {
/// Is this Node.js?
if (typeof global !== "undefined" && typeof require !== "undefined") {
this.LZMA = function (lzma_path) {
return require(lzma_path || "./lzma_worker.js").LZMA;
};
/// Is this a browser?
} else if (typeof window !== "undefined" && window.document) {
(function () {
var that = this,
global_var,
req = function req(path) {
var script_tag = document.createElement("script");
script_tag.type ="text/javascript";
script_tag.src = path;
script_tag.onload = function () {
/// Make sure this LZMA variable doesn't get overwritten by the worker's.
that.LZMA = non_worker_lzma;
};
document.getElementsByTagName("head")[0].appendChild(script_tag);
};

/// Determine the global variable (it's called "window" in browsers, "global" in Node.js).
if (typeof window !== "undefined") {
global_var = window;
} else if (global) {
global_var = global;
}

function non_worker_lzma(path) {
var fake_lzma;

req(path);

fake_lzma = {
compress: function compress(mixed, mode, on_finish, on_progress) {
if (global_var.LZMA_WORKER) {
global_var.LZMA_WORKER.compress(mixed, mode, on_finish, on_progress);
} else {
/// Wait
setTimeout(function ()
{
fake_lzma.compress(mixed, mode, on_finish, on_progress);
}, 50);
}
},
decompress: function decompress(byte_arr, on_finish, on_progress) {
if (global_var.LZMA_WORKER) {
global_var.LZMA_WORKER.decompress(byte_arr, on_finish, on_progress);
} else {
/// Wait
setTimeout(function ()
{
fake_lzma.decompress(byte_arr, on_finish, on_progress);
}, 50);
}
},
worker: function worker () {
return null;
}
};

return fake_lzma;
}

that.LZMA = non_worker_lzma;
}());
} else {
/// It doesn't seem to be either Node.js or a browser.
console.error("Can't load the worker. Sorry.");
}
} else {
/// Let's use Web Workers.
///NOTE: The "this" keyword is the global context ("window" variable) if loaded via a <script> tag
/// or the function context if loaded as a module (e.g., in Node.js).
this.LZMA = function (lzma_path) {
var action_compress = 1,
action_decompress = 2,
action_progress = 3,

callback_obj = {},

///NOTE: Node.js needs something like "./" or "../" at the beginning.
lzma_worker = new Worker(lzma_path || "./lzma_worker-min.js");

lzma_worker.onmessage = function onmessage(e) {
if (e.data.action === action_progress) {
if (callback_obj[e.data.cbn] && typeof callback_obj[e.data.cbn].on_progress === "function") {
callback_obj[e.data.cbn].on_progress(e.data.result);
}
} else {
if (callback_obj[e.data.cbn] && typeof callback_obj[e.data.cbn].on_finish === "function") {
callback_obj[e.data.cbn].on_finish(e.data.result, e.data.error);

/// Since the (de)compression is complete, the callbacks are no longer needed.
delete callback_obj[e.data.cbn];
}
}
};

/// Very simple error handling.
lzma_worker.onerror = function(event) {
var err = new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");

for (var cbn in callback_obj) {
callback_obj[cbn].on_finish(null, err);
}

console.error('Uncaught error in lzma_worker', err);
};

return (function () {

function send_to_worker(action, data, mode, on_finish, on_progress) {
var cbn;

do {
cbn = Math.floor(Math.random() * (10000000));
} while(typeof callback_obj[cbn] !== "undefined");

callback_obj[cbn] = {
on_finish: on_finish,
on_progress: on_progress
};

lzma_worker.postMessage({
action: action, /// action_compress = 1, action_decompress = 2, action_progress = 3
cbn: cbn, /// callback number
data: data,
mode: mode
});
}

return {
compress: function compress(mixed, mode, on_finish, on_progress) {
send_to_worker(action_compress, mixed, mode, on_finish, on_progress);
},
decompress: function decompress(byte_arr, on_finish, on_progress) {
send_to_worker(action_decompress, byte_arr, false, on_finish, on_progress);
},
worker: function worker() {
return lzma_worker;
}
};
}());
};
}
Loading

0 comments on commit e8d05ec

Please sign in to comment.