@@ -573,34 +573,34 @@ static function ( $validation_error ) {
573573 }
574574 }
575575
576+ $ attr_spec_list = array_merge (
577+ $ this ->globally_allowed_attributes ,
578+ $ attr_spec_list
579+ );
580+
576581 // Remove element if it has illegal CDATA.
577582 if ( ! empty ( $ cdata ) && $ node instanceof DOMElement ) {
578583 $ validity = $ this ->validate_cdata_for_node ( $ node , $ cdata );
579584 if ( true !== $ validity ) {
580- $ this ->remove_invalid_child (
585+ $ sanitized = $ this ->remove_invalid_child (
581586 $ node ,
582587 array_merge (
583588 $ validity ,
584589 [ 'spec_name ' => $ this ->get_spec_name ( $ node , $ tag_spec ) ]
585590 )
586591 );
587- return null ;
592+ return $ sanitized ? null : $ this -> get_required_script_components ( $ node , $ tag_spec , $ attr_spec_list ) ;
588593 }
589594 }
590595
591- $ merged_attr_spec_list = array_merge (
592- $ this ->globally_allowed_attributes ,
593- $ attr_spec_list
594- );
595-
596596 // Amend spec list with layout.
597597 if ( isset ( $ tag_spec ['amp_layout ' ] ) ) {
598- $ merged_attr_spec_list = array_merge ( $ merged_attr_spec_list , $ this ->layout_allowed_attributes );
598+ $ attr_spec_list = array_merge ( $ attr_spec_list , $ this ->layout_allowed_attributes );
599599
600600 if ( isset ( $ tag_spec ['amp_layout ' ]['supported_layouts ' ] ) ) {
601601 $ layouts = wp_array_slice_assoc ( Layout::FROM_SPEC , $ tag_spec ['amp_layout ' ]['supported_layouts ' ] );
602602
603- $ merged_attr_spec_list ['layout ' ][ AMP_Rule_Spec::VALUE_REGEX_CASEI ] = '( ' . implode ( '| ' , $ layouts ) . ') ' ;
603+ $ attr_spec_list ['layout ' ][ AMP_Rule_Spec::VALUE_REGEX_CASEI ] = '( ' . implode ( '| ' , $ layouts ) . ') ' ;
604604 }
605605 }
606606
@@ -626,12 +626,12 @@ static function ( $validation_error ) {
626626 // Remove the element if it is has an invalid layout.
627627 $ layout_validity = $ this ->is_valid_layout ( $ tag_spec , $ node );
628628 if ( true !== $ layout_validity ) {
629- $ this ->remove_invalid_child ( $ node , $ layout_validity );
630- return null ;
629+ $ sanitized = $ this ->remove_invalid_child ( $ node , $ layout_validity );
630+ return $ sanitized ? null : $ this -> get_required_script_components ( $ node , $ tag_spec , $ attr_spec_list ) ;
631631 }
632632
633633 // Identify attribute values that don't conform to the attr_spec.
634- $ disallowed_attributes = $ this ->sanitize_disallowed_attribute_values_in_node ( $ node , $ merged_attr_spec_list );
634+ $ disallowed_attributes = $ this ->sanitize_disallowed_attribute_values_in_node ( $ node , $ attr_spec_list );
635635
636636 // Remove all invalid attributes.
637637 if ( ! empty ( $ disallowed_attributes ) ) {
@@ -679,7 +679,7 @@ static function ( $validation_error ) {
679679
680680 if ( $ this ->should_sanitize_validation_error ( $ validation_error , [ 'node ' => $ attr_node ] ) ) {
681681 $ properties = $ this ->parse_properties_attribute ( $ attr_node ->nodeValue );
682- if ( ! empty ( $ merged_attr_spec_list [ $ attr_node ->nodeName ]['value_properties ' ][ $ error_data ['name ' ] ]['mandatory ' ] ) ) {
682+ if ( ! empty ( $ attr_spec_list [ $ attr_node ->nodeName ]['value_properties ' ][ $ error_data ['name ' ] ]['mandatory ' ] ) ) {
683683 $ properties [ $ error_data ['name ' ] ] = $ error_data ['required_value ' ];
684684 } else {
685685 unset( $ properties [ $ error_data ['name ' ] ] );
@@ -697,7 +697,7 @@ static function ( $validation_error ) {
697697 $ node ->setAttribute ( $ attr_node ->nodeName , $ this ->serialize_properties_attribute ( $ properties ) );
698698 }
699699 } else {
700- $ attr_spec = isset ( $ merged_attr_spec_list [ $ attr_node ->nodeName ] ) ? $ merged_attr_spec_list [ $ attr_node ->nodeName ] : [];
700+ $ attr_spec = isset ( $ attr_spec_list [ $ attr_node ->nodeName ] ) ? $ attr_spec_list [ $ attr_node ->nodeName ] : [];
701701 if ( $ this ->remove_invalid_attribute ( $ node , $ attr_node , $ validation_error , $ attr_spec ) ) {
702702 $ removed_attributes [] = $ attr_node ;
703703 }
@@ -726,71 +726,82 @@ static function ( $validation_error ) {
726726 }
727727
728728 // After attributes have been sanitized (and potentially removed), if mandatory attribute(s) are missing, remove the element.
729- $ missing_mandatory_attributes = $ this ->get_missing_mandatory_attributes ( $ merged_attr_spec_list , $ node );
729+ $ missing_mandatory_attributes = $ this ->get_missing_mandatory_attributes ( $ attr_spec_list , $ node );
730730 if ( ! empty ( $ missing_mandatory_attributes ) ) {
731- $ this ->remove_invalid_child (
731+ $ sanitized = $ this ->remove_invalid_child (
732732 $ node ,
733733 [
734734 'code ' => self ::ATTR_REQUIRED_BUT_MISSING ,
735735 'attributes ' => $ missing_mandatory_attributes ,
736736 'spec_name ' => $ this ->get_spec_name ( $ node , $ tag_spec ),
737737 ]
738738 );
739- return null ;
739+ return $ sanitized ? null : $ this -> get_required_script_components ( $ node , $ tag_spec , $ attr_spec_list ) ;
740740 }
741741
742742 if ( ! empty ( $ tag_spec [ AMP_Rule_Spec::MANDATORY_ANYOF ] ) ) {
743743 $ anyof_attributes = $ this ->get_element_attribute_intersection ( $ node , $ tag_spec [ AMP_Rule_Spec::MANDATORY_ANYOF ] );
744744 if ( 0 === count ( $ anyof_attributes ) ) {
745- $ this ->remove_invalid_child (
745+ $ sanitized = $ this ->remove_invalid_child (
746746 $ node ,
747747 [
748748 'code ' => self ::MANDATORY_ANYOF_ATTR_MISSING ,
749749 'mandatory_anyof_attrs ' => $ tag_spec [ AMP_Rule_Spec::MANDATORY_ANYOF ], // @todo Temporary as value can be looked up via spec name. See https://github.com/ampproject/amp-wp/pull/3817.
750750 'spec_name ' => $ this ->get_spec_name ( $ node , $ tag_spec ),
751751 ]
752752 );
753- return null ;
753+ return $ sanitized ? null : $ this -> get_required_script_components ( $ node , $ tag_spec , $ attr_spec_list ) ;
754754 }
755755 }
756756
757757 if ( ! empty ( $ tag_spec [ AMP_Rule_Spec::MANDATORY_ONEOF ] ) ) {
758758 $ oneof_attributes = $ this ->get_element_attribute_intersection ( $ node , $ tag_spec [ AMP_Rule_Spec::MANDATORY_ONEOF ] );
759759 if ( 0 === count ( $ oneof_attributes ) ) {
760- $ this ->remove_invalid_child (
760+ $ sanitized = $ this ->remove_invalid_child (
761761 $ node ,
762762 [
763763 'code ' => self ::MANDATORY_ONEOF_ATTR_MISSING ,
764764 'mandatory_oneof_attrs ' => $ tag_spec [ AMP_Rule_Spec::MANDATORY_ONEOF ], // @todo Temporary as value can be looked up via spec name. See https://github.com/ampproject/amp-wp/pull/3817.
765765 'spec_name ' => $ this ->get_spec_name ( $ node , $ tag_spec ),
766766 ]
767767 );
768- return null ;
768+ return $ sanitized ? null : $ this -> get_required_script_components ( $ node , $ tag_spec , $ attr_spec_list ) ;
769769 } elseif ( count ( $ oneof_attributes ) > 1 ) {
770- $ this ->remove_invalid_child (
770+ $ sanitized = $ this ->remove_invalid_child (
771771 $ node ,
772772 [
773773 'code ' => self ::DUPLICATE_ONEOF_ATTRS ,
774774 'duplicate_oneof_attrs ' => $ oneof_attributes ,
775775 'spec_name ' => $ this ->get_spec_name ( $ node , $ tag_spec ),
776776 ]
777777 );
778- return null ;
778+ return $ sanitized ? null : $ this -> get_required_script_components ( $ node , $ tag_spec , $ attr_spec_list ) ;
779779 }
780780 }
781781
782- // Add required AMP component scripts.
782+ return $ this ->get_required_script_components ( $ node , $ tag_spec , $ attr_spec_list );
783+ }
784+
785+ /**
786+ * Get required AMP component scripts.
787+ *
788+ * @param DOMElement $node Element.
789+ * @param array $tag_spec Tag spec.
790+ * @param array $attr_spec_list Attribute spec list.
791+ * @return string[] Script component handles.
792+ */
793+ private function get_required_script_components ( DOMElement $ node , $ tag_spec , $ attr_spec_list ) {
783794 $ script_components = [];
784795 if ( ! empty ( $ tag_spec ['requires_extension ' ] ) ) {
785796 $ script_components = array_merge ( $ script_components , $ tag_spec ['requires_extension ' ] );
786797 }
787798
788799 // Add required AMP components for attributes.
789800 foreach ( $ node ->attributes as $ attribute ) {
790- if ( isset ( $ merged_attr_spec_list [ $ attribute ->nodeName ]['requires_extension ' ] ) ) {
801+ if ( isset ( $ attr_spec_list [ $ attribute ->nodeName ]['requires_extension ' ] ) ) {
791802 $ script_components = array_merge (
792803 $ script_components ,
793- $ merged_attr_spec_list [ $ attribute ->nodeName ]['requires_extension ' ]
804+ $ attr_spec_list [ $ attribute ->nodeName ]['requires_extension ' ]
794805 );
795806 }
796807 }
@@ -809,7 +820,6 @@ static function ( $validation_error ) {
809820 }
810821 }
811822 }
812-
813823 return $ script_components ;
814824 }
815825
0 commit comments