-
Notifications
You must be signed in to change notification settings - Fork 71
/
bookmarkleter.js
77 lines (61 loc) · 2.43 KB
/
bookmarkleter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Load dependencies.
const babelMinify = require( 'babel-minify' );
const babel = require( '@babel/standalone' );
babel.transformSync = babel.transform;
// URI-encode only a subset of characters. Most user agents are permissive with
// non-reserved characters, so don't obfuscate more than we have to.
const specialCharacters = [ '%', '"', '<', '>', '#', '@', ' ', '\\&', '\\?' ];
// CDN URL for jQuery.
const jQueryURL = 'https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js';
// Default minimum jQuery version.
const jQueryMinVersion = 1.7;
const jquery = code => `void function ($) {
var loadBookmarklet = function ($) {${code}};
if($ && $.fn && parseFloat($.fn.jquery) >= ${jQueryMinVersion}) {
load($);
return;
}
var s = document.createElement('script');
s.src = '${jQueryURL}';
s.onload = s.onreadystatechange = function () {
var state = this.readyState;
if(!state || state === 'loaded' || state === 'complete') {
loadBookmarklet(jQuery.noConflict());
}
};
document.getElementsByTagName('head')[0].appendChild(s);
}(window.jQuery);`;
const iife = code => `void function () {${code}\n}();`;
const minify = ( code, mangle ) => babelMinify( code, { mangle, deadcode: mangle }, { babel, comments: false } ).code;
const prefix = code => `javascript:${code}`;
const transpile = code => babel.transform( code, { comments: false, filename: 'bookmarklet.js', presets: [ 'env' ], targets: '> 2%, not dead' } ).code
const urlencode = code => code.replace( new RegExp( specialCharacters.join( '|' ), 'g' ), encodeURIComponent );
// Create a bookmarklet.
module.exports = ( code, options = {} ) => {
let result = code;
// Add jQuery? (also adds IIFE wrapper).
if ( options.jQuery || options.jquery ) {
options.jQuery = true;
result = jquery( result );
}
// Add IIFE wrapper?
if ( ( options.iife || options.anonymize ) && !options.jQuery ) {
result = iife( result );
}
// Transpile?
if ( options.transpile ) {
result = transpile( result );
}
// Minify by default
result = minify( result, options.mangleVars || false );
// If code minifies down to nothing, stop processing.
if ( '' === result.replace( /^"use strict";/, '').replace( /^void function\(\){}\(\);$/, '' ) ) {
return null;
}
// URL-encode by default.
if ( options.urlencode || 'undefined' === typeof options.urlencode ) {
result = urlencode( result );
}
// Add javascript prefix.
return prefix( result );
};