styles; } public function sanitize() { $body = $this->get_body_node(); $this->collect_styles_recursive( $body ); } private function collect_styles_recursive( $node ) { if ( $node->nodeType !== XML_ELEMENT_NODE ) { return; } if ( $node->hasAttributes() && $node instanceof DOMElement ) { $style = $node->getAttribute( 'style' ); $class = $node->getAttribute( 'class' ); if ( $style ) { $style = $this->process_style( $style ); if ( ! empty( $style ) ) { $class_name = $this->generate_class_name( $style ); $new_class = trim( $class . ' ' . $class_name ); $node->setAttribute( 'class', $new_class ); $this->styles[ '.' . $class_name ] = $style; } $node->removeAttribute( 'style' ); } } $length = $node->childNodes->length; for ( $i = $length - 1; $i >= 0; $i -- ) { $child_node = $node->childNodes->item( $i ); $this->collect_styles_recursive( $child_node ); } } private function process_style( $string ) { // Filter properties $string = safecss_filter_attr( esc_html( $string ) ); if ( ! $string ) { return array(); } // Normalize order $styles = array_map( 'trim', explode( ';', $string ) ); sort( $styles ); $processed_styles = array(); // Normalize whitespace and filter rules foreach ( $styles as $index => $rule ) { $arr2 = array_map( 'trim', explode( ':', $rule, 2 ) ); if ( 2 !== count( $arr2 ) ) { continue; } list( $property, $value ) = $this->filter_style( $arr2[0], $arr2[1] ); if ( empty( $property ) || empty( $value ) ) { continue; } $processed_styles[ $index ] = $property . ':' . $value; } return $processed_styles; } private function filter_style( $property, $value ) { // Handle overflow rule // https://www.ampproject.org/docs/reference/spec.html#properties if ( 0 === strpos( $property, 'overflow' ) && ( false !== strpos( $value, 'auto' ) || false !== strpos( $value, 'scroll' ) ) ) { return false; } if ( 'width' === $property ) { $property = 'max-width'; } // !important is not allowed if ( false !== strpos( $value, 'important' ) ) { $value = preg_replace( '/\s*\!\s*important$/', '', $value ); } return array( $property, $value ); } private function generate_class_name( $data ) { $string = maybe_serialize( $data ); return 'amp-wp-inline-' . md5( $string ); } }