@@ -45,6 +45,7 @@ import { XfaLayer } from "./xfa_layer.js";
4545
4646const DEFAULT_FONT_SIZE = 9 ;
4747const GetElementsByNameSet = new WeakSet ( ) ;
48+ const TIMEZONE_OFFSET = new Date ( ) . getTimezoneOffset ( ) * 60 * 1000 ;
4849
4950/**
5051 * @typedef {Object } AnnotationElementParameters
@@ -1354,9 +1355,10 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
13541355 element . disabled = this . data . readOnly ;
13551356 element . name = this . data . fieldName ;
13561357 element . tabIndex = 0 ;
1357- const format = this . data . dateFormat || this . data . timeFormat ;
1358- if ( format ) {
1359- element . title = format ;
1358+ const { datetimeFormat, datetimeType, timeStep } = this . data ;
1359+ const hasDateOrTime = ! ! datetimeType && this . enableScripting ;
1360+ if ( datetimeFormat ) {
1361+ element . title = datetimeFormat ;
13601362 }
13611363
13621364 this . _setRequired ( element , this . data . required ) ;
@@ -1397,8 +1399,34 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
13971399 return ;
13981400 }
13991401 const { target } = event ;
1402+ if ( hasDateOrTime ) {
1403+ target . type = datetimeType ;
1404+ if ( timeStep ) {
1405+ target . step = timeStep ;
1406+ }
1407+ }
1408+
14001409 if ( elementData . userValue ) {
1401- target . value = elementData . userValue ;
1410+ const value = elementData . userValue ;
1411+ if ( hasDateOrTime ) {
1412+ if ( datetimeType === "time" ) {
1413+ const date = new Date ( value ) ;
1414+ const parts = [
1415+ date . getHours ( ) ,
1416+ date . getMinutes ( ) ,
1417+ date . getSeconds ( ) ,
1418+ ] ;
1419+ target . value = parts
1420+ . map ( v => v . toString ( ) . padStart ( 2 , "0" ) )
1421+ . join ( ":" ) ;
1422+ } else {
1423+ target . value = new Date ( value - TIMEZONE_OFFSET )
1424+ . toISOString ( )
1425+ . split ( datetimeType === "date" ? "T" : "." , 1 ) [ 0 ] ;
1426+ }
1427+ } else {
1428+ target . value = value ;
1429+ }
14021430 }
14031431 elementData . lastCommittedValue = target . value ;
14041432 elementData . commitKey = 1 ;
@@ -1412,7 +1440,11 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
14121440 const actions = {
14131441 value ( event ) {
14141442 elementData . userValue = event . detail . value ?? "" ;
1415- storage . setValue ( id , { value : elementData . userValue . toString ( ) } ) ;
1443+ if ( ! hasDateOrTime ) {
1444+ storage . setValue ( id , {
1445+ value : elementData . userValue . toString ( ) ,
1446+ } ) ;
1447+ }
14161448 event . target . value = elementData . userValue ;
14171449 } ,
14181450 formattedValue ( event ) {
@@ -1426,9 +1458,16 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
14261458 // Input hasn't the focus so display formatted string
14271459 event . target . value = formattedValue ;
14281460 }
1429- storage . setValue ( id , {
1461+ const data = {
14301462 formattedValue,
1431- } ) ;
1463+ } ;
1464+ if ( hasDateOrTime ) {
1465+ // If the field is a date or time, we store the formatted value
1466+ // in the `value` property, so that it can be used by the
1467+ // `Keystroke` action.
1468+ data . value = formattedValue ;
1469+ }
1470+ storage . setValue ( id , data ) ;
14321471 } ,
14331472 selRange ( event ) {
14341473 event . target . setSelectionRange ( ...event . detail . selRange ) ;
@@ -1516,7 +1555,25 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
15161555 if ( ! this . data . actions ?. Blur ) {
15171556 elementData . focused = false ;
15181557 }
1519- const { value } = event . target ;
1558+ const { target } = event ;
1559+ let { value } = target ;
1560+ if ( hasDateOrTime ) {
1561+ if ( value && datetimeType === "time" ) {
1562+ const parts = value . split ( ":" ) . map ( v => parseInt ( v , 10 ) ) ;
1563+ value = new Date (
1564+ 2000 ,
1565+ 0 ,
1566+ 1 ,
1567+ parts [ 0 ] ,
1568+ parts [ 1 ] ,
1569+ parts [ 2 ] || 0
1570+ ) . valueOf ( ) ;
1571+ target . step = "" ;
1572+ } else {
1573+ value = new Date ( value ) . valueOf ( ) ;
1574+ }
1575+ target . type = "text" ;
1576+ }
15201577 elementData . userValue = value ;
15211578 if ( elementData . lastCommittedValue !== value ) {
15221579 this . linkService . eventBus ?. dispatch ( "dispatcheventinsandbox" , {
0 commit comments