]>
Commit | Line | Data |
---|---|---|
42c80841 NL |
1 | <?php\r |
2 | /**\r | |
3 | * JavaScript-like HTML DOM Element\r | |
4 | *\r | |
5 | * This class extends PHP's DOMElement to allow\r | |
6 | * users to get and set the innerHTML property of\r | |
7 | * HTML elements in the same way it's done in \r | |
8 | * JavaScript.\r | |
9 | *\r | |
10 | * Example usage:\r | |
11 | * @code\r | |
12 | * require_once 'JSLikeHTMLElement.php';\r | |
13 | * header('Content-Type: text/plain');\r | |
14 | * $doc = new DOMDocument();\r | |
15 | * $doc->registerNodeClass('DOMElement', 'JSLikeHTMLElement');\r | |
16 | * $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>');\r | |
17 | * $elem = $doc->getElementsByTagName('div')->item(0);\r | |
18 | * \r | |
19 | * // print innerHTML\r | |
20 | * echo $elem->innerHTML; // prints '<p>Para 1</p><p>Para 2</p>'\r | |
21 | * echo "\n\n";\r | |
22 | * \r | |
23 | * // set innerHTML\r | |
24 | * $elem->innerHTML = '<a href="http://fivefilters.org">FiveFilters.org</a>';\r | |
25 | * echo $elem->innerHTML; // prints '<a href="http://fivefilters.org">FiveFilters.org</a>'\r | |
26 | * echo "\n\n";\r | |
27 | * \r | |
28 | * // print document (with our changes)\r | |
29 | * echo $doc->saveXML();\r | |
30 | * @endcode\r | |
31 | *\r | |
32 | * @author Keyvan Minoukadeh - http://www.keyvan.net - keyvan@keyvan.net\r | |
33 | * @see http://fivefilters.org (the project this was written for)\r | |
34 | */\r | |
35 | class JSLikeHTMLElement extends DOMElement\r | |
36 | {\r | |
37 | /**\r | |
38 | * Used for setting innerHTML like it's done in JavaScript:\r | |
39 | * @code\r | |
40 | * $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>';\r | |
41 | * @endcode\r | |
42 | */\r | |
43 | public function __set($name, $value) {\r | |
44 | if ($name == 'innerHTML') {\r | |
45 | // first, empty the element\r | |
46 | for ($x=$this->childNodes->length-1; $x>=0; $x--) {\r | |
47 | $this->removeChild($this->childNodes->item($x));\r | |
48 | }\r | |
49 | // $value holds our new inner HTML\r | |
50 | if ($value != '') {\r | |
51 | $f = $this->ownerDocument->createDocumentFragment();\r | |
52 | // appendXML() expects well-formed markup (XHTML)\r | |
53 | $result = @$f->appendXML($value); // @ to suppress PHP warnings\r | |
54 | if ($result) {\r | |
55 | if ($f->hasChildNodes()) $this->appendChild($f);\r | |
56 | } else {\r | |
57 | // $value is probably ill-formed\r | |
58 | $f = new DOMDocument();\r | |
59 | $value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8');\r | |
60 | // Using <htmlfragment> will generate a warning, but so will bad HTML\r | |
61 | // (and by this point, bad HTML is what we've got).\r | |
62 | // We use it (and suppress the warning) because an HTML fragment will \r | |
63 | // be wrapped around <html><body> tags which we don't really want to keep.\r | |
64 | // Note: despite the warning, if loadHTML succeeds it will return true.\r | |
65 | $result = @$f->loadHTML('<htmlfragment>'.$value.'</htmlfragment>');\r | |
66 | if ($result) {\r | |
67 | $import = $f->getElementsByTagName('htmlfragment')->item(0);\r | |
68 | foreach ($import->childNodes as $child) {\r | |
69 | $importedNode = $this->ownerDocument->importNode($child, true);\r | |
70 | $this->appendChild($importedNode);\r | |
71 | }\r | |
72 | } else {\r | |
73 | // oh well, we tried, we really did. :(\r | |
74 | // this element is now empty\r | |
75 | }\r | |
76 | }\r | |
77 | }\r | |
78 | } else {\r | |
79 | $trace = debug_backtrace();\r | |
80 | trigger_error('Undefined property via __set(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);\r | |
81 | }\r | |
82 | }\r | |
83 | \r | |
84 | /**\r | |
85 | * Used for getting innerHTML like it's done in JavaScript:\r | |
86 | * @code\r | |
87 | * $string = $div->innerHTML;\r | |
88 | * @endcode\r | |
89 | */ \r | |
90 | public function __get($name)\r | |
91 | {\r | |
92 | if ($name == 'innerHTML') {\r | |
93 | $inner = '';\r | |
94 | foreach ($this->childNodes as $child) {\r | |
95 | $inner .= $this->ownerDocument->saveXML($child);\r | |
96 | }\r | |
97 | return $inner;\r | |
98 | }\r | |
99 | \r | |
100 | $trace = debug_backtrace();\r | |
101 | trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);\r | |
102 | return null;\r | |
103 | }\r | |
104 | \r | |
105 | public function __toString()\r | |
106 | {\r | |
107 | return '['.$this->tagName.']';\r | |
108 | }\r | |
109 | }\r | |
110 | ?> |