Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
PFragmentHandler
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 5
20
0.00% covered (danger)
0.00%
0 / 1
 sourceToFragment
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0
 processAttributeEmbeddedDom
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 lintHandler
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 domToSource
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 diffHandler
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Ext;
5
6use Wikimedia\Parsoid\DOM\DocumentFragment;
7use Wikimedia\Parsoid\DOM\Element;
8use Wikimedia\Parsoid\Fragments\PFragment;
9
10/**
11 * A Parsoid extension module may register handlers for one or more
12 * fragment generators.  Fragment generators can use parser function
13 * or (TODO: T390342) extension tag syntax.
14 *
15 * The only method which is generally required by all fragment
16 * generators is `sourceToFragment`.  All other methods have default
17 * do-nothing implementations; override them if you wish to implement
18 * those features.  Default implementations consistently return
19 * `false` to indicate not-implemented, since in some cases `null`
20 * would be a valid return value, and in other cases `null` would be a
21 * likely "accidental" return value which we'd like to catch and flag.
22 *
23 * PFragmentHandler supplies lazy (unexpanded) arguments using the
24 * Arguments interface.  Argument values can be evaluated eagerly
25 * (expanded) using PFragment::expand().  The Arguments interface
26 * provides for interpreting the argument list either as named or
27 * positional arguments, and provides a convenient way to access
28 * expanded and trimmed values.
29 *
30 * When using the extension tag syntax the arguments will be presented
31 * as if the equivalent {{#tag:...}}  function were invoked; in
32 * particular the tag contents will be presented as the first ordered
33 * argument, with attributes provided as named arguments following it.
34 *
35 * Note that the legacy parser presented arguments in lazy/unexpanded
36 * form for extension tag syntax but by default (unless
37 * SFH_OBJECT_ARGS was passed) presented arguments in eager/expanded
38 * form for parser function syntax.  The legacy parser also provided
39 * "named arguments" (ie attributes) for extension tag syntax, but
40 * only "positional arguments" for parser function syntax, although
41 * implementers often reimplemented named-argument parsing in their
42 * own code.
43 *
44 * Implementers should be aware of the historical convention that
45 * extension tag syntax corresponds to lazy/named/unexpanded and that
46 * parser function syntax corresponds to eager/positional/expanded,
47 * although the Arguments interface can provide both behaviors
48 * regardless of syntax.
49 */
50abstract class PFragmentHandler {
51
52    /**
53     * Convert an fragment generator's content to a PFragment.
54     * Note that the returned fragment may also contain metadata,
55     * collected via $extApi->getMetadata() (a ContentMetadataCollector).
56     * @param ParsoidExtensionAPI $extApi
57     * @param Arguments $arguments The arguments of
58     *  the fragment.
59     * @param bool $tagSyntax True if this PFragment handler was invoked using
60     *  extension tag syntax; false if parser function syntax was used
61     *  (including {{#tag:}}).
62     * @return PFragment|AsyncResult
63     *  - `PFragment` if returning some parsed content
64     *  - `AsyncResult` if the asynchronous source is "not ready yet"
65     *     to return content.
66     */
67    abstract public function sourceToFragment(
68        ParsoidExtensionAPI $extApi,
69        Arguments $arguments,
70        bool $tagSyntax
71    );
72
73    /**
74     * Extensions might embed HTML in attributes in their own custom
75     * representation (whether in data-mw or elsewhere).
76     *
77     * Core Parsoid will need a way to traverse such content. This method
78     * is a way for extension tag handlers to provide this functionality.
79     * Parsoid will only call this method if the tag's config sets the
80     * options['wt2html']['embedsDomInAttributes'] property to true.
81     *
82     * @param ParsoidExtensionAPI $extApi
83     * @param Element $elt The node whose data attributes need to be examined
84     * @param callable(DocumentFragment):bool $proc The processor that will
85     *        process the embedded HTML
86     *        Signature: (DocumentFragment) -> bool
87     *        This processor will be provided the DocumentFragment as input
88     *        and is expected to return true if the given fragment is modified.
89     * @return bool Whether or not changes were made to the embedded fragments
90     */
91    public function processAttributeEmbeddedDom(
92        ParsoidExtensionAPI $extApi, Element $elt, callable $proc
93    ): bool {
94        // Introduced in If14a86645b9feb5b3d9503e3037de403e588d65d
95        // Nothing to do by default
96        return false;
97    }
98
99    /**
100     * Lint handler for this fragment generator.
101     *
102     * If the fragment generator has lints it wants to expose, it should use $extApi
103     * to register those lints. Alternatively, the extension might simply
104     * inspect its DOM and invoke the default lint handler on a DOM tree
105     * that it wants inspected. For example, <ref> nodes often only have
106     * a pointer (the id attribute) to its content, and its lint handler would
107     * look up the DOM tree and invoke the default lint handler on that tree.
108     *
109     * @param ParsoidExtensionAPI $extApi
110     * @param Element $rootNode Extension content's root node
111     * @param callable $defaultHandler Default lint handler
112     *    - Default lint handler has signature $defaultHandler( Element $elt ): void
113     * @return bool Return `false` to indicate that this
114     *   extension has no special lint handler (the default lint handler will
115     *   be used.  Return `true` to indicate linting should proceed with the
116     *   next sibling.
117     */
118    public function lintHandler(
119        ParsoidExtensionAPI $extApi, Element $rootNode, callable $defaultHandler
120    ) {
121        /* Use default linter */
122        return false;
123    }
124
125    /**
126     * Serialize a DOM node created by this extension to wikitext.
127     * @param ParsoidExtensionAPI $extApi
128     * @param Element $node
129     * @param bool $wrapperUnmodified
130     * @param ?bool $tagSyntax True if using extension tag syntax, false to
131     *  use parser function syntax, null allows implementer to choose.
132     * @return string|false Return false to use the default serialization.
133     */
134    public function domToSource(
135        ParsoidExtensionAPI $extApi, Element $node,
136        bool $wrapperUnmodified, ?bool $tagSyntax
137    ) {
138        // TODO (T390343)
139        /* Use default serialization */
140        return false;
141    }
142
143    /**
144     * XXX: Experimental
145     *
146     * Call $domDiff on corresponding subtrees of $origNode and $editedNode
147     *
148     * @param ParsoidExtensionAPI $extApi
149     * @param callable $domDiff
150     * @param Element $origNode
151     * @param Element $editedNode
152     * @return bool
153     */
154    public function diffHandler(
155        ParsoidExtensionAPI $extApi, callable $domDiff, Element $origNode,
156        Element $editedNode
157    ): bool {
158        return false;
159    }
160}
161/** @deprecated */
162class_alias( PFragmentHandler::class, '\Wikimedia\Parsoid\Ext\FragmentHandler' );