@@ -27,8 +27,9 @@ public function render(): string
2727 {
2828 $ field = $ this ->arguments ['field ' ];
2929
30- [$ autocompleteTokens , $ token , $ section , $ type , $ purpose ]
30+ [$ fieldType , $ autocompleteTokens , $ token , $ section , $ type , $ purpose ]
3131 = [
32+ $ field ->getType (),
3233 '' ,
3334 $ field ->getAutocompleteToken (),
3435 trim ($ field ->getAutocompleteSection ()),
@@ -41,6 +42,10 @@ public function render(): string
4142 return $ token ;
4243 }
4344
45+ if (!$ this ->tokenIsAllowedForFieldType ($ token , $ fieldType )) {
46+ return '' ;
47+ }
48+
4449 // Optional section token must begin with the string 'section-'
4550 if (!empty ($ section )) {
4651 if ($ this ->tokenIsAllowedForSection ($ token )) {
@@ -57,7 +62,7 @@ public function render(): string
5762
5863 // Optional purpose token is only allowed for certain autofill-field tokens
5964 if (!empty ($ purpose )) {
60- if ($ this ->tokenIsAllowedForPurpose ($ token , $ purpose )) {
65+ if ($ this ->tokenIsAllowedForPurpose ($ token , $ purpose, $ fieldType )) {
6166 $ autocompleteTokens .= $ purpose . ' ' ;
6267 }
6368 }
@@ -67,6 +72,11 @@ public function render(): string
6772
6873
6974 /**
75+ * Checks if the given type token is allowed for the specified autocomplete field token.
76+ *
77+ * Based on WHATWG HTML Spec:
78+ * https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
79+ *
7080 * @param string $token
7181 * @param string $type
7282 *
@@ -75,35 +85,95 @@ public function render(): string
7585 protected function tokenIsAllowedForType (string $ token , string $ type ): bool
7686 {
7787 $ allowedTypes = ['shipping ' , 'billing ' ];
78- $ tokensNotSupportingType = ['nickname ' , 'sex ' , 'impp ' , 'url ' , 'organization-title ' , 'tel-country-code ' , 'tel-area-code ' , 'tel-national ' , 'tel-local ' , 'tel-local-prefix ' , 'tel-local-suffix ' , 'tel-extension ' , 'username ' , 'new-password ' , 'current-password ' , 'one-time-code ' , 'bday ' , 'bday-day ' , 'bday-month ' , 'bday-year ' , 'language ' , 'photo ' ];
88+ $ tokensNotSupportingType = [
89+ 'nickname ' , 'sex ' , 'impp ' , 'url ' , 'organization-title ' ,
90+ 'tel-country-code ' , 'tel-area-code ' , 'tel-national ' , 'tel-local ' ,
91+ 'tel-local-prefix ' , 'tel-local-suffix ' , 'tel-extension ' ,
92+ 'username ' , 'new-password ' , 'current-password ' , 'one-time-code ' ,
93+ 'bday ' , 'bday-day ' , 'bday-month ' , 'bday-year ' , 'language ' , 'photo '
94+ ];
7995 return in_array ($ type , $ allowedTypes )
8096 && !in_array ($ token , $ tokensNotSupportingType );
8197 }
8298
83-
8499 /**
100+ * Checks if the given purpose token is allowed for the specified autocomplete field token.
101+ *
102+ * Based on WHATWG HTML Spec:
103+ * https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
104+ *
85105 * @param string $token
86106 * @param string $purpose
107+ * @param string $fieldType
87108 *
88109 * @return bool
89110 */
90- protected function tokenIsAllowedForPurpose (string $ token , string $ purpose ): bool
111+ protected function tokenIsAllowedForPurpose (string $ token , string $ purpose, string $ fieldType ): bool
91112 {
92113 $ allowedPurposes = ['home ' , 'work ' , 'mobile ' , 'fax ' , 'pager ' ];
93114 $ tokensSupportingPurpose = ['tel ' , 'email ' , 'impp ' ];
115+ $ purposeAllowedForFields = ['input ' , 'textarea ' , 'hidden ' ];
94116
95- return in_array ($ token , $ allowedPurposes , true )
96- && !in_array ($ token , $ tokensSupportingPurpose , true );
117+ return in_array ($ fieldType , $ purposeAllowedForFields )
118+ && in_array ($ purpose , $ allowedPurposes , true )
119+ && in_array ($ token , $ tokensSupportingPurpose , true );
97120 }
98121
99122 /**
123+ * Checks if the given autocomplete field token allows a section token prefix.
124+ *
125+ * Based on WHATWG HTML Spec:
126+ * https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
127+ *
100128 * @param string $token
101129 *
102130 * @return bool
103131 */
104132 protected function tokenIsAllowedForSection (string $ token ): bool
105133 {
106- $ tokensNotSupportingSection = ['nickname ' , 'sex ' , 'impp ' , 'url ' , 'organization-title ' , 'username ' , 'new-password ' , 'current-password ' , 'one-time-code ' , 'bday ' , 'bday-day ' , 'bday-month ' , 'bday-year ' , 'language ' , 'photo ' ];
134+ $ tokensNotSupportingSection = [
135+ 'nickname ' , 'sex ' , 'impp ' , 'url ' , 'organization-title ' ,
136+ 'username ' , 'new-password ' , 'current-password ' , 'one-time-code ' ,
137+ 'bday ' , 'bday-day ' , 'bday-month ' , 'bday-year ' , 'language ' , 'photo '
138+ ];
107139 return !in_array ($ token , $ tokensNotSupportingSection , true );
108140 }
141+
142+ /**
143+ * Checks if the given autocomplete field token is allowed for the current field type.
144+ *
145+ * Based on WHATWG HTML Spec:
146+ * https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
147+ *
148+ * @param string $token
149+ * @param string $fieldType
150+ *
151+ * @return bool
152+ */
153+ protected function tokenIsAllowedForFieldType (string $ token , string $ fieldType ): bool
154+ {
155+ $ allowedForAllTypes = ['on ' , 'off ' ];
156+ $ allowedForSelect = ['country ' , 'country-name ' , 'language ' , 'sex ' , 'bday ' , 'bday-day ' , 'bday-month ' , 'bday-year ' , 'title ' , 'address-level1 ' , 'address-level2 ' , 'cc-exp-month ' , 'cc-exp-year ' ];
157+ $ allowedForLocation = ['country ' , 'country-name ' , 'street-address ' , 'postal-code ' , 'address-line1 ' , 'address-line2 ' , 'address-line3 ' , 'address-level1 ' , 'address-level2 ' , 'address-level3 ' , 'address-level4 ' ];
158+ $ allowedForCountry = ['country ' , 'country-name ' ];
159+ $ allowedForHidden = ['name ' , 'honorific-prefix ' , 'given-name ' , 'additional-name ' , 'family-name ' , 'honorific-suffix ' , 'email ' , 'username ' , 'organization ' , 'organization-title ' , 'country ' , 'country-name ' , 'language ' ];
160+ $ allowedForPassword = ['new-password ' , 'current-password ' ];
161+
162+ switch ($ fieldType ) {
163+ case 'input ' :
164+ case 'textarea ' :
165+ //allow all
166+ return true ;
167+ case 'location ' :
168+ return in_array ($ token , $ allowedForAllTypes , true ) || in_array ($ token , $ allowedForLocation , true );
169+ case 'select ' :
170+ return in_array ($ token , $ allowedForAllTypes , true ) || in_array ($ token , $ allowedForSelect , true );
171+ case 'country ' :
172+ return in_array ($ token , $ allowedForAllTypes , true ) || in_array ($ token , $ allowedForCountry , true );
173+ case 'hidden ' :
174+ return in_array ($ token , $ allowedForAllTypes , true ) || in_array ($ token , $ allowedForHidden , true );
175+ case 'password ' :
176+ return in_array ($ token , $ allowedForAllTypes , true ) || in_array ($ token , $ allowedForPassword , true );
177+ }
178+ }
109179}
0 commit comments