public function process_textnodes( $html, callable $fixer, Settings $settings, $is_title = false, array $body_classes = [] ) {
		if ( isset( $settings['ignoreTags'] ) && $is_title && ( \in_array( 'h1', /** Array. @scrutinizer ignore-type */ $settings['ignoreTags'], true ) || \in_array( 'h2', /** Array. @scrutinizer ignore-type */ $settings['ignoreTags'], true ) ) ) {
			return $html;
		}

		// Lazy-load our parser (the text parser is not needed for feeds).
		$html5_parser = $this->get_html5_parser();

		// Parse the HTML.
		$dom = $this->parse_html( $html5_parser, $html, $settings, $body_classes );

		// Abort if there were parsing errors.
		if ( empty( $dom ) ) {
			return $html;
		}

		// Query some nodes in the DOM.
		$xpath          = new \DOMXPath( $dom );
		$body_node      = $xpath->query( '/html/body' )->item( 0 );
		$tags_to_ignore = $this->query_tags_to_ignore( $xpath, $body_node, $settings );

		// Start processing.
		foreach ( $xpath->query( '//text()', $body_node ) as $textnode ) {
			if (
				// One of the ancestors should be ignored.
				self::arrays_intersect( DOM::get_ancestors( $textnode ), $tags_to_ignore ) ||
				// The node contains only whitespace.
				$textnode->isWhitespaceInElementContent()
			) {
				continue;
			}

			// Store original content.
			$original = $textnode->data;

			// Apply fixes.
			$fixer( $textnode, $settings, $is_title );

			// Until now, we've only been working on a textnode: HTMLify result.
			$new = $textnode->data;

			// Replace original node (if anthing was changed).
			if ( $new !== $original ) {
				$this->replace_node_with_html( $textnode, $new );
			}
		}

		return $html5_parser->saveHTML( $body_node->childNodes );
	}