public function test__is_node_empty__no__has_child()
 {
     $source = '<p><b></b></p>';
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $node = $dom->getElementsByTagName('p')->item(0);
     $this->assertFalse(AMP_DOM_Utils::is_node_empty($node));
 }
 public function sanitize()
 {
     $nodes = $this->dom->getElementsByTagName(self::$tag);
     $num_nodes = $nodes->length;
     if (0 === $num_nodes) {
         return;
     }
     for ($i = $num_nodes - 1; $i >= 0; $i--) {
         $node = $nodes->item($i);
         $old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($node);
         $new_attributes = $this->filter_attributes($old_attributes);
         if (!isset($new_attributes['width'], $new_attributes['height'])) {
             $new_attributes['height'] = self::FALLBACK_HEIGHT;
             $new_attributes['layout'] = 'fixed-height';
         }
         $new_attributes = $this->enforce_sizes_attribute($new_attributes);
         $new_node = AMP_DOM_Utils::create_node($this->dom, 'amp-video', $new_attributes);
         // TODO: limit child nodes too (only allowed: `source`; move rest to div+fallback)
         // TODO: `source` does not have closing tag, and DOMDocument doesn't handle it well.
         foreach ($node->childNodes as $child_node) {
             $new_child_node = $child_node->cloneNode(true);
             $new_node->appendChild($new_child_node);
         }
         $node->parentNode->replaceChild($new_node, $node);
     }
 }
 public function sanitize($amp_attributes = array())
 {
     $nodes = $this->dom->getElementsByTagName(self::$tag);
     $num_nodes = $nodes->length;
     if (0 === $num_nodes) {
         return;
     }
     for ($i = $num_nodes - 1; $i >= 0; $i--) {
         $node = $nodes->item($i);
         $old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($node);
         if (!array_key_exists('src', $old_attributes)) {
             $node->parentNode->removeChild($node);
             continue;
         }
         $new_attributes = $this->filter_attributes($old_attributes);
         if (!isset($new_attributes['width']) || !isset($new_attributes['height'])) {
             $dimensions = AMP_Image_Dimension_Extractor::extract($new_attributes['src']);
             if ($dimensions) {
                 $new_attributes['width'] = $dimensions[0];
                 $new_attributes['height'] = $dimensions[1];
             }
         }
         $new_attributes = $this->enforce_sizes_attribute($new_attributes);
         $new_attributes = array_merge($new_attributes, $amp_attributes);
         if ($this->is_gif_url($new_attributes['src'])) {
             $this->did_convert_elements = true;
             $new_tag = 'amp-anim';
         } else {
             $new_tag = 'amp-img';
         }
         $new_node = AMP_DOM_Utils::create_node($this->dom, $new_tag, $new_attributes);
         $node->parentNode->replaceChild($new_node, $node);
     }
 }
 public function sanitize()
 {
     $nodes = $this->dom->getElementsByTagName(self::$tag);
     $num_nodes = $nodes->length;
     if (0 === $num_nodes) {
         return;
     }
     for ($i = $num_nodes - 1; $i >= 0; $i--) {
         $node = $nodes->item($i);
         $old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($node);
         $new_attributes = $this->filter_attributes($old_attributes);
         $new_node = AMP_DOM_Utils::create_node($this->dom, 'amp-audio', $new_attributes);
         // TODO: `source` does not have closing tag, and DOMDocument doesn't handle it well.
         foreach ($node->childNodes as $child_node) {
             $new_child_node = $child_node->cloneNode(true);
             $old_child_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($new_child_node);
             $new_child_attributes = $this->filter_attributes($old_child_attributes);
             // Only append source tags with a valid src attribute
             if (!empty($new_child_attributes['src']) && 'source' === $new_child_node->tagName) {
                 $new_node->appendChild($new_child_node);
             }
         }
         // If the node has at least one valid source, replace the old node with it.
         // Otherwise, just remove the node.
         //
         // TODO: Add a fallback handler.
         // See: https://github.com/ampproject/amphtml/issues/2261
         if (0 === $new_node->childNodes->length && empty($new_attributes['src'])) {
             $node->parentNode->removeChild($node);
         } else {
             $node->parentNode->replaceChild($new_node, $node);
         }
         $this->did_convert_elements = true;
     }
 }
 /**
  * @dataProvider get_data
  */
 public function test_sanitizer($source, $expected)
 {
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Blacklist_Sanitizer($dom);
     $sanitizer->sanitize();
     $content = AMP_DOM_Utils::get_content_from_dom($dom);
     $this->assertEquals($expected, $content);
 }
 public function test_add_attributes_to_node__attribute_with_value()
 {
     $dom = AMP_DOM_Utils::get_dom_from_content('<p>Hello World</p>');
     $node = $dom->createElement('div');
     $attributes = array('class' => 'myClass', 'id' => 'myId');
     AMP_DOM_Utils::add_attributes_to_node($node, $attributes);
     $this->assertTrue($node->hasAttributes());
     $this->check_node_has_attributes($node, $attributes);
 }
 public function test_get_scripts__empty()
 {
     $source = '<video width="300" height="300" src="https://archive.org/download/WebmVp8Vorbis/webmvp8_512kb.mp4"></video>';
     $expected = array();
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Video_Sanitizer($dom);
     $sanitizer->sanitize();
     $scripts = $sanitizer->get_scripts();
     $this->assertEquals($expected, $scripts);
 }
 public function test__args__placeholder()
 {
     $source = '<iframe src="https://example.com/video/132886713" width="500" height="281"></iframe>';
     $expected = '<amp-iframe src="https://example.com/video/132886713" width="500" height="281" sandbox="allow-scripts allow-same-origin" sizes="(min-width: 500px) 500px, 100vw" class="amp-wp-enforced-sizes"><div placeholder="" class="amp-wp-iframe-placeholder"></div></amp-iframe>';
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Iframe_Sanitizer($dom, array('add_placeholder' => true));
     $sanitizer->sanitize();
     $content = AMP_DOM_Utils::get_content_from_dom($dom);
     $this->assertEquals($expected, $content);
 }
 public function test_get_scripts__did_convert()
 {
     $source = '<iframe src="https://player.vimeo.com/video/132886713" width="500" height="281"></iframe>';
     $expected = array('amp-iframe' => 'https://cdn.ampproject.org/v0/amp-iframe-0.1.js');
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Iframe_Sanitizer($dom);
     $sanitizer->sanitize();
     $scripts = $sanitizer->get_scripts();
     $this->assertEquals($expected, $scripts);
 }
 public function test_no_gif_image_scripts()
 {
     $source = '<img src="http://placehold.it/350x150.gif" width="350" height="150" alt="Placeholder!" />';
     $expected = array('amp-anim' => 'https://cdn.ampproject.org/v0/amp-anim-0.1.js');
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Img_Sanitizer($dom);
     $sanitizer->sanitize();
     $scripts = $sanitizer->get_scripts();
     $this->assertEquals($expected, $scripts);
 }
 public function test_get_scripts__did_convert()
 {
     $source = '<audio width="400" height="300" src="https://example.com/audio/file.ogg"></audio>';
     $expected = array('amp-audio' => 'https://cdn.ampproject.org/v0/amp-audio-0.1.js');
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Audio_Sanitizer($dom);
     $sanitizer->sanitize();
     $scripts = $sanitizer->get_scripts();
     $this->assertEquals($expected, $scripts);
 }
 public function test_get_scripts__empty()
 {
     $source = '<video width="300" height="300" src="https://example.com/video.mp4"></video>';
     $expected = array();
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Video_Sanitizer($dom);
     $sanitizer->sanitize();
     $scripts = $sanitizer->get_scripts();
     $this->assertEquals($expected, $scripts);
 }
 /**
  * @dataProvider get_data
  */
 public function test_sanitizer($source, $expected_content, $expected_stylesheet)
 {
     $dom = AMP_DOM_Utils::get_dom_from_content($source);
     $sanitizer = new AMP_Style_Sanitizer($dom);
     $sanitizer->sanitize();
     // Test content
     $content = AMP_DOM_Utils::get_content_from_dom($dom);
     $this->assertEquals($expected_content, $content);
     // Test stylesheet
     $stylesheet = $sanitizer->get_styles();
     $this->assertEquals($expected_stylesheet, $stylesheet);
 }
Beispiel #14
0
 private function sanitize($content)
 {
     $dom = AMP_DOM_Utils::get_dom_from_content($content);
     foreach ($this->sanitizer_classes as $sanitizer_class => $args) {
         $sanitizer = new $sanitizer_class($dom, array_merge($this->args, $args));
         if (!is_subclass_of($sanitizer, 'AMP_Base_Sanitizer')) {
             _doing_it_wrong(__METHOD__, sprintf(__('Sanitizer (%s) must extend `AMP_Base_Sanitizer`', 'amp'), esc_html($sanitizer_class)), '0.1');
             continue;
         }
         $sanitizer->sanitize();
         $this->add_scripts($sanitizer->get_scripts());
     }
     return AMP_DOM_Utils::get_content_from_dom($dom);
 }
 /**
  * Make final modifications to DOMNode
  *
  * @param DOMNode $node The DOMNode to adjust and replace
  */
 private function adjust_and_replace_node($node)
 {
     $old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($node);
     $new_attributes = $this->filter_attributes($old_attributes);
     $new_attributes = $this->enforce_sizes_attribute($new_attributes);
     if ($this->is_gif_url($new_attributes['src'])) {
         $this->did_convert_elements = true;
         $new_tag = 'amp-anim';
     } else {
         $new_tag = 'amp-img';
     }
     $new_node = AMP_DOM_Utils::create_node($this->dom, $new_tag, $new_attributes);
     $node->parentNode->replaceChild($new_node, $node);
 }
 private function strip_tags($node, $tag_names)
 {
     foreach ($tag_names as $tag_name) {
         $elements = $node->getElementsByTagName($tag_name);
         $length = $elements->length;
         if (0 === $length) {
             continue;
         }
         for ($i = $length - 1; $i >= 0; $i--) {
             $element = $elements->item($i);
             $parent_node = $element->parentNode;
             $parent_node->removeChild($element);
             if ('body' !== $parent_node->nodeName && AMP_DOM_Utils::is_node_empty($parent_node)) {
                 $parent_node->parentNode->removeChild($parent_node);
             }
         }
     }
 }
 public function sanitize()
 {
     $nodes = $this->dom->getElementsByTagName(self::$tag);
     $num_nodes = $nodes->length;
     if (0 === $num_nodes) {
         return;
     }
     for ($i = $num_nodes - 1; $i >= 0; $i--) {
         $node = $nodes->item($i);
         $old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($node);
         // Added data-src for lazy-loaded imgs.
         if (!array_key_exists('src', $old_attributes) && !array_key_exists('data-src', $old_attributes)) {
             $node->parentNode->removeChild($node);
             continue;
         }
         $new_attributes = $this->filter_attributes($old_attributes);
         // Try to extract dimensions for the image, if not set.
         if (!isset($new_attributes['width']) || !isset($new_attributes['height'])) {
             $dimensions = AMP_Image_Dimension_Extractor::extract($new_attributes['src']);
             if (is_array($dimensions)) {
                 $new_attributes['width'] = $dimensions[0];
                 $new_attributes['height'] = $dimensions[1];
             }
         }
         // Final fallback when we have no dimensions.
         if (!isset($new_attributes['width']) || !isset($new_attributes['height'])) {
             $new_attributes['width'] = isset($this->args['content_max_width']) ? $this->args['content_max_width'] : self::FALLBACK_WIDTH;
             $new_attributes['height'] = self::FALLBACK_HEIGHT;
             $this->add_or_append_attribute($new_attributes, 'class', 'amp-wp-unknown-size');
         }
         $new_attributes = $this->enforce_sizes_attribute($new_attributes);
         if ($this->is_gif_url($new_attributes['src'])) {
             $this->did_convert_elements = true;
             $new_tag = 'amp-anim';
         } else {
             $new_tag = 'amp-img';
         }
         $new_node = AMP_DOM_Utils::create_node($this->dom, $new_tag, $new_attributes);
         $node->parentNode->replaceChild($new_node, $node);
     }
 }
Beispiel #18
0
 public function transform()
 {
     $content = $this->original_content;
     $twitter_embed = new AMP_Twitter_Embed_Handler();
     $youtube_embed = new AMP_YouTube_Embed_Handler();
     $gallery_embed = new AMP_Gallery_Embed_Handler();
     $instagram_embed = new AMP_Instagram_Embed_Handler();
     $content = apply_filters('the_content', $content);
     $this->add_scripts($twitter_embed->get_scripts());
     $this->add_scripts($youtube_embed->get_scripts());
     $this->add_scripts($gallery_embed->get_scripts());
     $this->add_scripts($instagram_embed->get_scripts());
     $dom = AMP_DOM_Utils::get_dom_from_content($content);
     $this->sanitize(new AMP_Blacklist_Sanitizer($dom, $this->args));
     $this->sanitize(new AMP_Img_Sanitizer($dom, $this->args));
     $this->sanitize(new AMP_Video_Sanitizer($dom, $this->args));
     $this->sanitize(new AMP_Iframe_Sanitizer($dom, $this->args));
     $this->sanitize(new AMP_Audio_Sanitizer($dom, $this->args));
     $content = AMP_DOM_Utils::get_content_from_dom($dom);
     return $content;
 }
 public function sanitize($amp_attributes = array())
 {
     $nodes = $this->dom->getElementsByTagName(self::$tag);
     $num_nodes = $nodes->length;
     if (0 === $num_nodes) {
         return;
     }
     for ($i = $num_nodes - 1; $i >= 0; $i--) {
         $node = $nodes->item($i);
         $old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($node);
         if (!array_key_exists('src', $old_attributes)) {
             $node->parentNode->removeChild($node);
             continue;
         }
         $this->did_convert_elements = true;
         $new_attributes = $this->filter_attributes($old_attributes);
         $new_attributes = $this->enforce_sizes_attribute($new_attributes);
         $new_attributes = array_merge($new_attributes, $amp_attributes);
         $new_node = AMP_DOM_Utils::create_node($this->dom, 'amp-iframe', $new_attributes);
         $node->parentNode->replaceChild($new_node, $node);
     }
 }
 public function sanitize()
 {
     $nodes = $this->dom->getElementsByTagName(self::$tag);
     $num_nodes = $nodes->length;
     if (0 === $num_nodes) {
         return;
     }
     for ($i = $num_nodes - 1; $i >= 0; $i--) {
         $node = $nodes->item($i);
         $old_attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array($node);
         $new_attributes = $this->filter_attributes($old_attributes);
         $new_node = AMP_DOM_Utils::create_node($this->dom, 'amp-audio', $new_attributes);
         // TODO: limit child nodes too (only allowed: `source`; move rest to div+fallback)
         // TODO: `source` does not have closing tag, and DOMDocument doesn't handle it well.
         foreach ($node->childNodes as $child_node) {
             $new_child_node = $child_node->cloneNode(true);
             $new_node->appendChild($new_child_node);
         }
         $node->parentNode->replaceChild($new_node, $node);
         $this->did_convert_elements = true;
     }
 }
 private function build_placeholder($parent_attributes)
 {
     $placeholder_node = AMP_DOM_Utils::create_node($this->dom, 'div', array('layout' => 'fill', 'placeholder' => '', 'class' => 'amp-wp-iframe-placeholder'));
     return $placeholder_node;
 }
 public function test__recursive_force_closing_tags__force_close_with_children()
 {
     $dom = new DOMDocument();
     $node = $dom->createElement('div');
     $child_with_closing = $dom->createElement('amp-img');
     $child_self_closing = $dom->createElement('br');
     $node->appendChild($child_with_closing);
     $node->appendChild($child_self_closing);
     $expected = '<div><amp-img></amp-img><br/></div>';
     AMP_DOM_Utils::recursive_force_closing_tags($dom, $node);
     $this->assertEquals($expected, $dom->saveXML($node));
 }
Beispiel #23
0
 public static function sanitize($content, $sanitizer_classes, $args = array())
 {
     $scripts = array();
     $styles = array();
     $dom = AMP_DOM_Utils::get_dom_from_content($content);
     foreach ($sanitizer_classes as $sanitizer_class => $args) {
         if (!class_exists($sanitizer_class)) {
             _doing_it_wrong(__METHOD__, sprintf(__('Sanitizer (%s) class does not exist', 'amp'), esc_html($sanitizer_class)), '0.4.1');
             continue;
         }
         $sanitizer = new $sanitizer_class($dom, array_merge($args, $args));
         if (!is_subclass_of($sanitizer, 'AMP_Base_Sanitizer')) {
             _doing_it_wrong(__METHOD__, sprintf(__('Sanitizer (%s) must extend `AMP_Base_Sanitizer`', 'amp'), esc_html($sanitizer_class)), '0.1');
             continue;
         }
         $sanitizer->sanitize();
         $scripts = array_merge($scripts, $sanitizer->get_scripts());
         $styles = array_merge($styles, $sanitizer->get_styles());
     }
     $sanitized_content = AMP_DOM_Utils::get_content_from_dom($dom);
     return array($sanitized_content, $scripts, $styles);
 }