360: def match(element, first_only = false)
361:
362: if matched = (!@tag_name or @tag_name == element.name)
363:
364: for attr in @attributes
365: if element.attributes[attr[0]] !~ attr[1]
366: matched = false
367: break
368: end
369: end
370: end
371:
372:
373: if matched
374: for pseudo in @pseudo
375: unless pseudo.call(element)
376: matched = false
377: break
378: end
379: end
380: end
381:
382:
383: if matched and @negation
384: for negation in @negation
385: if negation[:tag_name] == element.name
386: matched = false
387: else
388: for attr in negation[:attributes]
389: if element.attributes[attr[0]] =~ attr[1]
390: matched = false
391: break
392: end
393: end
394: end
395: if matched
396: for pseudo in negation[:pseudo]
397: if pseudo.call(element)
398: matched = false
399: break
400: end
401: end
402: end
403: break unless matched
404: end
405: end
406:
407:
408:
409: if matched and @depends
410: matches = @depends.call(element, first_only)
411: else
412: matches = matched ? [element] : nil
413: end
414:
415:
416:
417: if @alternates and (!first_only or !matches)
418: @alternates.each do |alternate|
419: break if matches and first_only
420: if subset = alternate.match(element, first_only)
421: if matches
422: matches.concat subset
423: else
424: matches = subset
425: end
426: end
427: end
428: end
429:
430: matches
431: end