From 5e7dc72349a4d33e9b6432831d6a6d94442764cf Mon Sep 17 00:00:00 2001 From: tmk Date: Wed, 25 Sep 2013 16:29:32 +0900 Subject: [PATCH] Add compression share URL with lz-string --- editor/m0110/base64.js | 142 ++++++++++++++++++++++ editor/m0110/keymap_editor.js | 19 ++- editor/m0110/lz-string-1.0.2.js | 204 ++++++++++++++++++++++++++++++++ editor/m0110/m0110.html | 9 +- editor/m0110/m0110a.html | 9 +- 5 files changed, 369 insertions(+), 14 deletions(-) create mode 100644 editor/m0110/base64.js create mode 100644 editor/m0110/lz-string-1.0.2.js diff --git a/editor/m0110/base64.js b/editor/m0110/base64.js new file mode 100644 index 00000000..9cb51082 --- /dev/null +++ b/editor/m0110/base64.js @@ -0,0 +1,142 @@ +/** +* +* Base64 encode / decode +* http://www.webtoolkit.info/ +* +**/ + +var Base64 = { + + // private property + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + + // public method for encoding + encode : function (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + + input = Base64._utf8_encode(input); + + while (i < input.length) { + + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); + + } + + return output; + }, + + // public method for decoding + decode : function (input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + } + + output = Base64._utf8_decode(output); + + return output; + + }, + + // private method for UTF-8 encoding + _utf8_encode : function (string) { + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + }, + + // private method for UTF-8 decoding + _utf8_decode : function (utftext) { + var string = ""; + var i = 0; + var c = c1 = c2 = 0; + + while ( i < utftext.length ) { + + c = utftext.charCodeAt(i); + + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + + } + + return string; + } + +} diff --git a/editor/m0110/keymap_editor.js b/editor/m0110/keymap_editor.js index 2f56956d..b8fc96be 100644 --- a/editor/m0110/keymap_editor.js +++ b/editor/m0110/keymap_editor.js @@ -81,11 +81,9 @@ $(function() { var code = parseInt($(this).attr('id').match(/code-((0x){0,1}[0-9a-fA-F]+)/)[1]); $(this).text(keycodes[code].name); $(this).attr({ title: keycodes[code].desc }); - //console.log(index + ": " + code + " " + keycodes[code].desc); }); $(".action").click(function(ev,ui) { - console.log("action click"); if (!editing_key) return; // get matrix position from key id: key-RC where R is row and C is column in "0-v"(radix 32) @@ -197,15 +195,24 @@ $(function() { /* * Share URL */ -function encode_keymap(keymap) +function encode_keymap(obj) { - return window.btoa(JSON.stringify(keymap)); + if (typeof LZString != "undefined" && typeof Base64 != "undefined") { + return Base64.encode(LZString.compress(JSON.stringify(obj))); + } + return window.btoa(JSON.stringify(obj)); } -function decode_keymap(hash) +function decode_keymap(str) { try { - return JSON.parse(window.atob(hash)); + /* lz-string-1.3.3.js: LZString.decompress() runs away if given short string. */ + if (str == null || typeof str != "string" || str.length < 30) return null; + + if (typeof LZString != "undefined" && typeof Base64 != "undefined") { + return JSON.parse(LZString.decompress(Base64.decode(str))); + } + return JSON.parse(window.atob(str)); } catch (err) { return null; } diff --git a/editor/m0110/lz-string-1.0.2.js b/editor/m0110/lz-string-1.0.2.js new file mode 100644 index 00000000..86aafd08 --- /dev/null +++ b/editor/m0110/lz-string-1.0.2.js @@ -0,0 +1,204 @@ +// Copyright © 2013 Pieroxy +// This work is free. You can redistribute it and/or modify it +// under the terms of the WTFPL, Version 2 +// For more information see LICENSE.txt or http://www.wtfpl.net/ +// +// LZ-based compression algorithm, version 1.0.2-rc1 +var LZString = { + + writeBit : function(value, data) { + data.val = (data.val << 1) | value; + if (data.position == 15) { + data.position = 0; + data.string += String.fromCharCode(data.val); + data.val = 0; + } else { + data.position++; + } + }, + + writeBits : function(numBits, value, data) { + if (typeof(value)=="string") + value = value.charCodeAt(0); + for (var i=0 ; i> 1; + } + }, + + produceW : function (context) { + if (Object.prototype.hasOwnProperty.call(context.dictionaryToCreate,context.w)) { + if (context.w.charCodeAt(0)<256) { + this.writeBits(context.numBits, 0, context.data); + this.writeBits(8, context.w, context.data); + } else { + this.writeBits(context.numBits, 1, context.data); + this.writeBits(16, context.w, context.data); + } + this.decrementEnlargeIn(context); + delete context.dictionaryToCreate[context.w]; + } else { + this.writeBits(context.numBits, context.dictionary[context.w], context.data); + } + this.decrementEnlargeIn(context); + }, + + decrementEnlargeIn : function(context) { + context.enlargeIn--; + if (context.enlargeIn == 0) { + context.enlargeIn = Math.pow(2, context.numBits); + context.numBits++; + } + }, + + compress: function (uncompressed) { + var context = { + dictionary: {}, + dictionaryToCreate: {}, + c:"", + wc:"", + w:"", + enlargeIn: 2, // Compensate for the first entry which should not count + dictSize: 3, + numBits: 2, + result: "", + data: {string:"", val:0, position:0} + }, i; + + for (i = 0; i < uncompressed.length; i += 1) { + context.c = uncompressed.charAt(i); + if (!Object.prototype.hasOwnProperty.call(context.dictionary,context.c)) { + context.dictionary[context.c] = context.dictSize++; + context.dictionaryToCreate[context.c] = true; + } + + context.wc = context.w + context.c; + if (Object.prototype.hasOwnProperty.call(context.dictionary,context.wc)) { + context.w = context.wc; + } else { + this.produceW(context); + // Add wc to the dictionary. + context.dictionary[context.wc] = context.dictSize++; + context.w = String(context.c); + } + } + + // Output the code for w. + if (context.w !== "") { + this.produceW(context); + } + + // Mark the end of the stream + this.writeBits(context.numBits, 2, context.data); + + // Flush the last char + while (context.data.val>0) this.writeBit(0,context.data) + return context.data.string; + }, + + readBit : function(data) { + var res = data.val & data.position; + data.position >>= 1; + if (data.position == 0) { + data.position = 32768; + data.val = data.string.charCodeAt(data.index++); + } + //data.val = (data.val << 1); + return res>0 ? 1 : 0; + }, + + readBits : function(numBits, data) { + var res = 0; + var maxpower = Math.pow(2,numBits); + var power=1; + while (power!=maxpower) { + res |= this.readBit(data) * power; + power <<= 1; + } + return res; + }, + + decompress: function (compressed) { + var dictionary = {}, + next, + enlargeIn = 4, + dictSize = 4, + numBits = 3, + entry = "", + result = "", + i, + w, + c, + errorCount=0, + literal, + data = {string:compressed, val:compressed.charCodeAt(0), position:32768, index:1}; + + for (i = 0; i < 3; i += 1) { + dictionary[i] = i; + } + + next = this.readBits(2, data); + switch (next) { + case 0: + c = String.fromCharCode(this.readBits(8, data)); + break; + case 1: + c = String.fromCharCode(this.readBits(16, data)); + break; + case 2: + return ""; + } + dictionary[3] = c; + w = result = c; + while (true) { + c = this.readBits(numBits, data); + + switch (c) { + case 0: + if (errorCount++ > 10000) return "Error"; + c = String.fromCharCode(this.readBits(8, data)); + dictionary[dictSize++] = c; + c = dictSize-1; + enlargeIn--; + break; + case 1: + c = String.fromCharCode(this.readBits(16, data)); + dictionary[dictSize++] = c; + c = dictSize-1; + enlargeIn--; + break; + case 2: + return result; + } + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + if (dictionary[c]) { + entry = dictionary[c]; + } else { + if (c === dictSize) { + entry = w + w.charAt(0); + } else { + return null; + } + } + result += entry; + + // Add w+entry[0] to the dictionary. + dictionary[dictSize++] = w + entry.charAt(0); + enlargeIn--; + + w = entry; + + if (enlargeIn == 0) { + enlargeIn = Math.pow(2, numBits); + numBits++; + } + + } + return result; + } +}; diff --git a/editor/m0110/m0110.html b/editor/m0110/m0110.html index e4a061a2..a26e9eb9 100644 --- a/editor/m0110/m0110.html +++ b/editor/m0110/m0110.html @@ -8,8 +8,9 @@ - + + + @@ -530,13 +531,13 @@

Share URL:

- +

Keymap Output(for debug):

- +
diff --git a/editor/m0110/m0110a.html b/editor/m0110/m0110a.html index adce38e7..af7cbce4 100644 --- a/editor/m0110/m0110a.html +++ b/editor/m0110/m0110a.html @@ -8,8 +8,9 @@ - + + + @@ -531,13 +532,13 @@

Share URL:

- +

Keymap Output(for debug):

- +