PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 3.75.0
MailPoet – Newsletters, Email Marketing, and Automation v3.75.0
5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib-3rd-party / pquery / gan_formatter.php
mailpoet / lib-3rd-party / pquery Last commit date
third_party 4 years ago IQuery.php 4 years ago LICENSE 4 years ago gan_formatter.php 4 years ago gan_node_html.php 4 years ago gan_parser_html.php 4 years ago gan_selector_html.php 4 years ago gan_tokenizer.php 4 years ago gan_xml2array.php 4 years ago ganon.php 4 years ago index.php 4 years ago pQuery.php 4 years ago
gan_formatter.php
383 lines
1 <?php
2 /**
3 * @author Niels A.D.
4 * @author Todd Burry <todd@vanillaforums.com>
5 * @copyright 2010 Niels A.D., 2014 Todd Burry
6 * @license http://opensource.org/licenses/LGPL-2.1 LGPL-2.1
7 * @package pQuery
8 */
9
10 namespace MailPoetVendor\pQuery;
11
12 if (!defined('ABSPATH')) exit;
13
14
15 /**
16 * Indents text
17 * @param string $text
18 * @param int $indent
19 * @param string $indent_string
20 * @return string
21 */
22 function indent_text($text, $indent, $indent_string = ' ') {
23 if ($indent && $indent_string) {
24 return str_replace("\n", "\n".str_repeat($indent_string, $indent), $text);
25 } else {
26 return $text;
27 }
28 }
29
30 /**
31 * Class used to format/minify HTML nodes
32 *
33 * Used like:
34 * <code>
35 * <?php
36 * $formatter = new HtmlFormatter();
37 * $formatter->format($root);
38 * ?>
39 * </code>
40 */
41 class HtmlFormatter {
42
43 /**
44 * Determines which elements start on a new line and which function as block
45 * @var array('element' => array('new_line' => true, 'as_block' => true, 'format_inside' => true))
46 */
47 var $block_elements = array(
48 'p' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
49 'h1' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
50 'h2' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
51 'h3' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
52 'h4' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
53 'h5' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
54 'h6' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
55
56 'form' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
57 'fieldset' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
58 'legend' => array('new_line' => true, 'as_block' => false, 'format_inside' => true),
59 'dl' => array('new_line' => true, 'as_block' => false, 'format_inside' => true),
60 'dt' => array('new_line' => true, 'as_block' => false, 'format_inside' => true),
61 'dd' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
62 'ol' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
63 'ul' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
64 'li' => array('new_line' => true, 'as_block' => false, 'format_inside' => true),
65
66 'table' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
67 'tr' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
68
69 'dir' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
70 'menu' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
71 'address' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
72 'blockquote' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
73 'center' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
74 'del' => array('new_line' => true, 'as_block' => false, 'format_inside' => true),
75 //'div' => array('new_line' => false, 'as_block' => true, 'format_inside' => true),
76 'hr' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
77 'ins' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
78 'noscript' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
79 'pre' => array('new_line' => true, 'as_block' => true, 'format_inside' => false),
80 'script' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
81 'style' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
82
83 'html' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
84 'head' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
85 'body' => array('new_line' => true, 'as_block' => true, 'format_inside' => true),
86 'title' => array('new_line' => true, 'as_block' => false, 'format_inside' => false)
87 );
88
89 /**
90 * Determines which characters are considered whitespace
91 * @var array("\t" => true) True to recognize as new line
92 */
93 var $whitespace = array(
94 ' ' => false,
95 "\t" => false,
96 "\x0B" => false,
97 "\0" => false,
98 "\n" => true,
99 "\r" => true
100 );
101
102 /**
103 * String that is used to generate correct indenting
104 * @var string
105 */
106 var $indent_string = ' ';
107
108 /**
109 * String that is used to break lines
110 * @var string
111 */
112 var $linebreak_string = "\n";
113
114 /**
115 * Other formatting options
116 * @var array
117 */
118 public $options = array(
119 'img_alt' => '',
120 'self_close_str' => null,
121 'attribute_shorttag' => false,
122 'sort_attributes' => false,
123 'attributes_case' => CASE_LOWER,
124 'minify_script' => true
125 );
126
127 /**
128 * Errors found during formatting
129 * @var array
130 */
131 var $errors = array();
132
133
134 /**
135 * Class constructor
136 * @param array $options {@link $options}
137 */
138 function __construct($options = array()) {
139 $this->options = array_merge($this->options, $options);
140
141 if (isset($options['indent_str']))
142 $this->indent_string = $options['indent_str'];
143
144 if (isset($options['linebreak_str']))
145 $this->linebreak_string = $options['linebreak_str'];
146 }
147
148 #php4 PHP4 class constructor compatibility
149 #function HtmlFormatter($options = array()) {return $this->__construct($options);}
150 #php4e
151
152 /**
153 * Class magic invoke method, performs {@link format()}
154 * @access private
155 */
156 function __invoke(&$node) {
157 return $this->format($node);
158 }
159
160 /**
161 * Minifies HTML / removes unneeded whitespace
162 * @param DomNode $root
163 * @param bool $strip_comments
164 * @param bool $recursive
165 */
166 static function minify_html(&$root, $strip_comments = true, $recursive = true) {
167 if ($strip_comments) {
168 foreach($root->select(':comment', false, $recursive, true) as $c) {
169 $prev = $c->getSibling(-1);
170 $next = $c->getSibling(1);
171 $c->delete();
172 if ($prev && $next && ($prev->isText()) && ($next->isText())) {
173 $prev->text .= $next->text;
174 $next->delete();
175 }
176 }
177 }
178 foreach($root->select('(!pre + !xmp + !style + !script + !"?php" + !"~text~" + !"~comment~"):not-empty > "~text~"', false, $recursive, true) as $c) {
179 $c->text = preg_replace('`\s+`', ' ', $c->text);
180 }
181 }
182
183 /**
184 * Minifies javascript using JSMin+
185 * @param DomNode $root
186 * @param string $indent_string
187 * @param bool $wrap_comment Wrap javascript in HTML comments (<!-- ~text~ //-->)
188 * @param bool $recursive
189 * @return bool|array Array of errors on failure, true on succes
190 */
191 static function minify_javascript(&$root, $indent_string = ' ', $wrap_comment = true, $recursive = true) {
192 #php4 JSMin+ doesn't support PHP4
193 #return true;
194 #php4e
195 #php5
196 include_once('third_party/jsminplus.php');
197
198 $errors = array();
199 foreach($root->select('script:not-empty > "~text~"', false, $recursive, true) as $c) {
200 try {
201 $text = $c->text;
202 while ($text) {
203 $text = trim($text);
204 //Remove comment/CDATA tags at begin and end
205 if (substr($text, 0, 4) === '<!--') {
206 $text = substr($text, 5);
207 continue;
208 } elseif (strtolower(substr($text, 0, 9)) === '<![cdata[') {
209 $text = substr($text, 10);
210 continue;
211 }
212
213 if (($end = substr($text, -3)) && (($end === '-->') || ($end === ']]>'))) {
214 $text = substr($text, 0, -3);
215 continue;
216 }
217
218 break;
219 }
220
221 if (trim($text)) {
222 $text = JSMinPlus::minify($text);
223 if ($wrap_comment) {
224 $text = "<!--\n".$text."\n//-->";
225 }
226 if ($indent_string && ($wrap_comment || (strpos($text, "\n") !== false))) {
227 $text = indent_text("\n".$text, $c->indent(), $indent_string);
228 }
229 }
230 $c->text = $text;
231 } catch (\Exception $e) {
232 $errors[] = array($e, $c->parent->dumpLocation());
233 }
234 }
235
236 return (($errors) ? $errors : true);
237 #php5e
238 }
239
240 /**
241 * Formats HTML
242 * @param DomNode $root
243 * @param bool $recursive
244 * @access private
245 */
246 function format_html(&$root, $recursive = null) {
247 if ($recursive === null) {
248 $recursive = true;
249 self::minify_html($root);
250 } elseif (is_int($recursive)) {
251 $recursive = (($recursive > 1) ? $recursive - 1 : false);
252 }
253
254 $root_tag = strtolower($root->tag);
255 $in_block = isset($this->block_elements[$root_tag]) && $this->block_elements[$root_tag]['as_block'];
256 $child_count = count($root->children);
257
258 if (isset($this->options['attributes_case']) && $this->options['attributes_case']) {
259 $root->attributes = array_change_key_case($root->attributes, $this->options['attributes_case']);
260 $root->attributes_ns = null;
261 }
262
263 if (isset($this->options['sort_attributes']) && $this->options['sort_attributes']) {
264 if ($this->options['sort_attributes'] === 'reverse') {
265 krsort($root->attributes);
266 } else {
267 ksort($root->attributes);
268 }
269 }
270
271 if ($root->select(':element', true, false, true)) {
272 $root->setTag(strtolower($root->tag), true);
273 if (($this->options['img_alt'] !== null) && ($root_tag === 'img') && (!isset($root->alt))) {
274 $root->setAttribute('alt', $this->options['img_alt']);
275 }
276 }
277 if ($this->options['self_close_str'] !== null) {
278 $root->self_close_str = $this->options['self_close_str'];
279 }
280 if ($this->options['attribute_shorttag'] !== null) {
281 $root->attribute_shorttag = $this->options['attribute_shorttag'];
282 }
283
284 $prev = null;
285 $n_tag = '';
286 // $prev_tag = '';
287 $as_block = false;
288 $prev_asblock = false;
289 for($i = 0; $i < $child_count; $i++) {
290 $n =& $root->children[$i];
291 $indent = $n->indent();
292
293 if (!$n->isText()) {
294 $n_tag = strtolower($n->tag);
295 $new_line = isset($this->block_elements[$n_tag]) && $this->block_elements[$n_tag]['new_line'];
296 $as_block = isset($this->block_elements[$n_tag]) && $this->block_elements[$n_tag]['as_block'];
297 $format_inside = ((!isset($this->block_elements[$n_tag])) || $this->block_elements[$n_tag]['format_inside']);
298
299 if ($prev && ($prev->isText()) && $prev->text && ($char = $prev->text[strlen($prev->text) - 1]) && isset($this->whitespace[$char])) {
300 if ($this->whitespace[$char]) {
301 $prev->text .= str_repeat($this->indent_string, $indent);
302 } else {
303 $prev->text = substr_replace($prev->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), -1, 1);
304 }
305 } elseif (($new_line || $prev_asblock || ($in_block && ($i === 0)))){
306 if ($prev && ($prev->isText())) {
307 $prev->text .= $this->linebreak_string.str_repeat($this->indent_string, $indent);
308 } else {
309 $root->addText($this->linebreak_string.str_repeat($this->indent_string, $indent), $i);
310 ++$child_count;
311 }
312 }
313
314 if ($format_inside && count($n->children)) {
315 //$last = end($n->children);
316 $last = $n->children[count($n->children) - 1];
317 $last_tag = ($last) ? strtolower($last->tag) : '';
318 $last_asblock = ($last_tag && isset($this->block_elements[$last_tag]) && $this->block_elements[$last_tag]['as_block']);
319
320 if (($n->childCount(true) > 0) || (trim($n->getPlainText()))) {
321 if ($last && ($last->isText()) && $last->text && ($char = $last->text[strlen($last->text) - 1]) && isset($this->whitespace[$char])) {
322 if ($as_block || ($last->index() > 0) || isset($this->whitespace[$last->text[0]])) {
323 if ($this->whitespace[$char]) {
324 $last->text .= str_repeat($this->indent_string, $indent);
325 } else {
326 $last->text = substr_replace($last->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), -1, 1);
327 }
328 }
329 } elseif (($as_block || $last_asblock || ($in_block && ($i === 0))) && $last) {
330 if ($last && ($last->isText())) {
331 $last->text .= $this->linebreak_string.str_repeat($this->indent_string, $indent);
332 } else {
333 $n->addText($this->linebreak_string.str_repeat($this->indent_string, $indent));
334 }
335 }
336 } elseif (!trim($n->getInnerText())) {
337 $n->clear();
338 }
339
340 if ($recursive) {
341 $this->format_html($n, $recursive);
342 }
343 }
344
345 } elseif (trim($n->text) && ((($i - 1 < $child_count) && ($char = $n->text[0]) && isset($this->whitespace[$char])) || ($in_block && ($i === 0)))) {
346 if (isset($this->whitespace[$char])) {
347 if ($this->whitespace[$char]) {
348 $n->text = str_repeat($this->indent_string, $indent).$n->text;
349 } else {
350 $n->text = substr_replace($n->text, $this->linebreak_string.str_repeat($this->indent_string, $indent), 0, 1);
351 }
352 } else {
353 $n->text = $this->linebreak_string.str_repeat($this->indent_string, $indent).$n->text;
354 }
355 }
356
357 $prev = $n;
358 // $prev_tag = $n_tag;
359 $prev_asblock = $as_block;
360 }
361
362 return true;
363 }
364
365 /**
366 * Formats HTML/Javascript
367 * @param DomNode $root
368 * @see format_html()
369 */
370 function format(&$node) {
371 $this->errors = array();
372 if ($this->options['minify_script']) {
373 $a = self::minify_javascript($node, $this->indent_string, true, true);
374 if (is_array($a)) {
375 foreach($a as $error) {
376 $this->errors[] = $error[0]->getMessage().' >>> '.$error[1];
377 }
378 }
379 }
380 return $this->format_html($node);
381 }
382 }
383