how to use importAnnotations() for lazy loading of external annotation

1,040 views
Skip to first unread message

Danny Mendel

unread,
May 30, 2016, 1:59:00 PM5/30/16
to PDFTron WebViewer
hi Matt,

first of all i would like to congratulate you guys on really awesome job you did with the WebViewer and with PDFTRON in general. you really nail it down! too good!

regarding my question,
i would like to use importAnnotations() api in order to load annotation (externally), separately and  long after the document has been loaded. typically i would like to use the importAnnotations() in order to synchronize between participants who are sharing / working on same document, yet editing/modifying the annotations. so the exercise i'm looking to hear from you guys, is how to use the importAnnotations() called from my main JS application w/o forced to load the entire document (via "loadDocument") firstly.

i manage to run this code successfully

$(document).on('documentLoaded', function() {
        var annotManager = readerControl.docViewer.getAnnotationManager();
data = '<?xml version="1.0" encoding="UTF-8" ?><xfdf xmlns="http://ns.adobe.com/xfdf/...." 
annotManager.importAnnotations(data);        
}):

but when i tried same code w/o $(document).on('documentLoaded', it seems not to work at all.

can you help guys, showing me what is the "right" way to treat "lazy" loading or import annotation to existing document, without forced to reload the entire document ?

Many many thanks.
Danny

Kristian Hein

unread,
May 30, 2016, 8:16:06 PM5/30/16
to PDFTron WebViewer
Hello Danny,

Yes, you can not use annotManager.importAnnotations before the 'documentLoaded' event. This is because AnnotationManager is not initialized until said event triggers.
To make sure that importAnnotations gets called after the 'documentLoaded' event you can use the following code:

var isDocumentLoaded = false;

$(document).on('documentLoaded', function() {
    isDocumentLoaded = true;
});

// call this whenever you want to import annotations
function gotMyAnnotations(data) {
  if (isDocumentLoaded) {
    importAnnotations(data);
  } else {
    // if the document has not been loaded then we queue up the call
    $(document).one('documentLoaded', function() {
      importAnnotations(data);
    });
  }
}

function importMyAnnotations(data) {
  var annotManager = readerControl.docViewer.getAnnotationManager();
  annotManager.importAnnotations(data);   
}

Danny Mendel

unread,
Jun 3, 2016, 4:17:02 PM6/3/16
to PDFTron WebViewer
Dear Kristian

thanks for your reply
however testing your code gives same result as mine
 $(document).one('documentLoaded', function() {
      importAnnotations(data);
    });

works fine, like running it under $(document).on('documentLoaded', function() .... event handler

however this part is not important for "lazy" operation, as my desire is to run annotation much after and not in relation with the actual "documentloaded" event (my server is sending a push event "load annotation" with data read from xfdf file... to other participants in specific given time by request much after the original doc has been loaded)

So, when i try to run the first part - the "Lazy / much later than document is loaded"
if (isDocumentLoaded) {
    importAnnotations(data);
  } 

i get Zero effect, no new "data" annotatoin merged into existing doc, exactly as i have been reported.

can you please send me a working sample, where i can actually see working in "real-life" for you ?

for simplifying my implmentation i prepare a quick xfdf "Data" string which works as expected invoked by documentloaded even handler, but can never run by later/lazy request.

code -->

data = '<?xml version="1.0" encoding="UTF-8" ?><xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"><fields /><annots><ink subject="Free Hand" page="0" rect="38.19,354.63,563.95,517.36" flags="print" name="5f149845-65ce-3c68-80b2-091a2894ea19" title="Guest" date="D:20150414172649-07\'00\'" color="#FF0000" width="3" opacity="1" creationdate="D:20150414172636-07\'00\'"><inklist><gesture>321.72,515.11;210.97,515.11;190.75,513.35;155.59,512.47;138.01,509.83;119.55,508.95;102.85,505.44;65.93,492.25;59.77,488.74;50.1,480.83;44.83,473.79;40.44,461.49;40.44,448.3;42.19,439.51;47.47,425.45;58.02,412.26;61.53,411.38;68.56,406.11;102.85,385.89;109.88,383.25;116.03,379.74;125.7,377.1;139.76,370.95;148.55,369.19;152.95,366.55;158.22,366.55;171.41,363.04;214.48,362.16;259.31,359.52;270.74,357.76;296.23,356.88;375.34,356.88;387.65,360.4;398.2,361.28;409.62,363.92;423.69,369.19;440.39,371.83;475.55,379.74;491.37,385.89;504.56,388.53;525.66,396.44;539.72,403.47;542.36,406.11;549.39,410.5;550.27,412.26;556.42,417.54;559.94,423.69;561.7,430.72;561.7,462.37;557.3,472.91;552.91,478.19;544.99,483.46;539.72,485.22;523.9,487.86;497.53,487.86;482.58,489.62;465.88,489.62;463.25,490.5;430.72,490.5;428.08,491.37;408.75,491.37;399.08,493.13;390.29,493.13;384.13,494.01;381.5,495.77;377.98,495.77;375.34,497.53;367.43,497.53;364.79,499.29;361.28,499.29;358.64,501.04;353.37,501.92;337.55,507.2;330.51,511.59;327,512.47;325.24,515.11;320.84,515.11</gesture></inklist></ink><text subject="Comment" page="0" rect="489.62,726.56,512.87,749.81" flags="print" name="0ab40e4d-3608-6b5f-2baf-bcbc8ccc7b94" title="Alice" date="D:20150414172739-07\'00\'" color="#FF00FF" opacity="1" creationdate="D:20150414172652-07\'00\'" icon="Comment"><contents-richtext><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:spec="2.0.2" xfa:APIVersion="Acrobat:10.1.3"><p dir="ltr"><span dir="ltr" style="font-size:10.0pt;text-align:left;color:#000000;font-weight:normal;font-style:normal">Note</span></p></body></contents-richtext><contents>Note</contents></text><freetext subject="FreeText" page="0" rect="113.39,132.73,393.8,276.89" flags="print" name="b8544e17-0a98-32cc-9e92-1cb5ff66a9b9" title="Bob" date="D:20150414172718-07\'00\'" color="#FF8000" width="0" opacity="1" creationdate="D:20150414172700-07\'00\'" TextColor="#008000" FontSize="36" fringe="0,0,0,0"><contents-richtext><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" xfa:spec="2.0.2" xfa:APIVersion="Acrobat:10.1.3"><p dir="ltr"><span dir="ltr" style="font-family: Verdana; font-size: 36pt; text-align: left; color: #008000;font-weight:normal;font-style:normal">Bob\'s Annotation</span></p></body></contents-richtext><contents>Bob\'s Annotation</contents><defaultappearance>0 0 0 rg /Verdana 36 Tf</defaultappearance><defaultstyle>font: Verdana 36pt; text-align: left; color: #008000</defaultstyle></freetext></annots><pages><defmtx matrix="1.333333,0,0,-1.333333,0,1056" /></pages></xfdf>';
                                    if (isDocumentLoaded) {
                                        //importAnnotations(sync.syncmap[2].Value);
                                        importAnnotations(data);
                                    } else {
                                        // if the document has not been loaded then we queue up the call
                                        $(document).one('documentLoaded', function () {
                                            importAnnotations(data);
                                        });
                                    }


Many Many thanks!
Danny

Danny Mendel

unread,
Jun 3, 2016, 4:54:56 PM6/3/16
to PDFTron WebViewer
hi Krisitian

ok it seems to work now

var annotManager = myWebViewer.instance.docViewer.getAnnotationManager();
                                    annotManager.importAnnotations(sync.syncmap[2].Value);
                                    var currentPage = myWebViewer.instance.docViewer.getCurrentPage();
                                    myWebViewer.instance.docViewer.setCurrentPage(currentPage);

the issue was that it didn't "render" modified new merged annotation.
now - the last question
i'm using an artificial way to "force" render to show latest annotation using SetCurrentPage() call
is there more elegant way to invalidate display without calling SetCurrentPage() ?

many thanks!

On Monday, May 30, 2016 at 8:59:00 PM UTC+3, Danny Mendel wrote:

Anatoly Kudrevatukh

unread,
Jun 3, 2016, 5:35:42 PM6/3/16
to PDFTron WebViewer
You can use https://www.pdftron.com/webviewer/demo/lib/html5/doc/symbols/CoreControls.AnnotationManager.html#drawAnnotationsFromList
e.g. annotManager.drawAnnotationsFromlist(annotManager.importAnnotations())

Let us know if that works for you

Danny Mendel

unread,
Jun 6, 2016, 3:27:37 PM6/6/16
to PDFTron WebViewer
i think i found a bug with form fields annotations.
var list = annotManager.getAnnotationsList()                                    
annotManager.deleteAnnotations(list, true, true);
annotManager.importAnnotationsAsync(sync.syncmap[2].Value, function (list) {
annotManager.drawAnnotationsFromList(list);
});

this code works best when i import added or modified text fields annotations,
however when i clean the fields from value to empty 
such as "danny" to "", the drawAnnotationsFromList refuses to update/override "old" value with the new "empty" value, and it keeps showing the "old" value, 
so to recap - import seems to do great job with following scenarios:
a. old "xxxx" to new "yyyyy"  value works great
b. old "<empty>" to new "yyyy" value works great

bug / failed job

c. old "xxxx" to new "<empty> value not changing, and viewer keeps the old "xxxx" value.

this is very important for me to solve, as i can not do real sync among participants who work on same "virtual" viewer

Many Many thanks.
Danny


On Monday, May 30, 2016 at 8:59:00 PM UTC+3, Danny Mendel wrote:

Danny Mendel

unread,
Jun 6, 2016, 3:27:37 PM6/6/16
to PDFTron WebViewer
so testing it again i found that the call just add the "imported" annotation into "existing" list.
so revised code look like this -

var list = annotManager.getAnnotationsList()
annotManager.deleteAnnotations(list, true, true);
annotManager.importAnnotationsAsync(sync.syncmap[2].Value, function (list) {
annotManager.drawAnnotationsFromList(list);
});              

now the issue i discover is that the "fields" annotations are not deleted as other types (draw, signiture, arrows etc....)

now the open question is what is the api call in order to "deleteFields()...." as well?

Many many thanks
Danny

Danny Mendel

unread,
Jun 6, 2016, 3:27:37 PM6/6/16
to PDFTron WebViewer
another interesting discovery/bug/behavior i found
annotManager = myWebViewer.instance.docViewer.getAnnotationManager();
annotManager.on('annotationChanged', function (e) {
// check whether the annotation change is triggered because of an import (e.g. bec                                           if (!e.imported) {
     throttledSave();
}
});

"annotationChanged" event is fired / raised by ALMOST all annotation BESIDE form fields text annotation.
which is the most important type for my implementation, for sharing sync experience of filling form together among different participants sharing the same "virtual" viewer.


On Monday, May 30, 2016 at 8:59:00 PM UTC+3, Danny Mendel wrote:

Danny Mendel

unread,
Jun 6, 2016, 3:27:37 PM6/6/16
to PDFTron WebViewer
annotManager.importAnnotationsAsync(sync.syncmap[2].Value, function (list) {
                                        annotManager.drawAnnotationsFromList(list);
                                    });

seems to do the job.

On Saturday, June 4, 2016 at 12:35:42 AM UTC+3, Anatoly Kudrevatukh wrote:

Matt Parizeau

unread,
Jun 9, 2016, 1:55:20 PM6/9/16
to PDFTron WebViewer
Hi Danny,

We've created a new build that should hopefully address the issues you're running into. http://www.pdftron.com/ID-zJWLuhTffd3c/WebViewer/WebViewer_2.2.0.45440.zip

It includes a fieldChanged event on AnnotationManager that will notify you when an field's value has changed. Use like:
annotManager.on('fieldChanged', function(e, field, newValue) {
  console
.log("new value is: " + newValue);
};

For importing updated XFDF we would recommend that you don't include the widgets in the saved XFDF (the field values will still be saved). To do this you can call annotManager.exportAnnotations({widgets: false});
Then when you import this XFDF on other clients there would not be duplicate widgets added but the field values would be updated.

One other thing to note is that if the annotations that are loaded in the viewer have the same annotation.Id (name attribute in XFDF) then they should be automatically merged when you call importAnnotations and you shouldn't have to delete all the annotations before importing the changes. Is this not the behavior you're finding? Maybe somehow the Ids are being set incorrectly which is causing duplicate annotations to be created?

Matt Parizeau
Software Developer
PDFTron Systems Inc.

Danny Mendel

unread,
Jun 10, 2016, 12:38:30 PM6/10/16
to PDFTron WebViewer
Matt,

this is a great addition, i have tested it, and it works fine,

however,
in order to sync with other participants what i'm using for field sync currently is the code which works with the annnotatoin sync

first this is how i sync annotation updates, i'm listen to annotationChanged, i get the xfdf string via getAnnotCommand() send this annotation update/delete/add string to server with similar code to this:


annotManager.on('annotationChanged', function (e, annotations, action) {                                                
                                                console.log("annot changed");
                                                if (!e.imported) {
                                                    throttledSave();
                                                    var command = annotManager.getAnnotCommand();
                                                     ... internal stuff....sending to my server for push command to other peers
                                                    app.sendData("viewer", command , "viewer");
                                                }
                                            });


with the participant code i'm using this listener code to call importAnnotCommand() with annotation command xfdf string representation , and use the drawAnnotations() to force canvas refresh 
which perfectly update/re-draw gui for given annotation field.

annotManager.importAnnotCommand(command)                                    annotManager.drawAnnotations(myWebViewer.instance.docViewer.getCurrentPage())

Great!

however when trying to do same trick with field sync, i run into issue
manage to pack into command via similar job

annotManager.on('fieldChanged', function (e, field, newValue) {
                                                debugger;
                                                console.log("new value is: " + newValue);
                                                var command = annotManager.getAnnotCommand();                                                                                            app.sendData("viewer", command, "viewer");
                                            });

but the above listener
annotManager.importAnnotCommand(command)                                    annotManager.drawAnnotations(myWebViewer.instance.docViewer.getCurrentPage())

has no impact on the canvas.
my question is there any missing link here? do i need to do other  importAnnotCommand or drawAnnotations like call but dedicated for given field update?

Many Many thanks
Danny

Danny Mendel

unread,
Jun 10, 2016, 12:38:30 PM6/10/16
to PDFTron WebViewer
hi Matt,
another issue i notice


annotManager.on('fieldChanged', function(e, field, newValue) {
var command = annotManager.getAnnotCommand();
};


On Thursday, June 9, 2016 at 8:55:20 PM UTC+3, Matt Parizeau wrote:

Danny Mendel

unread,
Jun 10, 2016, 12:38:30 PM6/10/16
to PDFTron WebViewer
hi Matt,
continue with your suggested solution ->
when debugging

annotManager.on('fieldChanged', function(e, field, newValue) {
   var command = annotManager.getAnnotCommand();
   console.log("new value is: " + newValue);
  };

a. i notice that getAnnotCommand() takes all updated fields (add/delete/modified) into complete xfdf string representation,
however i think what i need to achieve is xfdf string representation of given (single) modified of the above triggered event field object.

how can i transform the current triggered field new value into xfdf command w/o adding the entire metadata? is it possible or importAnnotCommand() deals just with updates of entire annotations (both add/delete/modified annotations and form values)

b. as mentioned previously putting the annotManager.getAnnotCommand()  list of modified fields as input into

the other participant listener code , here -> 
annotManager.importAnnotCommand(sync.syncmap[2].Value)                                    annotManager.drawAnnotations(myWebViewer.instance.docViewer.getCurrentPage())

it doesn't work, not setting any new value into the expected field, and also not trigger the fieldChanged / annotationChanged event handlers, simply not working for me, i wonder is it working your end ?
it will be very nice to see a working example if it is actually work for you.

i'm not sure if the problem is with importAnnotCommand or drawAnnotations, which of the two are indifferent with form values.

if this is a problem with importAnnotCommand () api call not supporting fields like his **working** brother api call importAnnotations/importAnnotationsAsync  than it will be nice to have a sample code how to iterate current form.fields to monitor the field tree for any change, just to make sure this is the actual problem ?

if the problem is with drawAnnotations(), i notice it has more paramters than just which page to draw to.
drawAnnotations(pageNumber, overrideCanvas, majorRedraw, overrideContainer)
do i need to do a majorRedraw in order to view the new form field ? if so i don't know how to build access to all those paramters in order to test the full paramterized call (how to access canvas etc...in order to prepare a valid call)

still have no clue, how to solve this to support remote update for a given triggered field.

c. suppose i would like to go other direction such as - to send the actual javascript "field" object, without transforming into xfdf representation string,  

is there an option to serialize / deserialize the above triggered field object, so i can re-clone/re-playback it on other participant webviewer instances ? offcourse the xfdf string seems like the simplest solution, however it doesn't work for me to this moment - somehow it neglects the form values. and i have no way to sync fields beside using the default annotationhandler server code which i would like to avoid, as i'm implementing a real-time sync of form filling and it less efficient to call annotationhandler save file + publish sync among clients each time give client simply add a value to a form field, i want to have a perfect instant sync of a triggered field to be updated (add/delete/modified) on remote viewers.

please advise
Many Many thanks.
Danny







On Thursday, June 9, 2016 at 8:55:20 PM UTC+3, Matt Parizeau wrote:

Danny Mendel

unread,
Jun 10, 2016, 4:36:58 PM6/10/16
to PDFTron WebViewer
Hi matt
so my "temp" solution till you introduce me a way to import specific field command or serailziation of triggered field

1) annotationchanged + fieldChanged event handlers
2) mark if it is a "command" for detected typed annotation or "xfdf"  for un-detected type import of form value
3) see how i detect new field empty value, and force to put "space" otherwise the importAnnotations/Async will not handle modify canvas with empty fields (i had already reported this strange behavior/bug on this thread - before)

annotManager.on('annotationChanged', function (e, annotations, action) {                                                
                                                if (remoteSyncCommand) {
                                                    remoteSyncCommand = false;
                                                    return;
                                                }
                                                console.log("annot changed");
                                                if (!e.imported) {
                                                    throttledSave();
                                                    var command = annotManager.getAnnotCommand();
                                                    last_sync = sync;
                                                    sync.invoker = app.username;
                                                    sync.ts = new Date();
                                                    if (sync.syncmap.length > 2)
                                                        sync.syncmap.splice(2, sync.syncmap.length - 2);
                                                    sync.synctype = 2;
                                                    sync.syncmap[2] = { Key: "command", Value: command }
                                                    app.sendData("viewer", sync, "viewer");
                                                }
                                            });
                                            annotManager.on('fieldChanged', function (e, field, newValue) {
                                                if (remoteSyncCommand) {
                                                    remoteSyncCommand = false;
                                                    return;
                                                }
                                                console.log("new value is: " + newValue);
                                                if (newValue.length == 0) // adding artificial spacing as import fail of empty fields
                                                    field.value = " ";
                                                var xfdfString = annotManager.exportAnnotations({ widgets: false });
                                                last_sync = sync;
                                                sync.invoker = app.username;
                                                sync.ts = new Date();
                                                if (sync.syncmap.length > 2)
                                                    sync.syncmap.splice(2, sync.syncmap.length - 2);
                                                sync.synctype = 2;
                                                sync.syncmap[2] = { Key: "xfdf", Value: xfdfString }
                                                app.sendData("viewer", sync, "viewer");
                                            });

3) remote participant code listner to handle with differet api calls if "command" or "xfdf"

if (sync.syncmap[2].Key == "command") {
                                        annotManager.importAnnotCommand(sync.syncmap[2].Value)
                                        annotManager.drawAnnotations(myWebViewer.instance.docViewer.getCurrentPage())
                                    }
                                    else if (sync.syncmap[2].Key == "xfdf") {
                                        annotManager.importAnnotationsAsync(sync.syncmap[2].Value, function (list) {
                                            annotManager.drawAnnotationsFromList(list);
                                        });
                                    }


let me know if you can advise better unified approach instead of hacking different import methods to handle sync of form values.

Many many thanks
Danny

Matt Parizeau

unread,
Jun 13, 2016, 1:59:31 PM6/13/16
to PDFTron WebViewer
Hi Danny,

Thanks for your comments. Can you try out this updated build that should address the issues you're having http://www.pdftron.com/ID-zJWLuhTffd3c/WebViewer/WebViewer_2.2.0.45632.zip.

The changes are:
  • Importing fields with an empty value should now work without adding a space
  • getAnnotCommand now only includes fields that have changed since the last time you called it, just like annotations
  • importAnnotCommand now imports fields values
Let us know how this works for you!

Matt Parizeau
Software Developer
PDFTron Systems Inc.

Danny Mendel

unread,
Jun 15, 2016, 9:07:04 PM6/15/16
to PDFTron WebViewer
Matt, i tried it i think you manage to deal with most issues perfectly - onwards and upwards!
however i'm preparing to you a separate post regarding rendering issues i found when editing modern form fields, done/ generated by acrobat pro / livecycle designer
such as mis-order of alignment and "comb" of X characters. will send it tomorrow
thanks!
Danny.

Danny Mendel

unread,
Jul 18, 2016, 12:51:59 PM7/18/16
to PDFTron WebViewer
hi Matt
how are you long time, hope you are fine
i think i found some bug with this or even latest WebViewer_2.2.0.46957 (not sure if this is the latest - but this is what i notice is latest release i notice on group)

so the bug is with behavior of
annotManager.importAnnotCommand(this.sync.syncmap[2].Value)

i prepare a quick screen record of the bughere ->


the first time remote peer is calling importAnnotCommand()
it handled the command xfdf file of what the host generated via
var command = annotManager.getAnnotCommand();

now
debugging the first time a doc is loaded reveal that the command file looks strange like this

"<?xml version="1.0" encoding="UTF-8" ?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<fields>
<field name="FamilyStatusOwner">
<value>Married</value>
</field>
</fields>
<add>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
<widget/>
</add>
<modify />
<delete />
</xfdf>"

this command input result in importAnnotCommand fire exception
fm.min.js:9 Uncaught TypeError: Cannot read property 'ed' of undefined

mf @ CoreControls.js:formatted:17261mf @ CoreControls.js:formatted:28968Qg @ CoreControls.js:formatted:26008Cx @ CoreControls.js:formatted:26051Eq @ CoreControls.js:formatted:25999Kt @ CoreControls.js:formatted:25978Kt @ CoreControls.js:formatted:24889App.actionSync @ app.js:667(anonymous function) @ (index):535(anonymous function) @ app.js:246onReceive @ signalling.js:116fm.websync.client.s.raiseActionManual @ fm.websync.min.js:formatted:8826(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.raiseSubscribeDelivery @ fm.websync.min.js:formatted:9421(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.receiveMessage @ fm.websync.min.js:formatted:9622(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.streamCallback @ fm.websync.min.js:formatted:10192(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.sendCallback @ fm.websync.min.js:formatted:9984(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.messageTransfer.s.sendAsyncCallback @ fm.websync.min.js:formatted:5645(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.webSocketMessageTransfer.s.sendMessagesAsyncCallback @ fm.websync.min.js:formatted:12876(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.webSocketWebRequestTransfer.e.receive @ fm.min.js:12(anonymous function) @ fm.min.js:12fm.webSocket.e.raiseReceive @ fm.min.js:12(anonymous function) @ fm.min.js:12fm.webSocket.e._onMessage @ fm.min.js:12(anonymous function) @ fm.min.js:12setTimeout (async)fm.asyncException.t.asyncThrow @ fm.min.js:9fm.websync.client.s.raiseActionManual @ fm.websync.min.js:formatted:8831(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.raiseSubscribeDelivery @ fm.websync.min.js:formatted:9421(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.receiveMessage @ fm.websync.min.js:formatted:9622(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.streamCallback @ fm.websync.min.js:formatted:10192(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.client.s.sendCallback @ fm.websync.min.js:formatted:9984(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.messageTransfer.s.sendAsyncCallback @ fm.websync.min.js:formatted:5645(anonymous function) @ fm.websync.min.js:formatted:13063fm.websync.webSocketMessageTransfer.s.sendMessagesAsyncCallback @ fm.websync.min.js:formatted:12876(anonymous function) @ fm.websync.min.js:formatted:13063(anonymous function) @ fm.websync.min.js:formatted:13063fm.webSocketWebRequestTransfer.e.receive @ fm.min.js:12(anonymous function) @ fm.min.js:12fm.webSocket.e.raiseReceive @ fm.min.js:12(anonymous function) @ fm.min.js:12fm.webSocket.e._onMessage @ fm.min.js:12(anonymous function) @ fm.min.js:12

now next time i a command xfdf is generated we get normal xfdf input command
<?xml version="1.0" encoding="UTF-8" ?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<fields>
<field name="FamilyStatusOwner">
<value>Off</value>
</field>
</fields>
<add />
<modify />
<delete />
</xfdf>"

which work perfectly on mportAnnotCommand(**working input command xfdf*)

this error is quite annoying,

hope i help :)
Danny


On Monday, May 30, 2016 at 8:59:00 PM UTC+3, Danny Mendel wrote:

Matt Parizeau

unread,
Jul 20, 2016, 7:42:06 PM7/20/16
to PDFTron WebViewer
Hi Danny,

Thanks for the report! We were able to reproduce the issue and it should be fixed in this build http://www.pdftron.com/ID-zJWLuhTffd3c/WebViewer/WebViewer_2.2.0.47456.zip

Matt Parizeau
Software Developer
PDFTron Systems Inc.
Reply all
Reply to author
Forward
0 new messages