@@ -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,29 @@ 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
+ storage . setValue ( radio . id , { value : false } ) ;
1066
1109
}
1067
1110
}
1068
1111
storage . setValue ( id , { value : target . checked } ) ;
1069
1112
} ) ;
1070
1113
1071
1114
if ( this . enableScripting && this . hasJSActions ) {
1072
1115
const pdfButtonValue = data . buttonValue ;
1116
+ const self = this ;
1073
1117
element . addEventListener ( "updatefromsandbox" , jsEvent => {
1074
1118
const actions = {
1075
1119
value ( event ) {
1076
1120
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 } ) ;
1121
+ for ( const radio of self . _getElementsByName ( event . target . name ) ) {
1122
+ const curChecked = radio . id === id && checked ;
1123
+ if ( radio . domElement ) {
1124
+ radio . domElement . checked = curChecked ;
1125
+ }
1126
+ storage . setValue ( radio . id , { value : curChecked } ) ;
1081
1127
}
1082
1128
} ,
1083
1129
} ;
@@ -1150,6 +1196,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
1150
1196
const fontSizeStyle = `calc(${ fontSize } px * var(--zoom-factor))` ;
1151
1197
1152
1198
const selectElement = document . createElement ( "select" ) ;
1199
+ GetElementsByNameSet . add ( selectElement ) ;
1153
1200
selectElement . disabled = this . data . readOnly ;
1154
1201
selectElement . name = this . data . fieldName ;
1155
1202
selectElement . setAttribute ( "id" , id ) ;
@@ -2082,6 +2129,7 @@ class AnnotationLayer {
2082
2129
parameters . annotationStorage || new AnnotationStorage ( ) ,
2083
2130
enableScripting : parameters . enableScripting ,
2084
2131
hasJSActions : parameters . hasJSActions ,
2132
+ fieldObjects : parameters . fieldObjects ,
2085
2133
mouseState : parameters . mouseState || { isDown : false } ,
2086
2134
} ) ;
2087
2135
if ( element . isRenderable ) {
0 commit comments