@@ -61,51 +61,107 @@ lxb_status_t php_dom_query_selector_find_matches_callback(const xmlNode *node, l
61
61
return LXB_STATUS_OK ;
62
62
}
63
63
64
- static lxb_status_t php_dom_query_selector_common (
65
- zval * return_value ,
66
- const xmlNode * root ,
67
- zend_string * selectors_str ,
68
- lxb_selectors_cb_f cb ,
69
- void * ctx ,
64
+ static lxb_css_selector_list_t * php_dom_parse_selector (
65
+ lxb_css_parser_t * parser ,
66
+ lxb_selectors_t * selectors ,
67
+ const zend_string * selectors_str ,
70
68
lxb_selectors_opt_t options
71
69
)
72
70
{
73
71
lxb_status_t status ;
74
72
75
- lxb_css_parser_t parser ;
76
- memset (& parser , 0 , sizeof (lxb_css_parser_t ));
77
- status = lxb_css_parser_init (& parser , NULL );
73
+ memset (parser , 0 , sizeof (lxb_css_parser_t ));
74
+ status = lxb_css_parser_init (parser , NULL );
78
75
ZEND_ASSERT (status == LXB_STATUS_OK );
79
76
80
- lxb_selectors_t selectors ;
81
- memset (& selectors , 0 , sizeof (lxb_selectors_t ));
82
- status = lxb_selectors_init (& selectors );
77
+ memset (selectors , 0 , sizeof (lxb_selectors_t ));
78
+ status = lxb_selectors_init (selectors );
83
79
ZEND_ASSERT (status == LXB_STATUS_OK );
84
- lxb_selectors_opt_set (& selectors , options );
80
+ lxb_selectors_opt_set (selectors , options );
85
81
86
- lxb_css_selector_list_t * list = lxb_css_selectors_parse (& parser , (const lxb_char_t * ) ZSTR_VAL (selectors_str ), ZSTR_LEN (selectors_str ));
82
+ lxb_css_selector_list_t * list = lxb_css_selectors_parse (parser , (const lxb_char_t * ) ZSTR_VAL (selectors_str ), ZSTR_LEN (selectors_str ));
87
83
if (UNEXPECTED (list == NULL )) {
88
- size_t nr_of_messages = lexbor_array_obj_length (& parser . log -> messages );
84
+ size_t nr_of_messages = lexbor_array_obj_length (& parser -> log -> messages );
89
85
if (nr_of_messages > 0 ) {
90
- lxb_css_log_message_t * msg = lexbor_array_obj_get (& parser . log -> messages , 0 );
86
+ lxb_css_log_message_t * msg = lexbor_array_obj_get (& parser -> log -> messages , 0 );
91
87
char * error ;
92
88
zend_spprintf (& error , 0 , "Invalid selector (%.*s)" , (int ) msg -> text .length , msg -> text .data );
93
89
php_dom_throw_error_with_message (SYNTAX_ERR , error , true);
94
90
efree (error );
95
91
} else {
96
92
php_dom_throw_error_with_message (SYNTAX_ERR , "Invalid selector" , true);
97
93
}
94
+ }
95
+
96
+ return list ;
97
+ }
98
+
99
+ static lxb_status_t php_dom_check_css_execution_status (lxb_status_t status )
100
+ {
101
+ if (UNEXPECTED (status != LXB_STATUS_OK && status != LXB_STATUS_STOP )) {
102
+ zend_argument_value_error (1 , "contains an unsupported selector" );
103
+ return status ;
104
+ }
105
+ return LXB_STATUS_OK ;
106
+ }
107
+
108
+ static void php_dom_selector_cleanup (lxb_css_parser_t * parser , lxb_selectors_t * selectors , lxb_css_selector_list_t * list )
109
+ {
110
+ lxb_css_selector_list_destroy_memory (list );
111
+ lxb_selectors_destroy (selectors );
112
+ (void ) lxb_css_parser_destroy (parser , false);
113
+ }
114
+
115
+ static lxb_status_t php_dom_query_selector_common (
116
+ zval * return_value ,
117
+ const xmlNode * root ,
118
+ zend_string * selectors_str ,
119
+ lxb_selectors_cb_f cb ,
120
+ void * ctx ,
121
+ lxb_selectors_opt_t options
122
+ )
123
+ {
124
+ lxb_status_t status ;
125
+
126
+ lxb_css_parser_t parser ;
127
+ lxb_selectors_t selectors ;
128
+
129
+ lxb_css_selector_list_t * list = php_dom_parse_selector (& parser , & selectors , selectors_str , options );
130
+ if (UNEXPECTED (list == NULL )) {
98
131
status = LXB_STATUS_ERROR ;
99
132
} else {
100
133
status = lxb_selectors_find (& selectors , root , list , cb , ctx );
101
- if (UNEXPECTED (status != LXB_STATUS_OK && status != LXB_STATUS_STOP )) {
102
- zend_argument_value_error (1 , "contains an unsupported selector" );
103
- }
134
+ status = php_dom_check_css_execution_status (status );
104
135
}
105
136
106
- lxb_css_selector_list_destroy_memory (list );
107
- lxb_selectors_destroy (& selectors );
108
- (void ) lxb_css_parser_destroy (& parser , false);
137
+ php_dom_selector_cleanup (& parser , & selectors , list );
138
+
139
+ return status ;
140
+ }
141
+
142
+ static lxb_status_t php_dom_query_matches (
143
+ zval * return_value ,
144
+ const xmlNode * root ,
145
+ zend_string * selectors_str ,
146
+ lxb_selectors_cb_f cb ,
147
+ void * ctx ,
148
+ lxb_selectors_opt_t options
149
+ )
150
+ {
151
+ lxb_status_t status ;
152
+
153
+ lxb_css_parser_t parser ;
154
+ lxb_selectors_t selectors ;
155
+
156
+ lxb_css_selector_list_t * list = php_dom_parse_selector (& parser , & selectors , selectors_str , options );
157
+ if (UNEXPECTED (list == NULL )) {
158
+ status = LXB_STATUS_ERROR ;
159
+ } else {
160
+ status = lxb_selectors_match_node (& selectors , root , list , cb , ctx );
161
+ status = php_dom_check_css_execution_status (status );
162
+ }
163
+
164
+ php_dom_selector_cleanup (& parser , & selectors , list );
109
165
110
166
return status ;
111
167
}
@@ -159,18 +215,13 @@ void dom_element_matches(xmlNodePtr thisp, dom_object *intern, zval *return_valu
159
215
{
160
216
dom_query_selector_matches_ctx ctx = { thisp , false };
161
217
162
- const xmlNode * root = thisp ;
163
- while (root -> parent != NULL ) {
164
- root = root -> parent ;
165
- }
166
-
167
- if (php_dom_query_selector_common (
218
+ if (php_dom_query_matches (
168
219
return_value ,
169
- root ,
220
+ thisp ,
170
221
selectors_str ,
171
222
php_dom_query_selector_find_matches_callback ,
172
223
& ctx ,
173
- LXB_SELECTORS_OPT_DEFAULT
224
+ LXB_SELECTORS_OPT_MATCH_FIRST
174
225
) != LXB_STATUS_OK ) {
175
226
RETURN_THROWS ();
176
227
} else {
0 commit comments