From afebb09dc1b8eeaa2cdaffefc5583d1eb5f97de1 Mon Sep 17 00:00:00 2001 From: Ethan Spitz Date: Tue, 12 Mar 2013 17:05:17 -0400 Subject: [PATCH 1/2] Added script to replace atob function --- src/main/javascript/base64.js | 176 ++++++++++++++++++++++++++++ src/main/javascript/github-files.js | 2 +- 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 src/main/javascript/base64.js diff --git a/src/main/javascript/base64.js b/src/main/javascript/base64.js new file mode 100644 index 0000000..5baba0d --- /dev/null +++ b/src/main/javascript/base64.js @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2010 Nick Galbreath + * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* base64 encode/decode compatible with window.btoa/atob + * + * window.atob/btoa is a Firefox extension to convert binary data (the "b") + * to base64 (ascii, the "a"). + * + * It is also found in Safari and Chrome. It is not available in IE. + * + * if (!window.btoa) window.btoa = base64.encode + * if (!window.atob) window.atob = base64.decode + * + * The original spec's for atob/btoa are a bit lacking + * https://developer.mozilla.org/en/DOM/window.atob + * https://developer.mozilla.org/en/DOM/window.btoa + * + * window.btoa and base64.encode takes a string where charCodeAt is [0,255] + * If any character is not [0,255], then an DOMException(5) is thrown. + * + * window.atob and base64.decode take a base64-encoded string + * If the input length is not a multiple of 4, or contains invalid characters + * then an DOMException(5) is thrown. + */ +var base64 = {}; +base64.PADCHAR = '='; +base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +base64.makeDOMException = function() { + // sadly in FF,Safari,Chrome you can't make a DOMException + var e, tmp; + + try { + return new DOMException(DOMException.INVALID_CHARACTER_ERR); + } catch (tmp) { + // not available, just passback a duck-typed equiv + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype + var ex = new Error("DOM Exception 5"); + + // ex.number and ex.description is IE-specific. + ex.code = ex.number = 5; + ex.name = ex.description = "INVALID_CHARACTER_ERR"; + + // Safari/Chrome output format + ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; }; + return ex; + } +} + +base64.getbyte64 = function(s,i) { + // This is oddly fast, except on Chrome/V8. + // Minimal or no improvement in performance by using a + // object with properties mapping chars to value (eg. 'A': 0) + var idx = base64.ALPHA.indexOf(s.charAt(i)); + if (idx === -1) { + throw base64.makeDOMException(); + } + return idx; +} + +base64.decode = function(s) { + // convert to string + s = '' + s; + var getbyte64 = base64.getbyte64; + var pads, i, b10; + var imax = s.length + if (imax === 0) { + return s; + } + + if (imax % 4 !== 0) { + throw base64.makeDOMException(); + } + + pads = 0 + if (s.charAt(imax - 1) === base64.PADCHAR) { + pads = 1; + if (s.charAt(imax - 2) === base64.PADCHAR) { + pads = 2; + } + // either way, we want to ignore this last block + imax -= 4; + } + + var x = []; + for (i = 0; i < imax; i += 4) { + b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | + (getbyte64(s,i+2) << 6) | getbyte64(s,i+3); + x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff)); + } + + switch (pads) { + case 1: + b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6); + x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff)); + break; + case 2: + b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12); + x.push(String.fromCharCode(b10 >> 16)); + break; + } + return x.join(''); +} + +base64.getbyte = function(s,i) { + var x = s.charCodeAt(i); + if (x > 255) { + throw base64.makeDOMException(); + } + return x; +} + +base64.encode = function(s) { + if (arguments.length !== 1) { + throw new SyntaxError("Not enough arguments"); + } + var padchar = base64.PADCHAR; + var alpha = base64.ALPHA; + var getbyte = base64.getbyte; + + var i, b10; + var x = []; + + // convert to string + s = '' + s; + + var imax = s.length - s.length % 3; + + if (s.length === 0) { + return s; + } + for (i = 0; i < imax; i += 3) { + b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2); + x.push(alpha.charAt(b10 >> 18)); + x.push(alpha.charAt((b10 >> 12) & 0x3F)); + x.push(alpha.charAt((b10 >> 6) & 0x3f)); + x.push(alpha.charAt(b10 & 0x3f)); + } + switch (s.length - imax) { + case 1: + b10 = getbyte(s,i) << 16; + x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + + padchar + padchar); + break; + case 2: + b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8); + x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + + alpha.charAt((b10 >> 6) & 0x3f) + padchar); + break; + } + return x.join(''); +} diff --git a/src/main/javascript/github-files.js b/src/main/javascript/github-files.js index b460b31..cc8fcaf 100644 --- a/src/main/javascript/github-files.js +++ b/src/main/javascript/github-files.js @@ -7,7 +7,7 @@ if (data.data.content && data.data.encoding === "base64") { var contentArray = window - .atob(data.data.content.replace(/\n/g, "")) + .base64.decode(data.data.content.replace(/\n/g, "")) .split("\n"); endLineNum = endLineNum || contentArray.length; From 08d91791a35d72b4e2740c5314b3858704c88050 Mon Sep 17 00:00:00 2001 From: Ethan Spitz Date: Tue, 12 Mar 2013 20:08:52 -0400 Subject: [PATCH 2/2] Added conditional so base64.js file not required File is only required for IE support --- src/main/javascript/github-files.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/javascript/github-files.js b/src/main/javascript/github-files.js index cc8fcaf..b1083d8 100644 --- a/src/main/javascript/github-files.js +++ b/src/main/javascript/github-files.js @@ -5,11 +5,19 @@ var fnSuccess = function (data, startLineNum, endLineNum, callback) { if (data.data.content && data.data.encoding === "base64") { - var contentArray = + if (window.atob) { + var contentArray = + window + .atob(data.data.content.replace(/\n/g, "")) + .split("\n"); + } + else + { + var contentArray = window .base64.decode(data.data.content.replace(/\n/g, "")) .split("\n"); - + } endLineNum = endLineNum || contentArray.length; callback(contentArray.slice(startLineNum - 1, endLineNum).join("\n"));