0

I have the following JS (not jQuery), which I want to compress (saved in a PHP file with header('Content-type: text/javascript')):

var $url = window.location.href;

    $url = $url.toLowerCase().replace(/^(http(s)?\:\/\/)/g, ''),
    $url = $url.split('/');

var $current_page = $url[$url.length - 1].replace(/(\?.*)?(\#.*)?/g, ''); // Current Page

document.addEventListener('DOMContentLoaded', function() {
    if ($current_page === 'index.html') {
        if (window.location.hash) {
            var $current_hash = window.location.hash.substring(1);
        } else {
            window.location.hash = '';
        }

        // Ignore the code above, the important part is right below:
        var $fp_imgs = document.querySelectorAll('img.-homepage-poster');
        $fp_imgs.forEach(function($fp_img) {
            var $imgs = [518966, 518967, 518968, 518969],
                $rand = Math.floor($imgs.length * Math.random()),
                $xmhr = new XMLHttpRequest();

            var response = function($e) {
                var $this = this,
                    $url_creator = window.URL || window.webkitURL,
                    $image_url = $url_creator.createObjectURL($this.response);
                $fp_img.src = $image_url;
            }

            $xmhr.open('get', '../imgs/' + $imgs[$rand] + '.jpg', true);
            $xmhr.responseType = 'blob';
            $xmhr.onload = response;
            $xmhr.send();
        });
    }
});

I use ob_start with the following regex pattern in order to compress the code at the beginning of the file:

ob_start(function($code) {
    // return $code; # If the compression causing errors, do not compress
    return preg_replace('(\s{2,})', ' ', preg_replace('/(?:(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:(?<!\:|\\\|\')\/\/.*))/', '', $code));
});

When it's not compressed, Everything works well. But when I use the pattern, I get the following error in the console:

SyntaxError: unexpected token: identifier

The "minified" output:

var $url = window.location.href; $url = $url.toLowerCase().replace(/^(http(s)?\:\/\/)/g, ''), $url = $url.split('/'); var $current_page = $url[$url.length - 1].replace(/(\?.*)?(\#.*)?/g, ''); document.addEventListener('DOMContentLoaded', function() { if ($current_page === 'index.html') { if (window.location.hash) { var $current_hash = window.location.hash.substring(1); } else { window.location.hash = ''; } var $fp_imgs = document.querySelectorAll('img.-homepage-poster'); $fp_imgs.forEach(function($fp_img) { var $imgs = [518966, 518967, 518968, 518969], $rand = Math.floor($imgs.length * Math.random()), $xmhr = new XMLHttpRequest(); var response = function($e) { var $this = this, $url_creator = window.URL || window.webkitURL, $image_url = $url_creator.createObjectURL($this.response); $fp_img.src = $image_url; } $xmhr.open('get', '../imgs/' + $imgs[$rand] + '.jpg', true); $xmhr.responseType = 'blob'; $xmhr.onload = response; $xmhr.send(); }); } });

How can I solve this?

Thank you very much

  • From where did you get this compressing code? – Spoody Mar 18 '18 at 20:01
  • @MehdiBounya To remove js comments I used [this answer](https://stackoverflow.com/a/19510664/6247920), the rest I wrote –  Mar 18 '18 at 20:02
  • 1
    Maybe you are not minifying the js code correctly, the word you are looking for is Minify, there are libraries that do that for you – Spoody Mar 18 '18 at 20:05
  • @MehdiBounya Probably, but i'm not looking for something heavy or complicated, I need some easy solution with regex. is this possible? –  Mar 18 '18 at 20:06
  • 1
    When you do a diff between the uncompressed code and the compressed code, besides the removed comments, what else has changed? You clue is in that comparison. – Randy Casburn Mar 18 '18 at 20:07
  • @RandyCasburn `\s{2,}` can cause this? (update: yes, that's the reason that this isn't working) –  Mar 18 '18 at 20:08
  • @natanelg97 - you have to compare the output of the `preg_replace()` and the code you've provided in your question above. If you don't know how, then provide the "compressed" code so we can help you compare them. – Randy Casburn Mar 18 '18 at 20:10
  • @RandyCasburn The problem was with the `\s{2,}`, when I removed it it worked. but how can I make it in one line without this? –  Mar 18 '18 at 20:12
  • @natanelg97 - no `\s{2,}` is correct. Please see my answer below. – Randy Casburn Mar 18 '18 at 20:29

1 Answers1

0

The problem is that your JavaScript code has incorrect statement terminations. This is a common problem with JavaScript minification and a PITA inside spaghetti.

Just for the fun of it, here is the regex sample with your code: https://regex101.com/r/Iwvo4I/1/

Look at the very first var statement in your JS above. It appears you've terminated the var when you didn't intend to:

This

var $url = window.location.href; <-----------LOOK HERE

    $url = $url.toLowerCase().replace(/^(http(s)?\:\/\/)/g, ''),
    $url = $url.split('/');

Should be

var $url = window.location.href, <-----------LOOK HERE

    $url = $url.toLowerCase().replace(/^(http(s)?\:\/\/)/g, ''),
    $url = $url.split('/');

NEXT

Look at the code for the response function expression:

    var response = function($e) {
       //// ... 
    } // <--- PUT SEMICOLON HERE

Since this is a JavaScript expression, the statement should be terminated by a semicolon. It isn't, but it is causing your code the break when minified.

In order to be perfectly clear, replace the semicolon at the end of line one with a comma to correct you coding error. And place a semicolon after the response function declaration

That should do it.

Randy Casburn
  • 13,840
  • 1
  • 16
  • 31
  • Still getting the error. i'll update my question with the minified code –  Mar 18 '18 at 20:31
  • The semicolon is still terminating the first line. You did not apply the fix that is required. – Randy Casburn Mar 18 '18 at 20:42
  • even when I do `var $url = window.location.href, $url = $url.toLowerCase().replace(/^(http(s)?\:\/\/)/g, \'\'), $url = $url.split(\'/\');` I still get the error. the problem is with the blob, not the `$url` variable –  Mar 18 '18 at 21:42
  • You missed a second semicolon in the javascript code. Please re-read my answer update. Also, please, please, please discover that immensely better software development concepts of separating out all this code. You created a nightmare for no reason. – Randy Casburn Mar 18 '18 at 22:47