Baruch
Baruch

Reputation: 1636

Adjust html onClick calls according to obfuscated js

I am planning on obfuscating my js code for this project.
I have multiple js files that I am planning on combining to one minified, obfuscated js file.

Now the question is, is there a way to change the HTML calls (such as onClick) to the obfuscated function names?

** example:

assume file main.js before obfuscation

function functionName(){
 //Do Something here
}

and assume index.html as follows:

...
<button onClick="functionName()">    

...

<script src="path/to/file/main.js"></script>    
...

now file main.js after obfuscation and minification:

function a(){//Do Something here}

now I need index.html to call that function, is there a way to automate change of the onclick call from functionName() to a() during the obfuscation process in the index.html file??

*** end example

if not, after everything is minified and obfuscated, how would I change it manually?

*Side note, right now I am considering using google's closure compiler.

Upvotes: 3

Views: 2191

Answers (3)

Chad Killingsworth
Chad Killingsworth

Reputation: 14411

This can be done, but I don't know of any automated tools to do it (unless you are using Polymer). The higher the level of obfuscation, the harder this becomes.

Closure-Compiler SIMPLE Optimizations

Use the --variable_renaming_report flag to output a map of renamed variables. In SIMPLE mode, properties will not be renamed. You can then use this report to rename your symbols in HTML. Parse5 is a great tool for parsing and walking through a DOM tree and can assist in this.

Closure-Compiler ADVANCED Optimizations

In this mode, the only way to safely accomplish this is with a multi-step process. And it's quite involved. You need to transform the references from the HTML into fake javascript, pass that fake javascript into closure-compiler along with your source and use the module flags to split the output, then post process the renamed output of the compiler and update the original HTML. This is the methodology used by Polymer-Rename.

Upvotes: 0

owler
owler

Reputation: 1089

With Google Closure Compiler you could perhaps write your own tool to read Source Maps which compiler options like --create_source_map create.

If you look at the design doc referenced on that page you will see this example of the source map output:

{
"version" : 3,
"file": "out.js",
"sourceRoot": "",
"sources": ["foo.js", "bar.js"],
"sourcesContent": [null, null],
"names": ["src", "maps", "are", "fun"],
"mappings": "A,AAAB;;ABCDE;"
}

The last two lines show that src became A, and maps became AAAB, etc.

You could use the source map to find what the compiler renamed your function to, and then modify index.html accordingly.

However, the way this is usually handled is to instead tell the compiler to not rename functionName. (The code within functionName will still be minimized.) There are various ways to do this such as using the @export tag

/**
* @export
* @return {undefined}
*/
function functionName(){
 //Do Something here
}

Alternatively you can use goog.exportSymbol or goog.exportProperty directly (which is what the @export tag generates). There is more information on this page about exporting symbols https://developers.google.com/closure/compiler/docs/api-tutorial3?csw=1


previous answer

The functions (properties, and other names) that are built-in to the browser and JavaScript cannot be minified because then the browser/JavaScript won't recognize what you are trying to do. onclick is one of those built-in properties of an HTMLElement.

You can obfuscate the function you assign to onclick but not the name onclick itself.

As another example, you can't minify JavaScript keywords like function, this, return.

Upvotes: 0

user149341
user149341

Reputation:

Don't use inline attributes like onclick to bind events.

Bind events in Javascript code, using EventTarget.addEventListener(), e.g. instead of:

<button id="myButton" onClick="somefunction()">

leave out the onClick attribute and run the following after page load:

document.getElementById("myButton").addEventListener("click", somefunction);

Note that, if you're using a library like jQuery, it'll probably provide you with cleaner ways of doing this, e.g.

$("#myButton").on("click", somefunction);

Upvotes: 3

Related Questions