monocle icon indicating copy to clipboard operation
monocle copied to clipboard

Monocle.Templates cache system can be broken after minification

Open atabel opened this issue 11 years ago • 6 comments

This issue is related to: https://github.com/jashkenas/coffee-script/issues/2052

In https://github.com/soyjavi/monocle/blob/master/src/monocle.view.coffee, Monocle.Templates is used to cache the templates:

_loadTemplateFrom: (url) ->
        className = @constructor.name

        unless Monocle.Templates[className]
            loader = if $$? then $$ else $
            response = loader.ajax
                            url: url
                            async: false
                            dataType: 'text'
                            error: -> console.error arguments
            response = response.responseText unless $$?
            Monocle.Templates[className] = response

        @template = Monocle.Templates[className]

The used cache key is @constructor.name, which can be anything after minification, so it can generate key duplicates. As a result, two different views could end sharing the same template by error if both views were minified to the same variable name.

atabel avatar Aug 22 '13 14:08 atabel

Hi!, I'm working on it :)

soyjavi avatar Sep 10 '13 21:09 soyjavi

Fixed :) https://github.com/soyjavi/monocle/commit/035781e8d0ea386be6eddc9e6e46b927830b885d

soyjavi avatar Sep 11 '13 06:09 soyjavi

I think this doesn't fix the issue.

For example, if we have 2 Monocle views:

view1.coffee

class __View.View1 extends Monocle.View
    template_url: "templates/view1.mustache"

view2.coffee

class __View.View2 extends Monocle.View
    template_url: "templates/view2.mustache"

Once we "compile" these views to js we have:

view1.js

(function() {
  var __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  __View.View1 = (function(_super) {

    __extends(View1, _super);

    function View1() {
      return View1.__super__.constructor.apply(this, arguments);
    }

    View1.prototype.template_url = "templates/view1.mustache";

    return View1;

  })(Monocle.View);

}).call(this);

view2.js

(function() {
  var __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  __View.View2 = (function(_super) {

    __extends(View2, _super);

    function View2() {
      return View2.__super__.constructor.apply(this, arguments);
    }

    View2.prototype.template_url = "templates/view2.mustache";

    return View2;

  })(Monocle.View);

}).call(this);

And when we minify the view1.js and view2.js we have:

view1.min.js

!function(){var a={}.hasOwnProperty,b=function(b,c){function e(){this.constructor=b}for(var d in c)a.call(c,d)&&(b[d]=c[d]);return e.prototype=c.prototype,b.prototype=new e,b.__super__=c.prototype,b};__View.View1=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.template_url="templates/view1.mustache",c}(Monocle.View)}.call(this);

view2.min.js

!function(){var a={}.hasOwnProperty,b=function(b,c){function e(){this.constructor=b}for(var d in c)a.call(c,d)&&(b[d]=c[d]);return e.prototype=c.prototype,b.prototype=new e,b.__super__=c.prototype,b};__View.View2=function(a){function c(){return c.__super__.constructor.apply(this,arguments)}return b(c,a),c.prototype.template_url="templates/view2.mustache",c}(Monocle.View)}.call(this);

So, as you can see, both views contructor function has the same name after minification (c), which is the value that is going to be assigned to @className in the constructor of Monocle.Controller. So both classes will share the same cache key in Monocle.Templates, as they have the same name.

atabel avatar Sep 14 '13 22:09 atabel

Oouch!! I'll work on it... I'm sorry :(

soyjavi avatar Oct 17 '13 19:10 soyjavi

Not fix?

grigorov avatar Jan 27 '15 14:01 grigorov

yes it was finished, please update your monocle version.

— Javi Jiménez Villar @soyjavi

On Tue, Jan 27, 2015 at 9:52 PM, Aleksandr Grigorov [email protected] wrote:

Not fix?

Reply to this email directly or view it on GitHub: https://github.com/soyjavi/monocle/issues/11#issuecomment-71659823

soyjavi avatar Jan 28 '15 02:01 soyjavi