2018-11-23 12:29:20 +00:00
< ? php
2019-01-24 08:00:03 +00:00
2018-11-23 12:29:20 +00:00
namespace Masterminds\HTML5\Tests\Serializer ;
use Masterminds\HTML5\Serializer\OutputRules ;
use Masterminds\HTML5\Serializer\Traverser ;
use Masterminds\HTML5 ;
class OutputRulesTest extends \Masterminds\HTML5\Tests\TestCase
{
protected $markup = ' <! doctype html >
< html lang = " en " >
< head >
< meta charset = " utf-8 " >
< title > Test </ title >
</ head >
< body >
< p > This is a test .</ p >
</ body >
</ html > ' ;
/**
* @ var HTML5
*/
protected $html5 ;
public function setUp ()
{
$this -> html5 = $this -> getInstance ();
}
/**
* Using reflection we make a protected method accessible for testing .
*
* @ param string $name
2019-01-24 08:00:03 +00:00
* The name of the method on the Traverser class to test
2018-11-23 12:29:20 +00:00
*
* @ return \ReflectionMethod for the specified method
*/
public function getProtectedMethod ( $name )
{
$class = new \ReflectionClass ( '\Masterminds\HTML5\Serializer\OutputRules' );
$method = $class -> getMethod ( $name );
$method -> setAccessible ( true );
return $method ;
}
public function getTraverserProtectedProperty ( $name )
{
$class = new \ReflectionClass ( '\Masterminds\HTML5\Serializer\Traverser' );
$property = $class -> getProperty ( $name );
$property -> setAccessible ( true );
return $property ;
}
public function getOutputRules ( $options = array ())
{
$options = $options + $this -> html5 -> getOptions ();
$stream = fopen ( 'php://temp' , 'w' );
$dom = $this -> html5 -> loadHTML ( $this -> markup );
$r = new OutputRules ( $stream , $options );
$t = new Traverser ( $dom , $stream , $r , $options );
return array (
$r ,
2019-01-24 08:00:03 +00:00
$stream ,
2018-11-23 12:29:20 +00:00
);
}
public function testDocument ()
{
$dom = $this -> html5 -> loadHTML ( '<!doctype html><html lang="en"><body>foo</body></html>' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$r -> document ( $dom );
$expected = '<!DOCTYPE html>' . PHP_EOL . '<html lang="en"><body>foo</body></html>' . PHP_EOL ;
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( $expected , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testEmptyDocument ()
{
2019-01-24 08:00:03 +00:00
$dom = $this -> html5 -> loadHTML ( '' );
2018-11-23 12:29:20 +00:00
2019-01-24 08:00:03 +00:00
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
2018-11-23 12:29:20 +00:00
2019-01-24 08:00:03 +00:00
$r -> document ( $dom );
$expected = '<!DOCTYPE html>' . PHP_EOL ;
$this -> assertEquals ( $expected , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testDoctype ()
{
$dom = $this -> html5 -> loadHTML ( '<!doctype html><html lang="en"><body>foo</body></html>' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$m = $this -> getProtectedMethod ( 'doctype' );
$m -> invoke ( $r , 'foo' );
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<!DOCTYPE html>' . PHP_EOL , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testElement ()
{
$dom = $this -> html5 -> loadHTML (
' <! doctype html >
< html lang = " en " >
< body >
< div id = " foo " class = " bar baz " > foo bar baz </ div >
< svg width = " 150 " height = " 100 " viewBox = " 0 0 3 2 " >
< rect width = " 1 " height = " 2 " x = " 0 " fill = " #008d46 " />
< rect width = " 1 " height = " 2 " x = " 1 " fill = " #ffffff " />
< rect width = " 1 " height = " 2 " x = " 2 " fill = " #d2232c " />
</ svg >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'div' );
$r -> element ( $list -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<div id="foo" class="bar baz">foo bar baz</div>' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
2019-01-24 08:00:03 +00:00
public function testSerializeWithNamespaces ()
2018-11-23 12:29:20 +00:00
{
$this -> html5 = $this -> getInstance ( array (
2019-01-24 08:00:03 +00:00
'xmlNamespaces' => true ,
2018-11-23 12:29:20 +00:00
));
$source = '
<! DOCTYPE html >
< html >< body id = " body " xmlns : x = " http://www.prefixed.com " >
< a id = " bar1 " xmlns = " http://www.prefixed.com/bar1 " >
< b id = " bar4 " xmlns = " http://www.prefixed.com/bar4 " >< x : prefixed id = " prefixed " > xy </ x : prefixed ></ b >
</ a >
< svg id = " svg " > svg </ svg >
< c id = " bar2 " xmlns = " http://www.prefixed.com/bar2 " ></ c >
< div id = " div " ></ div >
< d id = " bar3 " ></ d >
< xn : d id = " bar5 " xmlns : xn = " http://www.prefixed.com/xn " xmlns = " http://www.prefixed.com/bar5_x " >< x id = " bar5_x " > y </ x ></ xn : d >
</ body >
</ html > ' ;
$dom = $this -> html5 -> loadHTML ( $source , array (
2019-01-24 08:00:03 +00:00
'xmlNamespaces' => true ,
2018-11-23 12:29:20 +00:00
));
$this -> assertFalse ( $this -> html5 -> hasErrors (), print_r ( $this -> html5 -> getErrors (), 1 ));
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$t -> walk ();
2019-01-24 08:00:03 +00:00
$rendered = stream_get_contents ( $stream , - 1 , 0 );
2018-11-23 12:29:20 +00:00
2019-01-24 08:00:03 +00:00
$clear = function ( $s ) {
return trim ( preg_replace ( '/[\s]+/' , ' ' , $s ));
2018-11-23 12:29:20 +00:00
};
$this -> assertEquals ( $clear ( $source ), $clear ( $rendered ));
}
public function testElementWithScript ()
{
$dom = $this -> html5 -> loadHTML (
' <! doctype html >
< html lang = " en " >
< head >
< script >
var $jQ = jQuery . noConflict ();
// Use jQuery via $jQ(...)
$jQ ( document ) . ready ( function () {
$jQ ( " #mktFrmSubmit " ) . wrap ( " <div class= \ 'buttonSubmit \ '></div> " );
$jQ ( " .buttonSubmit " ) . prepend ( " <span></span> " );
});
</ script >
</ head >
< body >
< div id = " foo " class = " bar baz " > foo bar baz </ div >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$script = $dom -> getElementsByTagName ( 'script' );
$r -> element ( $script -> item ( 0 ));
$this -> assertEquals (
' < script >
var $jQ = jQuery . noConflict ();
// Use jQuery via $jQ(...)
$jQ ( document ) . ready ( function () {
$jQ ( " #mktFrmSubmit " ) . wrap ( " <div class= \ 'buttonSubmit \ '></div> " );
$jQ ( " .buttonSubmit " ) . prepend ( " <span></span> " );
});
2019-01-24 08:00:03 +00:00
</ script > ' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testElementWithStyle ()
{
$dom = $this -> html5 -> loadHTML (
' <! doctype html >
< html lang = " en " >
< head >
< style >
body > . bar {
display : none ;
}
</ style >
</ head >
< body >
< div id = " foo " class = " bar baz " > foo bar baz </ div >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$style = $dom -> getElementsByTagName ( 'style' );
$r -> element ( $style -> item ( 0 ));
$this -> assertEquals ( ' < style >
body > . bar {
display : none ;
}
2019-01-24 08:00:03 +00:00
</ style > ' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testOpenTag ()
{
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< body >
< div id = " foo " class = " bar baz " > foo bar baz </ div >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'div' );
$m = $this -> getProtectedMethod ( 'openTag' );
$m -> invoke ( $r , $list -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<div id="foo" class="bar baz">' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testCData ()
{
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< body >
< div ><! [ CDATA [ bar ]] ></ div >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'div' );
$r -> cdata ( $list -> item ( 0 ) -> childNodes -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<![CDATA[bar]]>' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< body >
< div id = " foo " ></ div >
</ body >
</ html > ' );
2019-01-24 08:00:03 +00:00
$dom -> getElementById ( 'foo' ) -> appendChild ( new \DOMCdataSection ( ']]>Foo<[![CDATA test ]]>' ));
2018-11-23 12:29:20 +00:00
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'div' );
$r -> cdata ( $list -> item ( 0 ) -> childNodes -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<![CDATA[]]]]><![CDATA[>Foo<[![CDATA test ]]]]><![CDATA[>]]>' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testComment ()
{
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< body >
< div ><!-- foo --></ div >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'div' );
$r -> comment ( $list -> item ( 0 ) -> childNodes -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<!-- foo -->' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< body >
< div id = " foo " ></ div >
</ body >
</ html > ' );
$dom -> getElementById ( 'foo' ) -> appendChild ( new \DOMComment ( '<!-- --> --> Foo -->' ));
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'div' );
$r -> comment ( $list -> item ( 0 ) -> childNodes -> item ( 0 ));
// Could not find more definitive guidelines on what this should be. Went with
// what the HTML5 spec says and what \DOMDocument::saveXML() produces.
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<!--<!-- --> --> Foo -->-->' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testText ()
{
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< head >
< script > baz (); </ script >
</ head >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'script' );
$r -> text ( $list -> item ( 0 ) -> childNodes -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( 'baz();' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< head id = " foo " ></ head >
</ html > ' );
$foo = $dom -> getElementById ( 'foo' );
$foo -> appendChild ( new \DOMText ( '<script>alert("hi");</script>' ));
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$r -> text ( $foo -> firstChild );
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( '<script>alert("hi");</script>' , stream_get_contents ( $stream , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testNl ()
{
2019-01-24 08:00:03 +00:00
list ( $o , $s ) = $this -> getOutputRules ();
2018-11-23 12:29:20 +00:00
$m = $this -> getProtectedMethod ( 'nl' );
$m -> invoke ( $o );
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( PHP_EOL , stream_get_contents ( $s , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function testWr ()
{
2019-01-24 08:00:03 +00:00
list ( $o , $s ) = $this -> getOutputRules ();
2018-11-23 12:29:20 +00:00
$m = $this -> getProtectedMethod ( 'wr' );
$m -> invoke ( $o , 'foo' );
2019-01-24 08:00:03 +00:00
$this -> assertEquals ( 'foo' , stream_get_contents ( $s , - 1 , 0 ));
2018-11-23 12:29:20 +00:00
}
public function getEncData ()
{
return array (
array (
false ,
'&\'<>"' ,
'&\'<>"' ,
2019-01-24 08:00:03 +00:00
'&'<>"' ,
2018-11-23 12:29:20 +00:00
),
array (
false ,
'This + is. a < test' ,
'This + is. a < test' ,
2019-01-24 08:00:03 +00:00
'This + is. a < test' ,
2018-11-23 12:29:20 +00:00
),
array (
false ,
'.+#' ,
'.+#' ,
2019-01-24 08:00:03 +00:00
'.+#' ,
2018-11-23 12:29:20 +00:00
),
array (
true ,
'.+#\'' ,
'.+#\'' ,
2019-01-24 08:00:03 +00:00
'.+#'' ,
2018-11-23 12:29:20 +00:00
),
array (
true ,
'&".<' ,
'&".<' ,
2019-01-24 08:00:03 +00:00
'&".<' ,
2018-11-23 12:29:20 +00:00
),
array (
true ,
'&\'<>"' ,
'&\'<>"' ,
2019-01-24 08:00:03 +00:00
'&'<>"' ,
2018-11-23 12:29:20 +00:00
),
array (
true ,
" \xc2 \xa0 \" ' " ,
' "\'' ,
2019-01-24 08:00:03 +00:00
' "'' ,
),
2018-11-23 12:29:20 +00:00
);
}
/**
* Test basic encoding of text .
2019-01-24 08:00:03 +00:00
*
2018-11-23 12:29:20 +00:00
* @ dataProvider getEncData
*/
public function testEnc ( $isAttribute , $test , $expected , $expectedEncoded )
{
2019-01-24 08:00:03 +00:00
list ( $o , $s ) = $this -> getOutputRules ();
2018-11-23 12:29:20 +00:00
$m = $this -> getProtectedMethod ( 'enc' );
$this -> assertEquals ( $expected , $m -> invoke ( $o , $test , $isAttribute ));
2019-01-24 08:00:03 +00:00
list ( $o , $s ) = $this -> getOutputRules ( array (
'encode_entities' => true ,
2018-11-23 12:29:20 +00:00
));
$m = $this -> getProtectedMethod ( 'enc' );
$this -> assertEquals ( $expectedEncoded , $m -> invoke ( $o , $test , $isAttribute ));
}
/**
* Test basic encoding of text .
2019-01-24 08:00:03 +00:00
*
2018-11-23 12:29:20 +00:00
* @ dataProvider getEncData
*/
public function testEscape ( $isAttribute , $test , $expected , $expectedEncoded )
{
2019-01-24 08:00:03 +00:00
list ( $o , $s ) = $this -> getOutputRules ();
2018-11-23 12:29:20 +00:00
$m = $this -> getProtectedMethod ( 'escape' );
$this -> assertEquals ( $expected , $m -> invoke ( $o , $test , $isAttribute ));
}
public function booleanAttributes ()
{
return array (
array ( '<img alt="" ismap>' ),
array ( '<img alt="">' ),
array ( '<input type="radio" readonly>' ),
array ( '<input type="radio" checked disabled>' ),
array ( '<input type="checkbox" checked disabled>' ),
array ( '<input type="radio" value="" checked disabled>' ),
array ( '<div data-value=""></div>' ),
array ( '<select disabled></select>' ),
array ( '<div ng-app></div>' ),
array ( '<script defer></script>' ),
);
}
2019-01-24 08:00:03 +00:00
2018-11-23 12:29:20 +00:00
/**
* @ dataProvider booleanAttributes
*/
public function testBooleanAttrs ( $html )
{
2019-01-24 08:00:03 +00:00
$dom = $this -> html5 -> loadHTML ( '<!doctype html><html lang="en"><body>' . $html . '</body></html>' );
2018-11-23 12:29:20 +00:00
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$node = $dom -> getElementsByTagName ( 'body' ) -> item ( 0 ) -> firstChild ;
$m = $this -> getProtectedMethod ( 'attrs' );
$m -> invoke ( $r , $node );
2019-01-24 08:00:03 +00:00
$content = stream_get_contents ( $stream , - 1 , 0 );
2018-11-23 12:29:20 +00:00
$html = preg_replace ( '~<[a-z]+(.*)></[a-z]+>~' , '\1' , $html );
$html = preg_replace ( '~<[a-z]+(.*)/?>~' , '\1' , $html );
$this -> assertEquals ( $content , $html );
}
public function testAttrs ()
{
$dom = $this -> html5 -> loadHTML ( ' <! doctype html >
< html lang = " en " >
< body >
< div id = " foo " class = " bar baz " > foo bar baz </ div >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'div' );
$m = $this -> getProtectedMethod ( 'attrs' );
$m -> invoke ( $r , $list -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$content = stream_get_contents ( $stream , - 1 , 0 );
2018-11-23 12:29:20 +00:00
$this -> assertEquals ( ' id="foo" class="bar baz"' , $content );
}
public function testSvg ()
{
$dom = $this -> html5 -> loadHTML (
' <! doctype html >
< html lang = " en " >
< body >
< div id = " foo " class = " bar baz " > foo bar baz </ div >
< svg width = " 150 " height = " 100 " viewBox = " 0 0 3 2 " >
< rect width = " 1 " height = " 2 " x = " 0 " fill = " #008d46 " />
< rect width = " 1 " height = " 2 " x = " 1 " fill = " #ffffff " />
< rect width = " 1 " height = " 2 " x = " 2 " fill = " #d2232c " />
< rect id = " Bar " x = " 300 " y = " 100 " width = " 300 " height = " 100 " fill = " rgb(255,255,0) " >
< animate attributeName = " x " attributeType = " XML " begin = " 0s " dur = " 9s " fill = " freeze " from = " 300 " to = " 0 " />
</ rect >
</ svg >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'svg' );
$r -> element ( $list -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$contents = stream_get_contents ( $stream , - 1 , 0 );
2018-11-23 12:29:20 +00:00
$this -> assertRegExp ( '|<svg width="150" height="100" viewBox="0 0 3 2">|' , $contents );
$this -> assertRegExp ( '|<rect width="1" height="2" x="0" fill="#008d46" />|' , $contents );
$this -> assertRegExp ( '|<rect id="Bar" x="300" y="100" width="300" height="100" fill="rgb\(255,255,0\)">|' , $contents );
}
public function testMath ()
{
$dom = $this -> html5 -> loadHTML (
' <! doctype html >
< html lang = " en " >
< body >
< div id = " foo " class = " bar baz " > foo bar baz </ div >
< math >
< mi > x </ mi >
< csymbol definitionURL = " http://www.example.com/mathops/multiops.html#plusminus " >
< mo >& PlusMinus ; </ mo >
</ csymbol >
< mi > y </ mi >
</ math >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'math' );
$r -> element ( $list -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$content = stream_get_contents ( $stream , - 1 , 0 );
2018-11-23 12:29:20 +00:00
$this -> assertRegExp ( '|<math>|' , $content );
$this -> assertRegExp ( '|<csymbol definitionURL="http://www.example.com/mathops/multiops.html#plusminus">|' , $content );
}
public function testProcessorInstruction ()
{
$dom = $this -> html5 -> loadHTMLFragment ( '<?foo bar ?>' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$r -> processorInstruction ( $dom -> firstChild );
2019-01-24 08:00:03 +00:00
$content = stream_get_contents ( $stream , - 1 , 0 );
2018-11-23 12:29:20 +00:00
$this -> assertRegExp ( '|<\?foo bar \?>|' , $content );
}
public function testAddressTag ()
{
$dom = $this -> html5 -> loadHTML (
' <! doctype html >
< html lang = " en " >
< body >
< address >
< a href = " ../People/Raggett/ " > Dave Raggett </ a > ,
< a href = " ../People/Arnaud/ " > Arnaud Le Hors </ a > ,
contact persons for the < a href = " Activity " > W3C HTML Activity </ a >
</ address >
</ body >
</ html > ' );
$stream = fopen ( 'php://temp' , 'w' );
$r = new OutputRules ( $stream , $this -> html5 -> getOptions ());
$t = new Traverser ( $dom , $stream , $r , $this -> html5 -> getOptions ());
$list = $dom -> getElementsByTagName ( 'address' );
$r -> element ( $list -> item ( 0 ));
2019-01-24 08:00:03 +00:00
$contents = stream_get_contents ( $stream , - 1 , 0 );
2018-11-23 12:29:20 +00:00
$this -> assertRegExp ( '|<address>|' , $contents );
$this -> assertRegExp ( '|<a href="../People/Raggett/">Dave Raggett</a>,|' , $contents );
$this -> assertRegExp ( '|<a href="../People/Arnaud/">Arnaud Le Hors</a>,|' , $contents );
$this -> assertRegExp ( '|contact persons for the <a href="Activity">W3C HTML Activity</a>|' , $contents );
$this -> assertRegExp ( '|</address>|' , $contents );
}
/**
2019-01-24 08:00:03 +00:00
* Ensure direct DOM manipulation doesn ' t break TEXT_RAW elements ( iframe , script , etc ... ) .
2018-11-23 12:29:20 +00:00
*/
public function testHandlingInvalidRawContent ()
{
$dom = $this -> html5 -> loadHTML (
' <! doctype html >
< html lang = " en " id = " base " >
< body >
< script id = " template " type = " x-tmpl-mustache " >
< h1 > Hello !</ h1 >
</ script >
</ body >
</ html > ' );
2019-01-24 08:00:03 +00:00
$badNode = $dom -> createElement ( 'p' , 'Bar' );
2018-11-23 12:29:20 +00:00
// modify the content of the TEXT_RAW element: <script id="template"> appending dom nodes
2019-01-24 08:00:03 +00:00
$styleElement = $dom -> getElementById ( 'template' );
2018-11-23 12:29:20 +00:00
$styleElement -> appendChild ( $badNode );
$contents = $this -> html5 -> saveHTML ( $dom );
2019-01-24 08:00:03 +00:00
$this -> assertTrue ( false !== strpos ( $contents , ' < script id = " template " type = " x-tmpl-mustache " >
2018-11-23 12:29:20 +00:00
< h1 > Hello !</ h1 >
2019-01-24 08:00:03 +00:00
< p > Bar </ p ></ script > ' ));
2018-11-23 12:29:20 +00:00
}
}