Skip navigation
R.A.A
Currently Being Moderated

How to extend/add additional functionality (to) an InDesign class like Cell

Aug 2, 2011 9:28 AM

Hello,

I am trying to add some extra functionality to every instance of e.g. the Cell 'class' of InDesign using Javascript. I started doing something like this:

 

Cell.prototype.newFunction = function() { ....... }

 

which works fine: it is now possible to call newFunction() on every instance of Cell.

But now I would like to let this function (that I've added to the prototype chain of Cell like shown above and thus is also available for an 'instance' of Cell) use a 'variable' that is specific for every Cell instance, e.g.:

  

Cell.prototype.getSuperValue = function ()

{

if (this._cachedValue === undefined)

{

this._cachedValue = 3; // doing some incredible calculations that take some time

}

return this._cachedValue;

};

  

The this._cachedValue should be a attribute of the Cell instance. So if I take to cells from a Table and I call getSuperValue() on them I can get two different values that are specific for every instance of Cell.

 

  

Thanks a lot in advance!

  

P.S. although I am quite new to Javascript I know there are no classes in Javascript and that Cell is an object. But I thought explaining it like this would make it more clear?

  • Currently Being Moderated
    Community Member
    Aug 2, 2011 9:43 AM

    The implication is that you've tried it and it does not actually work.

    But you don't actually say that?

     

    So what exactly is the problem or behavior you are seeing?

     

    (I would sort of expect this not to work very well with InDesign DOM objects, because they don't behave like normal Javascript objects all of the time. But you might be lucky.)

    |
    Mark as:
  • Currently Being Moderated
    Community Member
    Aug 2, 2011 10:11 AM

    Yeah, I don't think that's going to work for you.

    But you could cheat and store the data in an array indexed by cell id, something like (untested):

     

    Cell.prototype.getSuperValue = function () {
      var CellCache = [];
      if (cellCache[this.id] === undefined) {
        cellCache[this.id] = 3; // doing some incredible calculations that take some time
      }
      return cellCache[this.id];
    };
    

     

    I don't know if inheritance is going to screw it up for you and maybe you want to index by this.toSpecifier().

    And maybe using a sparse array is a bad idea and you should use an Object instead, i.e. var cellCache = {};

    |
    Mark as:
  • Currently Being Moderated
    Community Member
    Aug 2, 2011 12:45 PM

    As John said, DOM objects have different behaviour than pure JS objects. More precisely, DOM objects are just syntactic specifiers that encapsulate commands, they don't actually give you read-and-write access to the final InDesign components. For example, what you call an 'instance' of the Cell object just represents a command, which may or may not point out to one, or several, actual InDesign cell(s). So when you extend the prototype of such object, you simply 'decorate' the interface of that command, but this has no impact on actual document cells:

     

    Cell.prototype.myProperty = 1;
    Cell.prototype.myMethod = function(){ alert('foo'); };
     
    // individual specifier:
    alert( myTable.cells[0].myProperty );           // => 1
     
    // collective specifier:
    alert( myTable.cells.everyItem().myProperty );     // => 1!
     
    // individual specifier:
    myTable.cells[0].myMethod();               // => 'foo'
     
    // collective specifier:
    myTable.cells.everyItem().myMethod();          // => 'foo' (once!)
    

     

    In the example above, myProperty and myMethod() does not extend cell's interface in terms of component's interface. This syntactically works as long as you don't attempt to write data within the real cell component (which you cannot extend):

     

    myTable.cells[0].myProperty = 2; // ERROR: myProperty is not supported!
    

     

    That said, ExtendScript provide a way to store data in most of the components through the label property. In your project, you probably could serialize your data and use Cell.label to manage it.

     

    @+

    Marc

    |
    Mark as:
  • Currently Being Moderated
    Community Member
    Aug 2, 2011 12:51 PM

    Just agreeing with John and Marc, that you do not want to be using native objects the way you are.

     

    John's method of using ids is not great, because the id of a cell is its coordinates, so the id is not unique across different tables.

     

    Using Cell.label (or better yet (Cell.insertLabel() and Cell.extractLabel()) is the way to go...

     

    Harbs

    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points