Permalink
Browse files

refactor: atob should be minified (#16)

  • Loading branch information...
popomore committed Apr 16, 2018
1 parent a8b4937 commit 9b32a6ed4e2219e323946fb987e900a1477d66d9
Showing with 82 additions and 22 deletions.
  1. +1 −0 .eslintignore
  2. +4 −19 lib/assets_context.js
  3. +29 −0 lib/fixtures/decode.js
  4. +1 −0 lib/fixtures/decode.min.js
  5. +3 −1 package.json
  6. +1 −1 test/assets.test.js
  7. +42 −0 test/decode.test.js
  8. +1 −1 test/ui.test.js
@@ -1 +1,2 @@
coverage
lib/fixtures
@@ -1,28 +1,13 @@
'use strict';

const fs = require('fs');
const path = require('path');
const assert = require('assert');
const utility = require('utility');

const CONTEXT_TEMPLATE_ID = 'context' + utility.sha1(String(Date.now()));
// https://github.com/davidchambers/Base64.js/blob/master/base64.js
const atobScript = `
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var atob = window.atob || function(input) {
var str = String(input).replace(/[=]+$/, '');
if (str.length % 4 == 1) {
throw new Error('atob failed: The string to be decoded is not correctly encoded.');
}
for (
var bc = 0, bs, buffer, idx = 0, output = '';
buffer = str.charAt(idx++);
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
buffer = chars.indexOf(buffer);
}
return output;
};
`;
const atobScript = fs.readFileSync(path.join(__dirname, 'fixtures/decode.min.js'), 'utf8');

// URL consists of host, resourceBase and entry,
// E.X. http://127.0.0.1:7001/public/index.js
@@ -67,7 +52,7 @@ class Assets {
getContext(data) {
data = safeStringify(data || this.assetsContext);
let ret = `<div id="${CONTEXT_TEMPLATE_ID}" style="display:none">${data}</div>\n`;
ret += `<script>(function(){${atobScript}window.${this.config.contextKey} = JSON.parse(decodeURIComponent(atob(document.getElementById('${CONTEXT_TEMPLATE_ID}').textContent)) || '{}');})()</script>`;
ret += `<script>(function(){${atobScript}window.${this.config.contextKey} = decode(document.getElementById('${CONTEXT_TEMPLATE_ID}').textContent);})()</script>`;
return ret;
}

@@ -0,0 +1,29 @@
'use strict';

var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

function decode(input) {
return JSON.parse(decodeURIComponent(_atob(input)) || '{}');
}

function _atob(input) {
// window.atob
if (typeof window !== 'undefined' && window.atob) return window.atob(input);
if (!input) return '';

var str = String(input).replace(/[=]+$/, '');
if (str.length % 4 == 1) {
throw new Error('atob failed: The string to be decoded is not correctly encoded.');
}
for (
var bc = 0, bs, buffer, idx = 0, output = '';
buffer = str.charAt(idx++);
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
buffer = chars.indexOf(buffer);
}
return output;
}

if (typeof module !== 'undefined' && module.exports) module.exports = decode;

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -37,6 +37,7 @@
"eslint-config-egg": "^7.0.0",
"puppeteer": "^1.3.0",
"supertest": "^3.0.0",
"uglify-js": "^3.3.21",
"webstorm-disable-index": "^1.2.0"
},
"engines": {
@@ -50,7 +51,8 @@
"lint": "eslint .",
"ci": "egg-bin pkgfiles --check && npm run lint && npm run cov",
"pkgfiles": "egg-bin pkgfiles",
"autod": "autod"
"autod": "autod",
"uglify": "uglifyjs lib/fixtures/decode.js -o lib/fixtures/decode.min.js"
},
"files": [
"app",
@@ -259,7 +259,7 @@ describe('test/assets.test.js', () => {
return app.httpRequest()
.get('/?query=<x%E2%80%A8x>')
.expect(/<div id="[^"]+" style="display:none">JTdCJTIycXVlcnklMjIlM0ElMjIlM0N4JUUyJTgwJUE4eCUzRSUyMiU3RA==<\/div>/)
.expect(/window\.context = JSON\.parse\(decodeURIComponent\(atob\(document\.getElementById\('[^']+'\).textContent\)\) \|\| '\{\}'\);/)
.expect(/window\.context = decode\(document\.getElementById\('[^']+'\).textContent\);/)
.expect(200);
});
});
@@ -0,0 +1,42 @@
'use strict';

const assert = require('assert');
const decode = require('../lib/fixtures/decode');
const decodeMin = require('../lib/fixtures/decode.min');


describe('test/decode.test.js', () => {

it('should decode base64', () => {
let obj = decode('JTdCJTIyZGF0YSUyMiUzQTElN0Q=');
assert(obj.data === 1);
obj = decodeMin('JTdCJTIyZGF0YSUyMiUzQTElN0Q=');
assert(obj.data === 1);

const data = { a: 1 };
const encoded = new Buffer(encodeURIComponent(JSON.stringify(data))).toString('base64');
obj = decode(encoded);
assert(obj.a === 1);
});

it('should decode undefined', () => {
assert(typeof decode() === 'object');
assert(typeof decodeMin() === 'object');
});

it('should decode error', () => {
try {
decode('1');
throw new Error('should not run');
} catch (err) {
assert(err.message === 'atob failed: The string to be decoded is not correctly encoded.');
}
try {
decodeMin('1');
throw new Error('should not run');
} catch (err) {
assert(err.message === 'atob failed: The string to be decoded is not correctly encoded.');
}
});

});
@@ -30,7 +30,7 @@ describe('test/ui.test.js', () => {
it('should render html', async () => {
await app.httpRequest()
.get('/')
.expect(/var atob = window.atob || function\(input\) {/)
.expect(/function _atob\(input\)/)
.expect(200);
});

0 comments on commit 9b32a6e

Please sign in to comment.