@@ -34,6 +34,7 @@ import { AnnotationStorage } from "./annotation_storage.js";
34
34
import { ColorConverters } from "../shared/scripting_utils.js" ;
35
35
36
36
const DEFAULT_TAB_INDEX = 1000 ;
37
+ const GetElementsByNameSet = new WeakSet ( ) ;
37
38
38
39
/**
39
40
* @typedef {Object } AnnotationElementParameters
@@ -50,6 +51,7 @@ const DEFAULT_TAB_INDEX = 1000;
50
51
* @property {Object } svgFactory
51
52
* @property {boolean } [enableScripting]
52
53
* @property {boolean } [hasJSActions]
54
+ * @property {Object } [fieldObjects]
53
55
* @property {Object } [mouseState]
54
56
*/
55
57
@@ -159,6 +161,7 @@ class AnnotationElement {
159
161
this . annotationStorage = parameters . annotationStorage ;
160
162
this . enableScripting = parameters . enableScripting ;
161
163
this . hasJSActions = parameters . hasJSActions ;
164
+ this . _fieldObjects = parameters . fieldObjects ;
162
165
this . _mouseState = parameters . mouseState ;
163
166
164
167
if ( isRenderable ) {
@@ -363,6 +366,43 @@ class AnnotationElement {
363
366
unreachable ( "Abstract method `AnnotationElement.render` called" ) ;
364
367
}
365
368
369
+ /**
370
+ * @private
371
+ * @returns {Array }
372
+ */
373
+ _getElementsByName ( name ) {
374
+ const fields = [ ] ;
375
+
376
+ if ( this . _fieldObjects ) {
377
+ const fieldObj = this . _fieldObjects [ name ] ;
378
+ if ( fieldObj ) {
379
+ for ( const { id, page } of fieldObj ) {
380
+ if ( page === - 1 ) {
381
+ continue ;
382
+ }
383
+ const domElement = document . getElementById ( id ) || null ;
384
+ if ( domElement && ! GetElementsByNameSet . has ( domElement ) ) {
385
+ warn ( `_getElementsByName - element not allowed: ${ id } ` ) ;
386
+ continue ;
387
+ }
388
+ fields . push ( { id, domElement } ) ;
389
+ }
390
+ }
391
+ return fields ;
392
+ }
393
+ // Fallback to a regular DOM lookup.
394
+ for ( const domElement of document . getElementsByName ( name ) ) {
395
+ if ( ! GetElementsByNameSet . has ( domElement ) ) {
396
+ continue ;
397
+ }
398
+ fields . push ( {
399
+ id : domElement . getAttribute ( "id" ) ,
400
+ domElement,
401
+ } ) ;
402
+ }
403
+ return fields ;
404
+ }
405
+
366
406
static get platform ( ) {
367
407
const platform = typeof navigator !== "undefined" ? navigator . platform : "" ;
368
408
@@ -683,13 +723,14 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
683
723
684
724
setPropertyOnSiblings ( base , key , value , keyInStorage ) {
685
725
const storage = this . annotationStorage ;
686
- for ( const element of document . getElementsByName ( base . name ) ) {
687
- if ( element ! == base ) {
688
- element [ key ] = value ;
689
- const data = Object . create ( null ) ;
690
- data [ keyInStorage ] = value ;
691
- storage . setValue ( element . getAttribute ( "id" ) , data ) ;
726
+ for ( const element of this . _getElementsByName ( base . name ) ) {
727
+ if ( element . domElement = == base ) {
728
+ continue ;
729
+ }
730
+ if ( element . domElement ) {
731
+ element . domElement [ key ] = value ;
692
732
}
733
+ storage . setValue ( element . id , { [ keyInStorage ] : value } ) ;
693
734
}
694
735
}
695
736
@@ -724,6 +765,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
724
765
element . type = "text" ;
725
766
element . setAttribute ( "value" , textContent ) ;
726
767
}
768
+ GetElementsByNameSet . add ( element ) ;
727
769
element . tabIndex = DEFAULT_TAB_INDEX ;
728
770
729
771
elementData . userValue = textContent ;
@@ -974,6 +1016,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
974
1016
this . container . className = "buttonWidgetAnnotation checkBox" ;
975
1017
976
1018
const element = document . createElement ( "input" ) ;
1019
+ GetElementsByNameSet . add ( element ) ;
977
1020
element . disabled = data . readOnly ;
978
1021
element . type = "checkbox" ;
979
1022
element . name = this . data . fieldName ;
@@ -983,16 +1026,15 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
983
1026
element . setAttribute ( "id" , id ) ;
984
1027
element . tabIndex = DEFAULT_TAB_INDEX ;
985
1028
986
- element . addEventListener ( "change" , function ( event ) {
987
- const name = event . target . name ;
988
- for ( const checkbox of document . getElementsByName ( name ) ) {
989
- if ( checkbox !== event . target ) {
990
- checkbox . checked = false ;
991
- storage . setValue (
992
- checkbox . parentNode . getAttribute ( "data-annotation-id" ) ,
993
- { value : false }
994
- ) ;
1029
+ element . addEventListener ( "change" , event => {
1030
+ for ( const checkbox of this . _getElementsByName ( event . target . name ) ) {
1031
+ if ( checkbox . domElement === event . target ) {
1032
+ continue ;
995
1033
}
1034
+ if ( checkbox . domElement ) {
1035
+ checkbox . domElement . checked = false ;
1036
+ }
1037
+ storage . setValue ( checkbox . id , { value : false } ) ;
996
1038
}
997
1039
storage . setValue ( id , { value : event . target . checked } ) ;
998
1040
} ) ;
@@ -1049,6 +1091,7 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
1049
1091
}
1050
1092
1051
1093
const element = document . createElement ( "input" ) ;
1094
+ GetElementsByNameSet . add ( element ) ;
1052
1095
element . disabled = data . readOnly ;
1053
1096
element . type = "radio" ;
1054
1097
element . name = data . fieldName ;
@@ -1058,26 +1101,30 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
1058
1101
element . setAttribute ( "id" , id ) ;
1059
1102
element . tabIndex = DEFAULT_TAB_INDEX ;
1060
1103
1061
- element . addEventListener ( "change" , function ( event ) {
1104
+ element . addEventListener ( "change" , event => {
1062
1105
const { target } = event ;
1063
- for ( const radio of document . getElementsByName ( target . name ) ) {
1064
- if ( radio ! == target ) {
1065
- storage . setValue ( radio . getAttribute ( "id" ) , { value : false } ) ;
1106
+ for ( const radio of this . _getElementsByName ( target . name ) ) {
1107
+ if ( radio . domElement = == target ) {
1108
+ continue ;
1066
1109
}
1110
+ storage . setValue ( radio . id , { value : false } ) ;
1067
1111
}
1068
1112
storage . setValue ( id , { value : target . checked } ) ;
1069
1113
} ) ;
1070
1114
1071
1115
if ( this . enableScripting && this . hasJSActions ) {
1072
1116
const pdfButtonValue = data . buttonValue ;
1117
+ const self = this ;
1073
1118
element . addEventListener ( "updatefromsandbox" , jsEvent => {
1074
1119
const actions = {
1075
1120
value ( event ) {
1076
1121
const checked = pdfButtonValue === event . detail . value ;
1077
- for ( const radio of document . getElementsByName ( event . target . name ) ) {
1078
- const radioId = radio . getAttribute ( "id" ) ;
1079
- radio . checked = radioId === id && checked ;
1080
- storage . setValue ( radioId , { value : radio . checked } ) ;
1122
+ for ( const radio of self . _getElementsByName ( event . target . name ) ) {
1123
+ const curChecked = radio . id === id && checked ;
1124
+ if ( radio . domElement ) {
1125
+ radio . domElement . checked = curChecked ;
1126
+ }
1127
+ storage . setValue ( radio . id , { value : curChecked } ) ;
1081
1128
}
1082
1129
} ,
1083
1130
} ;
@@ -1150,6 +1197,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
1150
1197
const fontSizeStyle = `calc(${ fontSize } px * var(--zoom-factor))` ;
1151
1198
1152
1199
const selectElement = document . createElement ( "select" ) ;
1200
+ GetElementsByNameSet . add ( selectElement ) ;
1153
1201
selectElement . disabled = this . data . readOnly ;
1154
1202
selectElement . name = this . data . fieldName ;
1155
1203
selectElement . setAttribute ( "id" , id ) ;
@@ -2082,6 +2130,7 @@ class AnnotationLayer {
2082
2130
parameters . annotationStorage || new AnnotationStorage ( ) ,
2083
2131
enableScripting : parameters . enableScripting ,
2084
2132
hasJSActions : parameters . hasJSActions ,
2133
+ fieldObjects : parameters . fieldObjects ,
2085
2134
mouseState : parameters . mouseState || { isDown : false } ,
2086
2135
} ) ;
2087
2136
if ( element . isRenderable ) {
0 commit comments