7 Replies Latest reply on Dec 7, 2015 4:50 AM by Trevorׅ

    MutationEvents

    Trevorׅ Adobe Community Professional

      Hi

       

      Why doesn't the below snippet work?

      #targetengine follow
      var doc = app.documents.add(), followMe, followHim, followEvent, n;
      followMe = doc.pages[0].textFrames.add({geometricBounds:["20mm", "20mm", "100mm", "100mm"], fillColor: "Cyan", contents: "Follow Me"});
      followHim = doc.pages[0].textFrames.add({geometricBounds:["120mm", "20mm", "200mm", "100mm"], fillColor: "Magenta", contents: "Follow Him"});
      function follow () {
          followHim.properties = followMe.properties;
          followHim.geometricBounds[0] += 100;
          followHim.geometricBounds[2] += 100;
          followHim.contents = "I'm following him"
      }
      followEvent = followMe.addEventListener(MutationEvent.AFTER_ATTRIBUTE_CHANGED, follow);
      for (n in followEvent) $.writeln(n + ": " + followEvent[n]);
      

       

      Trevor

        • 1. Re: MutationEvents
          TᴀW Adobe Community Professional & MVP

          As far as I can tell, only a Window, LayoutWindow, StoryWindow, Movie, Sound, MediaItem, Link, and Toolbox have an "afterAttributeChanged" event. TextFrames don't!

          • 2. Re: MutationEvents
            TᴀW Adobe Community Professional & MVP

            You could do something like this, I suppose:

            #targetengine follow 
            var doc = app.documents.add(), followMe, followHim, followEvent, n; 
            followMe = doc.pages[0].textFrames.add({geometricBounds:["20mm", "20mm", "100mm", "100mm"], fillColor: "Cyan", contents: "Follow Me"}); 
            followHim = doc.pages[0].textFrames.add({geometricBounds:["120mm", "20mm", "200mm", "100mm"], fillColor: "Magenta", contents: "Follow Him"}); 
            function follow () {
                //followHim.properties = followMe.properties;
              g = followMe.geometricBounds;
              g[0] += 100;
              g[2] += 100;
                followHim.geometricBounds = g;
              followHim.contents = "I'm following him" 
            } 
            followEvent = app.eventListeners.add(Event.AFTER_SELECTION_ATTRIBUTE_CHANGED, follow); 
            
            
            • 3. Re: MutationEvents
              Marc Autret Level 4

              Hi,

               

              AFTER_SELECTION_ATTRIBUTE_CHANGED doesn't work as expected with me :-/

               

              I you really need to synchronize your objects, I suggest you use an idleTask instead:

               

              #targetengine follow
              
              var doc = app.documents.add(),
                  master, slave;
              
              master = doc.pages[0].textFrames.add({geometricBounds:["20mm", "20mm", "100mm", "100mm"], fillColor: "Cyan", contents: "MASTER"});
              slave = doc.pages[0].textFrames.add({geometricBounds:["120mm", "20mm", "200mm", "100mm"], fillColor: "Cyan", fillTint:40, contents: "SLAVE"});
              
              function follow()
              {  
                  if( !master || !master.isValid ) return;
                  if( !slave || !slave.isValid ) return;
                  
                  var pm = master.properties, ps = slave.properties, t;
                  
                  if( ps.fillColor !== (t=pm.fillColor) ) { slave.fillColor = t }
                  if( ps.contents !== (t=pm.contents) ) { slave.contents = t }
                  // etc.
              
                  if( !follow.CACHE )
                      {
                      follow.CACHE = pm.geometricBounds.concat();
                      return;
                      }
                  if( follow.CACHE.toSource() != (t=pm.geometricBounds).toSource() )
                      {
                      var dx = t[1]-follow.CACHE[1];
                      var dy = t[0]-follow.CACHE[0];
                      slave.move(undefined,[dx,dy]);
                      
                      // etc.
              
                      follow.CACHE.length = 0;
                      [].push.apply(follow.CACHE,t);
                      }
              }
              
              (function(tasks,name,rate,callback)
              {
                  var t = tasks.itemByName(name);
                  if( t.isValid ){ t.eventListeners.everyItem().remove(); t.remove(); }
                  tasks.add({name:name, sleep:rate}).addEventListener(IdleEvent.ON_IDLE, callback, false);
              
              })(app.idleTasks,'followTask',15,follow);
              

               

              @+

              Marc

              • 4. Re: MutationEvents
                Trevorׅ Adobe Community Professional

                Hi

                 

                Thanks for the replies. According to the scripting reference Adobe InDesign CS6 (8.0) Object Model JS: MutationEvent textFrames along with a myriad of other dom objects do have mutation events.  In the past I have used Marc's solution but I thought perhaps that the mutation event is less aggressive than the idle event, which has a tendency to make the engine busy.  The AFTER_SELECTION_ATTRIBUTE_CHANGED event is not suitable although it does work for me but it only works on as it's name suggest the selected item so won't work if the items not selected, i.e. script events.

                I guess that the way to go is through the idle tasks but contrary to the object reference the first answer given is the correct one.

                 

                Thanks again,

                 

                Trevor

                • 5. Re: MutationEvents
                  TᴀW Adobe Community Professional & MVP

                  In the DOM browser in ESTK, as opposed to Jongware's, you'll find the available events for each object in the list of static properties for each object (Class). It could be that only those listed there actually do anything. (Now I see that also in Jongware's help only beforePlace and afterPlace are actually listed as static members of the TextFrame object.) I've always presumed that only those events that are listed under Class will actually work for a given object.

                  • 6. Re: MutationEvents
                    Marc Autret Level 4

                    TᴀW a écrit:

                     

                    (…) I've always presumed that only those events that are listed under Class will actually work for a given object.

                     

                    That's a good point. The beforePlace and afterPlace event types are statically registered at the PageItem level (and shared by the corresponding subclasses) which probably indicates that those kinds of objects can trigger those types of events. Here by “triggering” I mean that any PageItem can be the target of a (before/after)Place event—keeping in mind that one can still attach the listener to any parent in the hierarchy, e.g. a document or app.

                     

                    Using the same reasoning for afterAttributeChanged, we can notice that this event type is statically registered at the Window level, not at the Document level. From what we can conclude that afterAttributeChanged is mainly triggered by Window objects (incl. LayoutWindow and StoryWindow) and then is not connected to attribute changing at the pageitem or document levels. Interestingly this event also appears under the MediaItem, Link and ToolBox classes.

                     

                    As for afterSelectionChanged and afterSelectionAttributeChanged, we only find them at Window and app levels, so here again they do not target pageitems, although one may still run a scan on app.properties.selection when such event occurs. But I remain very dubious about the actual sensitivity and scope of those events. Maybe they are just flags for some GUI changing states, not including every “selection change” that is relevant to us.

                     

                    Apart from that I agree the IdleTask approach is highly resource-consuming and shouldn't be the right answer in a perfect world. Anyway it works (for me) in a very responsive and funny way :-)

                     

                    @+

                    Marc

                    • 7. Re: MutationEvents
                      Trevorׅ Adobe Community Professional

                      Yep there's definitely some amusing about moving one of those rectangles around  and seeing the other one move with it. Can't wait for the sequel of InTetris

                      Thanks for the explanation, it makes a lot of sense and satisfactory answers my question.  At some point in history the object model might get corrected.

                       

                      Trevor