marionette.inspector icon indicating copy to clipboard operation
marionette.inspector copied to clipboard

Capture _classPath, _className, _templatePath via patchDefine

Open jasonLaster opened this issue 9 years ago • 5 comments

Overview

One of the things we do at Etsy that I really like, is that we add _classPath and _className properties to all of our class prototypes. The way we do it, is to monkeypatch the define function in development and detect the classes as they're defined. When we find a class, we use the require path as the class path.

I think we can do something similar in patchDefine for the inspector. The way it would work, is that we'd add some extra functionality to patchFactoryFunc so that in addition to checking to see if the module is Marionette or Backbone, it also checks to see if it's a Backbone View or Model class. If it is, it adds those properties to the prototype.

The benefit of having _className on the prototype is that the inspector can show the class instead of the generic type. In the case of the footer view,'<Backbone.View 12> would be replaced with <FooterView 12>. How cool is tha? So cool!


Implementation

  1. improve _patchFactoryFunc
_patchFactoryFunc = function () {
var functionBody = function (bodyArguments) {
      var module = originalFunction.apply(this, bodyArguments);
      var Candidate = module || this;

      // check for backbone
     // check for marionette

     if (loadedModules.Backbone  
        && instanceof module == loadedModules.Backbone.View 
        || module == loadedModules.Backbone.model) {

        module._classPath = the.definePath // we'll have to find that somewhere... could be (views/footerView)
        module._className = the.definePath.split('/').chomp()
       module._templatePath = the.templatePath // might be hard to find "template!foo/blah" in the dependencies
    }
}

jasonLaster avatar Nov 30 '14 22:11 jasonLaster

I think we should consider using displayName instead of _className

It is a non-standard way of doing this that some browsers currently handle in one way or another: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/displayName

But one reason to use it, is that other people are. JSX and react add displayName. https://github.com/facebook/react/pull/799 And their devtools uses it to determine what objects are. https://github.com/facebook/react-devtools/blob/e47bccd514121574c95fcfc80f4bf2b3e5bb91ca/injected/InjectedScriptHost.js#L47

paulfalgout avatar Mar 17 '15 04:03 paulfalgout

neat - good thinking

jasonLaster avatar Mar 17 '15 15:03 jasonLaster

Might be easier to add a polyfill for Function.name.

jklmli avatar Apr 23 '15 04:04 jklmli

Function.name unfortunately doesn't work here.

var m = new Backbone.Model();

console.log(m.constructor.name); // => undefined

paulfalgout avatar Apr 23 '15 05:04 paulfalgout

Ah, it doesn't work for anonymous functions.

jklmli avatar Apr 24 '15 01:04 jklmli