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