C:\xampp\htdocs\landing\wp-content\updraft\plugins-old\amp\includes\utils\class-amp-dom-utils.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
<?php
/**
 * Class AMP_DOM_Utils.
 *
 * @package AMP
 */

use AmpProject\Dom\Document;
use 
AmpProject\Tag;

/**
 * Class AMP_DOM_Utils
 *
 * Functionality to simplify working with Dom\Documents and DOMElements.
 *
 * @internal
 */
class AMP_DOM_Utils {

    
/**
     * Attribute prefix for AMP-bind data attributes.
     *
     * @since 1.2.1
     * @deprecated Use AmpProject\Dom\Document::AMP_BIND_DATA_ATTR_PREFIX instead.
     * @internal
     * @var string
     */
    
const AMP_BIND_DATA_ATTR_PREFIX Document::AMP_BIND_DATA_ATTR_PREFIX;

    
/**
     * Regular expression pattern to match events and actions within an 'on' attribute.
     *
     * @since 1.4.0
     * @var string
     */
    
const AMP_EVENT_ACTIONS_REGEX_PATTERN '/((?<event>[^:;]+):(?<actions>(?:[^;,\(]+(?:\([^\)]+\))?,?)+))+?/';

    
/**
     * Regular expression pattern to match individual actions within an event.
     *
     * @since 1.4.0
     * @var string
     */
    
const AMP_ACTION_REGEX_PATTERN '/(?<action>[^(),\s]+(?:\([^\)]+\))?)+/';

    
/**
     * Regular expression pattern to match the contents of the <body> element.
     *
     * @since 1.5.0
     * @var string
     */
    
const HTML_BODY_CONTENTS_PATTERN '#^.*?<body.*?>(.*)</body>.*?$#si';

    
/**
     * Return a valid Dom\Document representing HTML document passed as a parameter.
     *
     * @since 0.7
     * @see AMP_DOM_Utils::get_content_from_dom_node()
     * @codeCoverageIgnore
     * @deprecated Use AmpProject\Dom\Document::fromHtml( $html, $encoding ) instead.
     *
     * @param string $document Valid HTML document to be represented by a Dom\Document.
     * @param string $encoding Optional. Encoding to use for the content.
     * @return Document|false Returns Dom\Document, or false if conversion failed.
     */
    
public static function get_dom$document$encoding null ) {
        
_deprecated_function__METHOD__'1.5.0''AmpProject\Dom\Document::fromHtml()' );
        return 
Document::fromHtml$document$encoding );
    }

    
/**
     * Determine whether a node can be in the head.
     *
     * @link https://github.com/ampproject/amphtml/blob/445d6e3be8a5063e2738c6f90fdcd57f2b6208be/validator/engine/htmlparser.js#L83-L100
     * @link https://www.w3.org/TR/html5/document-metadata.html
     * @codeCoverageIgnore
     * @deprecated Use AmpProject\Dom\Document->isValidHeadNode() instead.
     *
     * @param DOMNode $node Node.
     * @return bool Whether valid head node.
     */
    
public static function is_valid_head_nodeDOMNode $node ) {
        
_deprecated_function__METHOD__'1.5.0''AmpProject\Dom\Document->isValidHeadNode()' );
        return 
Document::fromNode$node )->isValidHeadNode$node );
    }

    
/**
     * Get attribute prefix for converted amp-bind attributes.
     *
     * This contains a random string to prevent HTML content containing this data- attribute
     * originally from being mutated to contain an amp-bind attribute when attributes are restored.
     *
     * @since 0.7
     * @see \AMP_DOM_Utils::convert_amp_bind_attributes()
     * @see \AMP_DOM_Utils::restore_amp_bind_attributes()
     * @codeCoverageIgnore
     * @deprecated Use AmpProject\Dom\Document::AMP_BIND_DATA_ATTR_PREFIX instead.
     * @link https://www.ampproject.org/docs/reference/components/amp-bind
     *
     * @return string HTML5 data-* attribute name prefix for AMP binding attributes.
     */
    
public static function get_amp_bind_placeholder_prefix() {
        
_deprecated_function__METHOD__'1.2.1' );
        return 
Document::AMP_BIND_DATA_ATTR_PREFIX;
    }

    
/**
     * Replace AMP binding attributes with something that libxml can parse (as HTML5 data-* attributes).
     *
     * This is necessary because attributes in square brackets are not understood in PHP and
     * get dropped with an error raised:
     * > Warning: DOMDocument::loadHTML(): error parsing attribute name
     * This is a reciprocal function of AMP_DOM_Utils::restore_amp_bind_attributes().
     *
     * @since 0.7
     * @codeCoverageIgnore
     * @deprecated This is handled automatically via AmpProject\Dom\Document.
     * @internal
     * @see \AMP_DOM_Utils::convert_amp_bind_attributes()
     * @link https://www.ampproject.org/docs/reference/components/amp-bind
     *
     * @param string $html HTML containing amp-bind attributes.
     * @return string HTML with AMP binding attributes replaced with HTML5 data-* attributes.
     */
    
public static function convert_amp_bind_attributes$html ) {
        
_deprecated_function__METHOD__'1.5.0' );
        return 
$html;
    }

    
/**
     * Convert AMP bind-attributes back to their original syntax.
     *
     * This is a reciprocal function of AMP_DOM_Utils::convert_amp_bind_attributes().
     *
     * @since 0.7
     * @see \AMP_DOM_Utils::convert_amp_bind_attributes()
     * @codeCoverageIgnore
     * @deprecated This is handled automatically via AmpProject\Dom\Document.
     * @internal
     * @link https://www.ampproject.org/docs/reference/components/amp-bind
     *
     * @param string $html HTML with amp-bind attributes converted.
     * @return string HTML with amp-bind attributes restored.
     */
    
public static function restore_amp_bind_attributes$html ) {
        
_deprecated_function__METHOD__'1.2.1' );
        return 
$html;
    }

    
/**
     * Return a valid Dom\Document representing arbitrary HTML content passed as a parameter.
     *
     * @see Reciprocal function get_content_from_dom()
     *
     * @since 0.2
     *
     * @param string $content  Valid HTML content to be represented by a Dom\Document.
     * @param string $encoding Optional. Encoding to use for the content. Defaults to `get_bloginfo( 'charset' )`.
     *
     * @return Document|false Returns a DOM document, or false if conversion failed.
     */
    
public static function get_dom_from_content$content$encoding null ) {
        
// Detect encoding from the current WordPress installation.
        
if ( null === $encoding ) {
            
$encoding get_bloginfo'charset' );
        }

        
/*
         * Wrap in dummy tags, since XML needs one parent node.
         * It also makes it easier to loop through nodes.
         * We can later use this to extract our nodes.
         */
        
$document "<html><head></head><body>{$content}</body></html>";

        return 
Document::fromHtml$document$encoding );
    }

    
/**
     * Return valid HTML *body* content extracted from the Dom\Document passed as a parameter.
     *
     * @since 0.2
     * @see AMP_DOM_Utils::get_content_from_dom_node() Reciprocal function.
     *
     * @param Document $dom Represents an HTML document from which to extract HTML content.
     * @return string Returns the HTML content of the body element represented in the Dom\Document.
     */
    
public static function get_content_from_domDocument $dom ) {
        return 
preg_replace(
            static::
HTML_BODY_CONTENTS_PATTERN,
            
'$1',
            
$dom->saveHTML$dom->body )
        );
    }

    
/**
     * Return valid HTML content extracted from the DOMNode passed as a parameter.
     *
     * @since 0.6
     * @see AMP_DOM_Utils::get_dom() Where the operations in this method are mirrored.
     * @see AMP_DOM_Utils::get_content_from_dom() Reciprocal function.
     * @codeCoverageIgnore
     * @deprecated Use Dom\Document->saveHtml( $node ) instead.
     *
     * @param Document   $dom  Represents an HTML document.
     * @param DOMElement $node Represents an HTML element of the $dom from which to extract HTML content.
     * @return string Returns the HTML content represented in the DOMNode
     */
    
public static function get_content_from_dom_nodeDocument $dom$node ) {
        
_deprecated_function__METHOD__'1.5.0''AmpProject\Dom\Document::saveHtml()' );
        return 
$dom->saveHTML$node );
    }

    
/**
     * Create a new node w/attributes (a DOMElement) and add to the passed Dom\Document.
     *
     * @since 0.2
     *
     * @param Document $dom        A representation of an HTML document to add the new node to.
     * @param string   $tag        A valid HTML element tag for the element to be added.
     * @param string[] $attributes One of more valid attributes for the new node.
     *
     * @return DOMElement|false The DOMElement for the given $tag, or false on failure
     */
    
public static function create_nodeDocument $dom$tag$attributes ) {
        
$node $dom->createElement$tag );
        
self::add_attributes_to_node$node$attributes );

        return 
$node;
    }

    
/**
     * Extract a DOMElement node's HTML element attributes and return as an array.
     *
     * @since 0.2
     *
     * @param DOMElement $node Represents an HTML element for which to extract attributes.
     *
     * @return string[] The attributes for the passed node, or an
     *                  empty array if it has no attributes.
     */
    
public static function get_node_attributes_as_assoc_array$node ) {
        
$attributes = [];
        if ( ! 
$node->hasAttributes() ) {
            return 
$attributes;
        }

        foreach ( 
$node->attributes as $attribute ) {
            
$attributes$attribute->nodeName ] = $attribute->nodeValue;
        }

        return 
$attributes;
    }

    
/**
     * Add one or more HTML element attributes to a node's DOMElement.
     *
     * @since 0.2
     *
     * @param DOMElement $node       Represents an HTML element.
     * @param string[]   $attributes One or more attributes for the node's HTML element.
     */
    
public static function add_attributes_to_node$node$attributes ) {
        foreach ( 
$attributes as $name => $value ) {
            try {
                
$node->setAttribute$name$value );
            } catch ( 
DOMException $e ) {
                
/*
                 * Catch a "Invalid Character Error" when libxml is able to parse attributes with invalid characters,
                 * but it throws error when attempting to set them via DOM methods. For example, '...this' can be parsed
                 * as an attribute but it will throw an exception when attempting to setAttribute().
                 */
                
continue;
            }
        }
    }

    
/**
     * Determines if a DOMElement's node is empty or not..
     *
     * @since 0.2
     *
     * @param DOMElement $node Represents an HTML element.
     * @return bool Returns true if the DOMElement has no child nodes and
     *              the textContent property of the DOMElement is empty;
     *              Otherwise it returns false.
     */
    
public static function is_node_empty$node ) {
        return 
false === $node->hasChildNodes() && empty( $node->textContent );
    }

    
/**
     * Forces HTML element closing tags given a Dom\Document and optional DOMElement.
     *
     * @since 0.2
     * @codeCoverageIgnore
     * @deprecated
     * @internal
     *
     * @param Document   $dom  Represents HTML document on which to force closing tags.
     * @param DOMElement $node Represents HTML element to start closing tags on.
     *                         If not passed, defaults to first child of body.
     */
    
public static function recursive_force_closing_tags$dom$node null ) {
        
_deprecated_function__METHOD__'0.7' );

        if ( 
null === $node ) {
            
$node $dom->body;
        }

        if ( 
XML_ELEMENT_NODE !== $node->nodeType ) {
            return;
        }

        if ( 
self::is_self_closing_tag$node->nodeName ) ) {
            
/*
             * Ensure there is no text content to accidentally force a child
             */
            
$node->textContent '';
            return;
        }

        if ( 
self::is_node_empty$node ) ) {
            
$text_node $dom->createTextNode'' );
            
$node->appendChild$text_node );

            return;
        }

        
$num_children $node->childNodes->length;
        for ( 
$i $num_children 1$i >= 0$i -- ) {
            
$child $node->childNodes->item$i );
            
self::recursive_force_closing_tags$dom$child );
        }

    }

    
/**
     * Determines if an HTML element tag is validly a self-closing tag per W3C HTML5 specs.
     *
     * @since 0.2
     *
     * @param string $tag Tag.
     * @return bool Returns true if a valid self-closing tag, false if not.
     */
    
private static function is_self_closing_tag$tag ) {
        return 
in_arraystrtolower$tag ), Tag::SELF_CLOSING_TAGStrue );
    }

    
/**
     * Check whether a given element has a specific class.
     *
     * @since 1.4.0
     *
     * @param DOMElement $element Element to check the classes of.
     * @param string     $class   Class to check for.
     * @return bool Whether the element has the requested class.
     */
    
public static function has_classDOMElement $element$class ) {
        if ( ! 
$element->hasAttribute'class' ) ) {
            return 
false;
        }

        
$classes $element->getAttribute'class' );

        return 
in_array$classpreg_split'/\s/'$classes ), true );
    }

    
/**
     * Get the ID for an element.
     *
     * If the element does not have an ID, create one first.
     *
     * @since 1.4.0
     * @since 1.5.1 Deprecated for AmpProject\Dom\Document::getElementId()
     *
     * @deprecated Use AmpProject\Dom\Document::getElementId() instead.
     *
     * @param DOMElement $element Element to get the ID for.
     * @param string     $prefix  Optional. Defaults to 'amp-wp-id'.
     * @return string ID to use.
     */
    
public static function get_element_id$element$prefix 'amp-wp-id' ) {
        
_deprecated_function(
            
'AMP_DOM_Utils::get_element_id',
            
'1.5.1',
            
'Use AmpProject\Amp\Dom\Document::getElementId() instead'
        
);

        return 
Document::fromNode$element )->getElementId$element$prefix );
    }

    
/**
     * Register an AMP action to an event on a given element.
     *
     * If the element already contains one or more events or actions, the method
     * will assemble them in a smart way.
     *
     * @since 1.4.0
     *
     * @param DOMElement $element Element to add an action to.
     * @param string     $event   Event to trigger the action on.
     * @param string     $action  Action to add.
     */
    
public static function add_amp_actionDOMElement $element$event$action ) {
        
$event_action_string "{$event}:{$action}";

        if ( ! 
$element->hasAttribute'on' ) ) {
            
// There's no "on" attribute yet, so just add it and be done.
            
$element->setAttribute'on'$event_action_string );
            return;
        }

        
$element->setAttribute(
            
'on',
            
self::merge_amp_actions(
                
$element->getAttribute'on' ),
                
$event_action_string
            
)
        );
    }

    
/**
     * Merge two sets of AMP events & actions.
     *
     * @since 1.4.0
     *
     * @param string $first  First event/action string.
     * @param string $second First event/action string.
     * @return string Merged event/action string.
     */
    
public static function merge_amp_actions$first$second ) {
        
$events = [];
        foreach ( [ 
$first$second ] as $event_action_string ) {
            
$matches = [];
            
$results preg_match_allself::AMP_EVENT_ACTIONS_REGEX_PATTERN$event_action_string$matches );

            if ( ! 
$results || ! isset( $matches['event'] ) ) {
                continue;
            }

            foreach ( 
$matches['event'] as $index => $event ) {
                
$events$event ][] = $matches['actions'][ $index ];
            }
        }

        
$value_strings = [];
        foreach ( 
$events as $event => $action_strings_array ) {
            
$actions_array = [];
            
array_walk(
                
$action_strings_array,
                static function ( 
$actions ) use ( &$actions_array ) {
                    
$matches = [];
                    
$results preg_match_allself::AMP_ACTION_REGEX_PATTERN$actions$matches );

                    if ( ! 
$results || ! isset( $matches['action'] ) ) {
                        
$actions_array[] = $actions;
                        return;
                    }

                    
$actions_array array_merge$actions_array$matches['action'] );
                }
            );

            
$actions         implode','array_uniquearray_filter$actions_array ) ) );
            
$value_strings[] = "{$event}:{$actions}";
        }

        return 
implode';'$value_strings );
    }

    
/**
     * Copy one or more attributes from one element to the other.
     *
     * @param array|string $attributes        Attribute name or array of attribute names to copy.
     * @param DOMElement   $from              DOM element to copy the attributes from.
     * @param DOMElement   $to                DOM element to copy the attributes to.
     * @param string       $default_separator Default separator to use for multiple values if the attribute is not known.
     */
    
public static function copy_attributes$attributesDOMElement $fromDOMElement $to$default_separator ',' ) {
        foreach ( (array) 
$attributes as $attribute ) {
            if ( 
$from->hasAttribute$attribute ) ) {
                
$values $from->getAttribute$attribute );
                if ( 
$to->hasAttribute$attribute ) ) {
                    switch ( 
$attribute ) {
                        case 
'on':
                            
$values self::merge_amp_actions$to->getAttribute$attribute ), $values );
                            break;
                        case 
'class':
                            
$values $to->getAttribute$attribute ) . ' ' $values;
                            break;
                        default:
                            
$values $to->getAttribute$attribute ) . $default_separator $values;
                    }
                }
                
$to->setAttribute$attribute$values );
            }
        }
    }
}
x

Windows NT KPTV 6.2 build 9200 (Windows Server 2012 Datacenter Edition) i586