Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/**
4
 * Represents an XHTML 1.1 module, with information on elements, tags
5
 * and attributes.
6
 * @note Even though this is technically XHTML 1.1, it is also used for
7
 *       regular HTML parsing. We are using modulization as a convenient
8
 *       way to represent the internals of HTMLDefinition, and our
9
 *       implementation is by no means conforming and does not directly
10
 *       use the normative DTDs or XML schemas.
11
 * @note The public variables in a module should almost directly
12
 *       correspond to the variables in HTMLPurifier_HTMLDefinition.
13
 *       However, the prefix info carries no special meaning in these
14
 *       objects (include it anyway if that's the correspondence though).
15
 * @todo Consider making some member functions protected
16
 */
17
 
18
class HTMLPurifier_HTMLModule
19
{
20
 
21
    // -- Overloadable ----------------------------------------------------
22
 
23
    /**
24
     * Short unique string identifier of the module.
25
     * @type string
26
     */
27
    public $name;
28
 
29
    /**
30
     * Informally, a list of elements this module changes.
31
     * Not used in any significant way.
32
     * @type array
33
     */
34
    public $elements = array();
35
 
36
    /**
37
     * Associative array of element names to element definitions.
38
     * Some definitions may be incomplete, to be merged in later
39
     * with the full definition.
40
     * @type array
41
     */
42
    public $info = array();
43
 
44
    /**
45
     * Associative array of content set names to content set additions.
46
     * This is commonly used to, say, add an A element to the Inline
47
     * content set. This corresponds to an internal variable $content_sets
48
     * and NOT info_content_sets member variable of HTMLDefinition.
49
     * @type array
50
     */
51
    public $content_sets = array();
52
 
53
    /**
54
     * Associative array of attribute collection names to attribute
55
     * collection additions. More rarely used for adding attributes to
56
     * the global collections. Example is the StyleAttribute module adding
57
     * the style attribute to the Core. Corresponds to HTMLDefinition's
58
     * attr_collections->info, since the object's data is only info,
59
     * with extra behavior associated with it.
60
     * @type array
61
     */
62
    public $attr_collections = array();
63
 
64
    /**
65
     * Associative array of deprecated tag name to HTMLPurifier_TagTransform.
66
     * @type array
67
     */
68
    public $info_tag_transform = array();
69
 
70
    /**
71
     * List of HTMLPurifier_AttrTransform to be performed before validation.
72
     * @type array
73
     */
74
    public $info_attr_transform_pre = array();
75
 
76
    /**
77
     * List of HTMLPurifier_AttrTransform to be performed after validation.
78
     * @type array
79
     */
80
    public $info_attr_transform_post = array();
81
 
82
    /**
83
     * List of HTMLPurifier_Injector to be performed during well-formedness fixing.
84
     * An injector will only be invoked if all of it's pre-requisites are met;
85
     * if an injector fails setup, there will be no error; it will simply be
86
     * silently disabled.
87
     * @type array
88
     */
89
    public $info_injector = array();
90
 
91
    /**
92
     * Boolean flag that indicates whether or not getChildDef is implemented.
93
     * For optimization reasons: may save a call to a function. Be sure
94
     * to set it if you do implement getChildDef(), otherwise it will have
95
     * no effect!
96
     * @type bool
97
     */
98
    public $defines_child_def = false;
99
 
100
    /**
101
     * Boolean flag whether or not this module is safe. If it is not safe, all
102
     * of its members are unsafe. Modules are safe by default (this might be
103
     * slightly dangerous, but it doesn't make much sense to force HTML Purifier,
104
     * which is based off of safe HTML, to explicitly say, "This is safe," even
105
     * though there are modules which are "unsafe")
106
     *
107
     * @type bool
108
     * @note Previously, safety could be applied at an element level granularity.
109
     *       We've removed this ability, so in order to add "unsafe" elements
110
     *       or attributes, a dedicated module with this property set to false
111
     *       must be used.
112
     */
113
    public $safe = true;
114
 
115
    /**
116
     * Retrieves a proper HTMLPurifier_ChildDef subclass based on
117
     * content_model and content_model_type member variables of
118
     * the HTMLPurifier_ElementDef class. There is a similar function
119
     * in HTMLPurifier_HTMLDefinition.
120
     * @param HTMLPurifier_ElementDef $def
121
     * @return HTMLPurifier_ChildDef subclass
122
     */
123
    public function getChildDef($def)
124
    {
125
        return false;
126
    }
127
 
128
    // -- Convenience -----------------------------------------------------
129
 
130
    /**
131
     * Convenience function that sets up a new element
132
     * @param string $element Name of element to add
133
     * @param string|bool $type What content set should element be registered to?
134
     *              Set as false to skip this step.
135
     * @param string|HTMLPurifier_ChildDef $contents Allowed children in form of:
136
     *              "$content_model_type: $content_model"
137
     * @param array|string $attr_includes What attribute collections to register to
138
     *              element?
139
     * @param array $attr What unique attributes does the element define?
140
     * @see HTMLPurifier_ElementDef:: for in-depth descriptions of these parameters.
141
     * @return HTMLPurifier_ElementDef Created element definition object, so you
142
     *         can set advanced parameters
143
     */
144
    public function addElement($element, $type, $contents, $attr_includes = array(), $attr = array())
145
    {
146
        $this->elements[] = $element;
147
        // parse content_model
148
        list($content_model_type, $content_model) = $this->parseContents($contents);
149
        // merge in attribute inclusions
150
        $this->mergeInAttrIncludes($attr, $attr_includes);
151
        // add element to content sets
152
        if ($type) {
153
            $this->addElementToContentSet($element, $type);
154
        }
155
        // create element
156
        $this->info[$element] = HTMLPurifier_ElementDef::create(
157
            $content_model,
158
            $content_model_type,
159
            $attr
160
        );
161
        // literal object $contents means direct child manipulation
162
        if (!is_string($contents)) {
163
            $this->info[$element]->child = $contents;
164
        }
165
        return $this->info[$element];
166
    }
167
 
168
    /**
169
     * Convenience function that creates a totally blank, non-standalone
170
     * element.
171
     * @param string $element Name of element to create
172
     * @return HTMLPurifier_ElementDef Created element
173
     */
174
    public function addBlankElement($element)
175
    {
176
        if (!isset($this->info[$element])) {
177
            $this->elements[] = $element;
178
            $this->info[$element] = new HTMLPurifier_ElementDef();
179
            $this->info[$element]->standalone = false;
180
        } else {
181
            trigger_error("Definition for $element already exists in module, cannot redefine");
182
        }
183
        return $this->info[$element];
184
    }
185
 
186
    /**
187
     * Convenience function that registers an element to a content set
188
     * @param string $element Element to register
189
     * @param string $type Name content set (warning: case sensitive, usually upper-case
190
     *        first letter)
191
     */
192
    public function addElementToContentSet($element, $type)
193
    {
194
        if (!isset($this->content_sets[$type])) {
195
            $this->content_sets[$type] = '';
196
        } else {
197
            $this->content_sets[$type] .= ' | ';
198
        }
199
        $this->content_sets[$type] .= $element;
200
    }
201
 
202
    /**
203
     * Convenience function that transforms single-string contents
204
     * into separate content model and content model type
205
     * @param string $contents Allowed children in form of:
206
     *                  "$content_model_type: $content_model"
207
     * @return array
208
     * @note If contents is an object, an array of two nulls will be
209
     *       returned, and the callee needs to take the original $contents
210
     *       and use it directly.
211
     */
212
    public function parseContents($contents)
213
    {
214
        if (!is_string($contents)) {
215
            return array(null, null);
216
        } // defer
217
        switch ($contents) {
218
            // check for shorthand content model forms
219
            case 'Empty':
220
                return array('empty', '');
221
            case 'Inline':
222
                return array('optional', 'Inline | #PCDATA');
223
            case 'Flow':
224
                return array('optional', 'Flow | #PCDATA');
225
        }
226
        list($content_model_type, $content_model) = explode(':', $contents);
227
        $content_model_type = strtolower(trim($content_model_type));
228
        $content_model = trim($content_model);
229
        return array($content_model_type, $content_model);
230
    }
231
 
232
    /**
233
     * Convenience function that merges a list of attribute includes into
234
     * an attribute array.
235
     * @param array $attr Reference to attr array to modify
236
     * @param array $attr_includes Array of includes / string include to merge in
237
     */
238
    public function mergeInAttrIncludes(&$attr, $attr_includes)
239
    {
240
        if (!is_array($attr_includes)) {
241
            if (empty($attr_includes)) {
242
                $attr_includes = array();
243
            } else {
244
                $attr_includes = array($attr_includes);
245
            }
246
        }
247
        $attr[0] = $attr_includes;
248
    }
249
 
250
    /**
251
     * Convenience function that generates a lookup table with boolean
252
     * true as value.
253
     * @param string $list List of values to turn into a lookup
254
     * @note You can also pass an arbitrary number of arguments in
255
     *       place of the regular argument
256
     * @return array array equivalent of list
257
     */
258
    public function makeLookup($list)
259
    {
260
        $args = func_get_args();
261
        if (is_string($list)) {
262
            $list = $args;
263
        }
264
        $ret = array();
265
        foreach ($list as $value) {
266
            if (is_null($value)) {
267
                continue;
268
            }
269
            $ret[$value] = true;
270
        }
271
        return $ret;
272
    }
273
 
274
    /**
275
     * Lazy load construction of the module after determining whether
276
     * or not it's needed, and also when a finalized configuration object
277
     * is available.
278
     * @param HTMLPurifier_Config $config
279
     */
280
    public function setup($config)
281
    {
282
    }
283
}
284
 
285
// vim: et sw=4 sts=4