@@ -16,8 +16,8 @@ var codeInput = {
1616 */
1717 observedAttributes : [
1818 "value" ,
19- "placeholder" ,
20- "lang" ,
19+ "placeholder" ,
20+ "lang" ,
2121 "template"
2222 ] ,
2323
@@ -37,6 +37,18 @@ var codeInput = {
3737 "pattern"
3838 ] ,
3939
40+ /**
41+ * A list of events whose listeners will be moved to
42+ * the textarea after they are added to the
43+ * code-input element.
44+ */
45+ textareaSyncEvents : [
46+ "change" ,
47+ "selectionchange" ,
48+ "invalid" ,
49+ "input"
50+ ] ,
51+
4052 /* ------------------------------------
4153 * ------------Templates---------------
4254 * ------------------------------------ */
@@ -364,7 +376,7 @@ var codeInput = {
364376
365377 this . pluginEvt ( "afterHighlight" ) ;
366378 }
367-
379+
368380 /**
369381 * Synchronise the scrolling of the textarea to the result element.
370382 */
@@ -408,7 +420,7 @@ var codeInput = {
408420 return undefined ;
409421 }
410422 }
411-
423+
412424 /**
413425 * Set up and initialise the textarea.
414426 * This will be called once the template has been added.
@@ -434,14 +446,14 @@ var codeInput = {
434446
435447 // Synchronise attributes to textarea
436448 codeInput . textareaSyncAttributes . forEach ( ( attribute ) => {
437- if ( this . hasAttribute ( attribute ) ) {
449+ if ( this . hasAttribute ( attribute ) ) {
438450 textarea . setAttribute ( attribute , this . getAttribute ( attribute ) ) ;
439451 }
440452 } ) ;
441-
442- textarea . addEventListener ( 'input' , ( evt ) => { textarea . parentElement . update ( textarea . value ) ; textarea . parentElement . sync_scroll ( ) ; } ) ;
443- textarea . addEventListener ( 'scroll' , ( evt ) => textarea . parentElement . sync_scroll ( ) ) ;
444-
453+
454+ textarea . addEventListener ( 'input' , ( evt ) => { textarea . parentElement . update ( textarea . value ) ; textarea . parentElement . sync_scroll ( ) ; } ) ;
455+ textarea . addEventListener ( 'scroll' , ( evt ) => textarea . parentElement . sync_scroll ( ) ) ;
456+
445457 this . append ( textarea ) ;
446458
447459 // Create result element
@@ -504,7 +516,7 @@ var codeInput = {
504516 * to `codeInput.CodeInput.attributeChangedCallback` when modified.
505517 */
506518 static get observedAttributes ( ) {
507- return codeInput . observedAttributes . concat ( codeInput . textareaSyncAttributes ) ;
519+ return codeInput . observedAttributes . concat ( codeInput . textareaSyncAttributes ) ;
508520 }
509521
510522 /**
@@ -568,47 +580,40 @@ var codeInput = {
568580
569581 break ;
570582 default :
571- if ( codeInput . textareaSyncAttributes . includes ( name ) ) {
583+ if ( codeInput . textareaSyncAttributes . includes ( name ) ) {
572584 this . querySelector ( "textarea" ) . setAttribute ( name , newValue ) ;
573585 }
574586 break ;
575587 }
576588 }
577589
578590 }
579-
591+
592+ /* ------------------------------------
593+ * -----------Overrides----------------
594+ * ------------------------------------
595+ * Override/Implement ordinary HTML textarea functionality so that the <code-input>
596+ * element acts just like a <textarea>. */
597+
580598 /**
581599 * @override
582600 */
583601 addEventListener ( type , listener , options = undefined ) {
584602 let boundCallback = listener . bind ( this ) ;
585603 this . boundEventCallbacks [ listener ] = boundCallback ;
586- if ( type == "change" ) {
604+
605+ if ( codeInput . textareaSyncEvents . includes ( type ) ) {
587606 if ( options === undefined ) {
588- this . querySelector ( "textarea" ) . addEventListener ( "change" , boundCallback ) ;
607+ this . querySelector ( "textarea" ) . addEventListener ( type , boundCallback ) ;
589608 } else {
590- this . querySelector ( "textarea" ) . addEventListener ( "change" , boundCallback , options ) ;
609+ this . querySelector ( "textarea" ) . addEventListener ( type , boundCallback , options ) ;
591610 }
592- } else if ( type == "selectionchange" ) {
611+ } else {
593612 if ( options === undefined ) {
594- this . querySelector ( "textarea" ) . addEventListener ( "selectionchange" , boundCallback ) ;
613+ super . addEventListener ( type , boundCallback ) ;
595614 } else {
596- this . querySelector ( "textarea" ) . addEventListener ( "selectionchange" , boundCallback , options ) ;
615+ super . addEventListener ( type , boundCallback , options ) ;
597616 }
598- } else if ( evt_name == "invalid" ) {
599- if ( thirdParameter === null ) {
600- this . querySelector ( "textarea" ) . addEventListener ( "invalid" , boundCallback ) ;
601- } else {
602- this . querySelector ( "textarea" ) . addEventListener ( "invalid" , boundCallback , thirdParameter ) ;
603- }
604- } else if ( evt_name == "input" ) {
605- if ( thirdParameter === null ) {
606- this . querySelector ( "textarea" ) . addEventListener ( "input" , boundCallback ) ;
607- } else {
608- this . querySelector ( "textarea" ) . addEventListener ( "input" , boundCallback , thirdParameter ) ;
609- }
610- } else {
611- super . addEventListener ( type , listener , options ) ;
612617 }
613618 }
614619
@@ -647,7 +652,7 @@ var codeInput = {
647652 set value ( val ) {
648653 return this . setAttribute ( "value" , val ) ;
649654 }
650-
655+
651656 /**
652657 * Get the placeholder of the code-input element that appears
653658 * when no code has been entered.
@@ -664,40 +669,73 @@ var codeInput = {
664669 return this . setAttribute ( "placeholder" , val ) ;
665670 }
666671
667- /* Form validation */
672+ /**
673+ * Returns a ValidityState object that represents the validity states of an element.
674+ *
675+ * See `HTMLTextAreaElement.validity`
676+ */
668677 get validity ( ) {
669678 return this . querySelector ( "textarea" ) . validity ;
670679 }
680+
681+ /**
682+ * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message.
683+ * It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation
684+ * messages without actually submitting.
685+ *
686+ * See `HTMLTextAreaElement.validationMessage`
687+ */
671688 get validationMessage ( ) {
672689 return this . querySelector ( "textarea" ) . validationMessage ;
673690 }
691+
692+ /**
693+ * Sets a custom error message that is displayed when a form is submitted.
694+ *
695+ * See `HTMLTextAreaElement.setCustomValidity`
696+ * @param error Sets a custom error message that is displayed when a form is submitted.
697+ */
674698 setCustomValidity ( error ) {
675699 return this . querySelector ( "textarea" ) . setCustomValidity ( error ) ;
676700 }
701+
702+ /**
703+ * Returns whether a form will validate when it is submitted,
704+ * without having to submit it.
705+ *
706+ * See `HTMLTextAreaElement.checkValidity`
707+ */
677708 checkValidity ( ) {
678709 return this . querySelector ( "textarea" ) . checkValidity ( ) ;
679710 }
711+
712+ /**
713+ * See `HTMLTextAreaElement.reportValidity`
714+ */
680715 reportValidity ( ) {
681716 return this . querySelector ( "textarea" ) . reportValidity ( ) ;
682717 }
683718
684719
685- /* Sync all attributes that can be set on the `code-input` element to the `textarea` element */
720+ /**
721+ * @override
722+ */
686723 setAttribute ( qualifiedName , value ) {
687724 super . setAttribute ( qualifiedName , value ) ; // code-input
688725 this . querySelector ( "textarea" ) . setAttribute ( qualifiedName , value ) ; // textarea
689726 }
690727
728+ /**
729+ * @override
730+ */
691731 getAttribute ( qualifiedName ) {
692- if ( this . querySelector ( "textarea" ) == null ) {
732+ if ( this . querySelector ( "textarea" ) == null ) {
693733 return super . getAttribute ( qualifiedName ) ;
694734 }
695735 return this . querySelector ( "textarea" ) . getAttribute ( qualifiedName ) ; // textarea
696736 }
697737
698- pluginData = { } ; // For plugins to store element-specific data under their name, e.g. <code-input>.pluginData.specialChars
699-
700- /**
738+ /**
701739 * Allows plugins to store data in the scope of a single element.
702740 * Key - name of the plugin
703741 * Value - object of data to be stored; different plugins may use this differently.
0 commit comments