Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8768805
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T17:09:37+00:00 2026-06-13T17:09:37+00:00

EDIT The lesson, learned with the help of @Alex, is that you should never

  • 0

EDIT

The lesson, learned with the help of @Alex, is that you should never put function declarations in block scope. Not that I intended to do this, but if you slip up, it can cause big problems.


I have a script file that seems to be getting compressed via Google Closure incorrectly. When I run my app with the original code, all works fine. But when I try to compress it with Google Closure, some errors get introduced.

I am NOT using the advanced option; I’m using the basic, default mode

Obviously I can’t expect anyone to debug the compressed file, but I’m hoping someone can look at the uncompressed code and let me know if I’m somehow doing something insanely stupid that would trick Closure.

Some notes on the minified code:

Closure is inlining BEFramework.prototype.hstreamLoad and BEFramework.prototype.hstreamEvalJson, and seems to be utterly removing the helper functions getDeleteValue, getValueToDisplay, getDisplayForLabel and likely others.

Uncompressed file is below.

This code can manually be compiled by closure here, which should reproduce the symptoms described above.

(function() {
    var $ = jQuery;

    // Load and display the messages ("healthstream") for a given module.
    // This requires that the module's HTML have specific features, see
    // dashboard.htm and contactsManager/details/default.htm for examples.
    // This also requires that the `request` support `pageIndex` and `pageSize`,
    // so we can handle paging.
    //
    // Args:    `options`       An options object with these keys:
    //                              `channelId`     The channel ID of the module (for transmitRequest)
    //                              `translationId` Optional alternate ID for translation (if not given,
    //                                              `channelId` is used).
    //                              `action`        The action (for transmitRequest)
    //                                                  - Must support `pageIndex` and `pageSize`
    //                              `request`       The request (for transmitRequest)
    //                                                  - Must include `pageIndex` and `pageSize`
    //                              `complete`      Optional callback triggered when the load is complete.
    //                              `showOptions`   Optional callback if an options menu is supported
    //                                              by the calling module. Receives a raw event instance
    //                                              and the item on which the options were triggered:
    //                                                  function showOptions(event, item)
    //                              `context`       Optional context (`this` value) for the call to
    //                                              `complete` and/or `showOptions`
    BEFramework.prototype.hstreamLoad = hstreamLoad;
    function hstreamLoad(options) {
        var inst = this;

        var channelId, translationId, action, request, complete, showOptions, context,
            pageIndex, pageCount, pageSize, pageCount,
            btnPrevious, btnNext,
            dataShownFlags;

        // Get our arguments (with defaults)
        channelId = options.channelId;
        translationId = options.translationId || options.channelId;
        action = options.action;
        request = $.extend({}, options.request);    // Create a *copy*, because we modify it when doing paging
        complete = options.complete;
        if (typeof complete !== "function") {
            complete = undefined;
        }
        showOptions = options.showOptions;
        if (typeof showOptions !== "function") {
            showOptions = undefined;
        }
        context = options.context;  // (undefined will automatically become the global object)

        // Grab the initial pageIndex and pageSize
        pageIndex = request.pageIndex || 1;
        pageSize = request.pageSize || 100;

        // Disable the button and show "searching" label
        $('#healthStreamSearchButton')
            .button("disable")
            .button("option", "label", BETranslate(translationId, 'HealthStreamSearching'));

        // Hook up the buttons; be a bit paranoid that they've been hooked before and clear previous handlers
        btnPrevious = $('#healthStreamPagePrevious');
        btnNext = $('#healthStreamPageNext');
        btnPrevious.hide().unbind("click.paging").bind("click.paging", goToPreviousPage);
        btnNext.hide().unbind("click.paging").bind("click.paging", goToNextPage);

        // Do it
        doLoad();

        // === Support functions

        // Trigger a load request
        function doLoad() {
            request.pageIndex = pageIndex;
            request.pageSize = pageSize;
            inst._transport.transmitRequest(channelId, action, request, hstreamLoaded);
        }

        // Hndle the load response
        function hstreamLoaded(objResponse) {
            var healthStream = objResponse.items;
            var total = objResponse.total;
            var tbody = $('#healthStreamList');

            // Need to make this update optional
            $('#pageHeaderName').html(BETranslate(translationId, 'HeaderActivity') + ' (' + String(total) + ')');
            $('#healthStreamSearchButton')
                .button("enable")
                .button("option", "label", BETranslate(translationId, 'HealthStreamSearch'));
            tbody.empty();
            btnPrevious.hide();
            btnNext.hide();

            if (healthStream.length > 0) {
                pageCount = Math.ceil(total / pageSize);

                if (pageCount > 1) {
                    if (pageIndex > 1) {
                        btnPrevious.show();
                    }
                    if (pageIndex < pageCount) {
                        btnNext.show();
                    }
                }

                var item;
                var tr;
                var tdMain;
                var daysHash = {};
                var creationDate;
                var key;
                var today = new Date();
                var yesterday = new Date();
                var msg;
                yesterday.setDate(yesterday.getDate() - 1);

                dataShownFlags = {};

                for (var x = 0; x < healthStream.length; x++) {
                    item = healthStream[x];
                    msg = inst.hstreamEvalJson(item);

                    if (msg.length > 0) {
                        creationDate = new Date(item.CreationDate);
                        key = [creationDate.getYear(), creationDate.getMonth(), creationDate.getDate()].join('-');

                        if (!daysHash[key]) {
                            if (isDateEqual(creationDate, today)) {
                                addRowHeader(tbody, BETranslate(inst._channelId, 'HSToday'));
                            }
                            else if (isDateEqual(creationDate, yesterday)) {
                                addRowHeader(tbody, BETranslate(inst._channelId, 'HSYesterday'));
                            }
                            else {
                                addRowHeader(tbody, creationDate.toString('MM/dd/yyyy'));
                            }
                            daysHash[key] = true;
                        }

                        tr = $(
                            "<tr>" +
                                "<td class='date' style='white-space:nowrap;'>" + new Date(item.CreationDate).toString('h:mm tt') + "</td>" +
                                "<td class='main'><span class='name'>" + msg + "</span>" +
                                "</tr>"
                        );
                        tbody.append(tr);
                        if (showOptions) {
                            tr.find("td.main").prepend($("<em rel='opt'>&nbsp;</em>").click(makeShowOptionsHandler(item)));
                        }
                    }
                }

                // If any of the templates created links with a `data` attribute, hook them up
                $('#healthStreamList a[data]').click(showTitle).each(function (index) {
                    this.id = 'data' + index;
                });

            }
            else {
                tbody.html('<tr><td colspan="2">' + BETranslate(inst._channelId, 'HSNoActivity') + '</td></tr>');
            }

            // Trigger completion callback
            if (complete) {
                complete.call(context, objResponse);
            }
        }

        function makeShowOptionsHandler(item) {
            // Our event comes to us from jQuery, but we pass on the raw
            // event to the callback
            return function (event) {
                showOptions.call(context, event.originalEvent || event, item);
            };
        }

        function addRowHeader(listRef, name) {
            listRef.append(
                "<tr>" +
                    "<td colspan='2' class='divider'>" + name + "</td>" +
                    "</tr>"
            );
        }

        function showTitle(event) {

            $.stopEvent(event);

            var link = this;
            var $link = $(this);
            var href = $link.attr("href");  // We want the attribute, not the property (the property is usually expanded)
            var hrefTitle = $link.attr('hreftitle') || BETranslate(inst._channelId, 'HSMoreInfo');
            var data = $link.attr('data') || "";
            var linkId = link.id;

            if (!dataShownFlags[linkId]) {
                dataShownFlags[linkId] = true;
                if (data) {
                    var div = $(
                        "<div class='data'>" +
                            "<span data-linkId='" + linkId + "' class='close'>x</span>" +
                            "<table><thead></thead></table>" +
                            "</div>"
                    );
                    $link.parent().append(div);

                    var thead = div.find("thead");
                    var arr = data.split('~');
                    var splitEntry;

                    for (var x = 0; x < arr.length; x++) {
                        splitEntry = arr[x].split('|');
                        if (splitEntry[0] === 'Changed length') {
                            splitEntry[1] = splitEntry[1].replace(/\d+/g, BEFramework.prettyTime);
                        }
                        if (splitEntry.length > 1 && splitEntry[1].length > 0) {
                            thead.append(
                                "<tr>" +
                                    "<td class='hslabel'>" + splitEntry[0] + ":</td>" +
                                    "<td>" + splitEntry[1] + "</td>" +
                                    "</tr>"
                            );
                        }
                    }

                    div.find("span:first").click(hideTitle);

                    if (href && href !== "#") {
                        $("<a target='_blank'>" + hrefTitle + "</a>").attr("href", href).appendTo(div);
                    }
                }
            }
        }

        function hideTitle(event) {
            var $this = $(this),
                linkId = $this.attr("data-linkId");
            delete dataShownFlags[linkId];
            $this.parent().remove();
            return false;
        }

        function goToPreviousPage(event) {
            --pageIndex;
            doLoad();
            return false;
        }
        function goToNextPage(event) {
            ++pageIndex;
            doLoad();
            return false;
        }
    }

    var ___x = false;
    var __i = 0;

    BEFramework.prototype.hstreamEvalJson = hstreamEvalJson;
    function hstreamEvalJson(item) {
        var inst = this;

        if (item.Action === 'saveinsurance' && !___x && __i != 0){
            var start = +new Date();
            __i = 1;
        }

        var userId = inst._BEUser ? inst._BEUser.getId() : -1;
        var json = eval('(' + item.JSON + ')');
        var key = 'HS' + item.Module + '_' + item.Action;
        var msg = BETranslate(inst._channelId, key);
        var fromIsMe = item.CreatedByContactId == userId;
        var toIsMe = item.ContactId == userId;
        var fromString = (fromIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYou') + '</strong>' : '<a class="vcard" contactId="' + item.CreatedByContactId + '">' + item.CreatedByName + '</a>';
        var toString = (toIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYour') + '</strong>' : '<a class="vcard" contactId="' + item.ContactId + '">' + item.ContactName + '</a>';
        var fromString2 = (fromIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYour').toLowerCase() + '</strong>' : '<a class="vcard" contactId="' + item.CreatedByContactId + '">' + item.CreatedByName + '</a>';
        var toString2 = (toIsMe) ? '<strong>' + BETranslate(inst._channelId, 'HSYou').toLowerCase() + '</strong>' : '<a class="vcard" contactId="' + item.ContactId + '">' + item.ContactName + '</a>';
        var subFormat, subProps;
        var configObject = (BEFramework.healthStreamConfig[item.Module] && BEFramework.healthStreamConfig[item.Module][item.Action]) || {};
        var standardCase = configObject.standardCase;
        var suppress = configObject.suppress || [];
        var propertiesInOrder = configObject.displayOrder || [];

        if (msg.indexOf('not found in module') != -1) {
            try {
                switch (item.Module) {
                    case 'contacts':
                        if (item.Action == 'setpermission' || item.Action == 'deleterelationship' || item.Action == 'addinvite') {
                            msg = BETranslate(inst._channelId, key + json.type.toString());
                        }
                        break;
                    case 'tasks':
                        if (item.Action == 'savetask') {
                            msg = BETranslate(inst._channelId, key + json.type.toString());
                        }
                        break;
                    default:
                        msg = '';
                }
            } catch (ex) {
                msg = '';
            }
        }

        for (var prop in json) {
            if (typeof (json[prop]) == 'object') {

                if (prop === 'changes' || prop === 'deleted'){
                    subProps = json[prop];

                    for (var propName in subProps) {
                        if (indexInArrayCI(propName, propertiesInOrder) === -1 && indexInArrayCI(propName, suppress) === -1){
                            propertiesInOrder.push(propName);
                        }
                    }
                }

                if (prop == 'changes') {
                    var changes = '';
                    var changeFrom = BETranslate(inst._channelId, 'HSChangedFrom');
                    var changeTo = BETranslate(inst._channelId, 'HSChangedTo');

                    for (var i = 0; i < propertiesInOrder.length; i++) {
                        var subprop = propertiesInOrder[i];
                        if (getObjectValCI(subProps, subprop) == null) continue;

                        var subSplit = stripHtml(getObjectValCI(subProps, subprop)).split('|');

                        if (subSplit.length === 1) {
                            subFormat = BETranslate(inst._channelId, 'HS' + item.Module + '_changes_' + subprop);
                            if (subFormat.indexOf('not found in module') < 0) {
                                changes += $.sandr(subFormat, '#{value}', subSplit[0]);
                            }
                            else {
                                changes += "*|" + subprop + " " + subSplit[0] + "~";
                            }
                        }
                        else {
                            var fromValue = stripHtml(subSplit[0]);
                            var toValue = stripHtml(subSplit[1]);

                            var packetInfo = processChangedValues(subprop, fromValue, toValue);
                            if (packetInfo.skip) continue;

                            changes = changes + changeFrom + packetInfo.display + '|' + packetInfo.fromValue + '<b>' + changeTo + '</b>' + packetInfo.toValue + '~';
                        }
                    }

                    msg = $.sandr(msg, '#{' + prop + '}', changes);
                } else if (prop == 'deleted') {
                    var deleted = '';

                    for (var i = 0; i < propertiesInOrder.length; i++) {
                        var subprop = propertiesInOrder[i];
                        var currentValue = getObjectValCI(subProps, subprop);

                        if (currentValue == null || currentValue.toString().length === 0) continue;

                        deleted = deleted + getDisplayForLabel(subprop) + '|' + getDeleteValue(subprop, currentValue) + '~';
                    }

                    msg = $.sandr(msg, '#{' + prop + '}', deleted);
                }
            } else {
                msg = $.sandr(msg, '#{' + prop + '}', $.sandr(json[prop], '"', ' '));
            }

            function processChangedValues(label, fromValue, toValue){
                var typeFormat = (getObjectValCI(configObject, label) || {}).type;
                var result = {};

                if (typeFormat === 'date'){
                    var d1 = new Date(fromValue);
                    var d2 = new Date(toValue);

                    if (isDateEqual(d1, d2)) result.skip = true;
                }

                result.fromValue = getValueToDisplay(fromValue, typeFormat);
                result.toValue = getValueToDisplay(toValue, typeFormat);

                result.display = getDisplayForLabel(label)

                return result;
            }

            function getDeleteValue(label, value){
                var typeFormat = (getObjectValCI(configObject, label) || {}).type;

                return getValueToDisplay(value, typeFormat);
            }

            function getValueToDisplay(rawValue, typeFormat){
                if (typeFormat === 'date'){
                    var d = new Date(rawValue);
                    return isNaN(d.getTime()) ? rawValue : d.toString('MM/dd/yyyy');
                } else if (typeof typeFormat === 'function') {
                    return typeFormat(rawValue)
                } else {
                    return rawValue;
                }
            }

            function getDisplayForLabel(label){
                var fixCaseOfProperty = standardCase === '*' || indexInArrayCI(label, standardCase) > -1;
                var rawConfigForLabel = getObjectValCI(configObject, label) || {};

                return (rawConfigForLabel && rawConfigForLabel.display)
                        || (fixCaseOfProperty ? fixCase(label) : null)
                        || label;
            }
        }

        msg = $.sandr(msg, '#{contactId}', item.ContactId);
        msg = $.sandr(msg, '#{from}', fromString);
        msg = $.sandr(msg, '#{to}', toString);
        msg = $.sandr(msg, '#{from2}', fromString2);
        msg = $.sandr(msg, '#{to2}', toString2);
        msg = $.sandr(msg, '#{recordId}', item.RecordId);

        msg = msg.replace(/#{[\S]*}/g, '');

        if (item.Action === 'saveinsurance' && !___x && __i == 1){
            var end = +new Date();
            ___x = true;
            //alert(end - start);
        }

        if (item.Action === 'saveinsurance') __i++;

        if (msg.indexOf('not found in module') == -1) {
            return msg;
        } else {
            return '';
        }
    }

    function stripHtml(html) {
        var tmp = document.createElement('DIV');
        tmp.innerHTML = html;
        return tmp.textContent || tmp.innerText;
    }

    function isDateEqual(date1, date2) {
        if (date1.getDate() === date2.getDate() &&
            date1.getMonth() === date2.getMonth() &&
            date1.getYear() === date2.getYear()) {
            return true;
        }
        else {
            return false;
        }
    }

    function getObjectValCI(obj, key){
        for (var k in obj){
            if (k.toLowerCase() === key.toLowerCase()){
                return obj[k];
            }
        }
    }

    function indexInArrayCI(item, arr){
        if (!$.isArray(arr)) arr = [];

        var target = item.toString().toLowerCase();

        for (var i = 0; i < arr.length; i++){
            if (target === arr[i].toLowerCase()) return i;
        }
        return -1;
    }

    function fixCase(str){
        return str.replace(/[a-z][A-Z]/g, function(match) { return match.charAt(0) + ' ' + match.charAt(1).toLowerCase(); }).toLowerCase()
            .replace(/\sid\s/g, ' ID ')
            .replace(/\sid$/g,  ' ID')
            .replace(/^id$/g,  'ID');
    }
})();
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T17:09:39+00:00Added an answer on June 13, 2026 at 5:09 pm

    Well, there are too many errors to think of. First of all, I don’t understand if you want static reference or instantiated values. You are not using jsDoc tags or anything like that. The Compiler does it’s best work only with the corresponding jsDoc tag. You’re logic is very weird and ill formulated. Prototype alternations, etc, all happening in an IIFE(immediately invoked function expression). Are your functions static? Are they constructors? Are we human or are we dancer?

    an IIFE executes before the DOMContentLoaded event is fired by the browser. The most you can do is a jQuery IIFE equivalent $(function() {})(); which binds that to the DOMReady or DOMContentLoaded callback. You are defining inline functions inside blocks, which is not even in the ECMA Language.

    While most script engines support Function Declarations within blocks it is not part of ECMAScript (see ECMA-262, clause 13 and 14). Worse implementations are inconsistent with each other and with future EcmaScript proposals. ECMAScript only allows for Function Declarations in the root statement list of a script or function. Instead use a variable initialized with a Function Expression to define a function within a block.

    var myFunctionName = function (params) {};
    

    You are also missing loads of semi-colons. Automatic semi-colon insertion on interpretation of your JS is not exactly flawless, so make a habit out of it.

    Relying on implicit insertion can cause subtle, hard to debug problems. Don’t do it. You’re better than that.

    There are a couple places where missing semicolons are particularly dangerous:

    // 1.
    MyClass.prototype.myMethod = function() {
      return 42;
    }  // No semicolon here.
    
    (function() {
      // Some initialization code wrapped in a function to create a scope for locals.
    })();
    
    
    var x = {
      'i': 1,
      'j': 2
    }  // No semicolon here.
    
    // 2.  Trying to do one thing on Internet Explorer and another on Firefox.
    // I know you'd never write code like this, but throw me a bone.
    [normalVersion, ffVersion][isFF]();
    
    
    var THINGS_TO_EAT = [apples, oysters, sprayOnCheese]  // No semicolon here.
    
    // 3. conditional execution a la bash
    -1 == resultOfOperation() || die();
    

    So what happens?

    JavaScript error – first the function returning 42 is called with the second function as a parameter, then the number 42 is “called” resulting in an error.
    You will most likely get a ‘no such property in undefined’ error at runtime as it tries to call x[ffVersion][isIE]().
    die is called unless resultOfOperation() is NaN and THINGS_TO_EAT gets assigned the result of die().
    Why?

    JavaScript requires statements to end with a semicolon, except when it thinks it can safely infer their existence. In each of these examples, a function declaration or object or array literal is used inside a statement. The closing brackets are not enough to signal the end of the statement. Javascript never ends a statement if the next token is an infix or bracket operator.

    This has really surprised people, so make sure your assignments end with semicolons.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Edit: Lesson learned: set the orientation or stuff might not show up. As per
EDIT: I was an idiot. I simply had an image that was vertically long,
EDIT: See my answer below--> I am wanting to have a view that when
Edit (updated question) I have a simple C program: // it is not important
EDIT: iam using ajax to load text in my content that is why onload
Edit : Note that, as Daniel and latkin noted in an answer and a
EDIT : It turned out that this can only be done through an external
I'm trying to make a function that does the following: it gets a list
So this is my first real Ruby on Rails project. I've learned my lesson
I have a model (share) in which I save who can edit a lesson.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.