31 use \IteratorAggregate;
32 use \ReverseArrayIterator;
75 self::HTML_NAMESPACE => [
76 'html' =>
true,
'head' =>
true,
'body' =>
true,
'frameset' =>
true,
78 'plaintext' =>
true,
'isindex' =>
true,
79 'xmp' =>
true,
'iframe' =>
true,
'noembed' =>
true,
80 'noscript' =>
true,
'script' =>
true,
86 self::HTML_NAMESPACE => [
87 'area' =>
true,
'base' =>
true,
'basefont' =>
true,
88 'bgsound' =>
true,
'br' =>
true,
'col' =>
true,
'command' =>
true,
89 'embed' =>
true,
'frame' =>
true,
'hr' =>
true,
'img' =>
true,
90 'input' =>
true,
'keygen' =>
true,
'link' =>
true,
'meta' =>
true,
91 'param' =>
true,
'source' =>
true,
'track' =>
true,
'wbr' =>
true
96 self::HTML_NAMESPACE => [
97 'pre' =>
true,
'textarea' =>
true,
'listing' =>
true,
102 self::HTML_NAMESPACE => [
103 'h1' =>
true,
'h2' =>
true,
'h3' =>
true,
104 'h4' =>
true,
'h5' =>
true,
'h6' =>
true
109 self::HTML_NAMESPACE => [
110 'address' =>
true,
'applet' =>
true,
'area' =>
true,
111 'article' =>
true,
'aside' =>
true,
'base' =>
true,
112 'basefont' =>
true,
'bgsound' =>
true,
'blockquote' =>
true,
113 'body' =>
true,
'br' =>
true,
'button' =>
true,
'caption' =>
true,
114 'center' =>
true,
'col' =>
true,
'colgroup' =>
true,
'dd' =>
true,
115 'details' =>
true,
'dir' =>
true,
'div' =>
true,
'dl' =>
true,
116 'dt' =>
true,
'embed' =>
true,
'fieldset' =>
true,
117 'figcaption' =>
true,
'figure' =>
true,
'footer' =>
true,
118 'form' =>
true,
'frame' =>
true,
'frameset' =>
true,
'h1' =>
true,
119 'h2' =>
true,
'h3' =>
true,
'h4' =>
true,
'h5' =>
true,
120 'h6' =>
true,
'head' =>
true,
'header' =>
true,
'hgroup' =>
true,
121 'hr' =>
true,
'html' =>
true,
'iframe' =>
true,
'img' =>
true,
122 'input' =>
true,
'isindex' =>
true,
'li' =>
true,
'link' =>
true,
123 'listing' =>
true,
'main' =>
true,
'marquee' =>
true,
124 'menu' =>
true,
'menuitem' =>
true,
'meta' =>
true,
'nav' =>
true,
125 'noembed' =>
true,
'noframes' =>
true,
'noscript' =>
true,
126 'object' =>
true,
'ol' =>
true,
'p' =>
true,
'param' =>
true,
127 'plaintext' =>
true,
'pre' =>
true,
'script' =>
true,
128 'section' =>
true,
'select' =>
true,
'source' =>
true,
129 'style' =>
true,
'summary' =>
true,
'table' =>
true,
130 'tbody' =>
true,
'td' =>
true,
'template' =>
true,
131 'textarea' =>
true,
'tfoot' =>
true,
'th' =>
true,
'thead' =>
true,
132 'title' =>
true,
'tr' =>
true,
'track' =>
true,
'ul' =>
true,
133 'wbr' =>
true,
'xmp' =>
true
135 self::SVG_NAMESPACE => [
136 'foreignobject' =>
true,
'desc' =>
true,
'title' =>
true
138 self::MATHML_NAMESPACE => [
139 'mi' =>
true,
'mo' =>
true,
'mn' =>
true,
'ms' =>
true,
140 'mtext' =>
true,
'annotation-xml' =>
true
145 self::HTML_NAMESPACE => [
146 'address' =>
true,
'div' =>
true,
'p' =>
true
151 self::HTML_NAMESPACE => [
152 'table' =>
true,
'thead' =>
true,
'tbody' =>
true,
153 'tfoot' =>
true,
'tr' =>
true
158 self::HTML_NAMESPACE => [
159 'dd' =>
true,
'dt' =>
true,
'li' =>
true,
'optgroup' =>
true,
160 'option' =>
true,
'p' =>
true,
'rb' =>
true,
'rp' =>
true,
161 'rt' =>
true,
'rtc' =>
true
166 self::HTML_NAMESPACE => [
167 'caption' =>
true,
'colgroup' =>
true,
'dd' =>
true,
'dt' =>
true,
168 'li' =>
true,
'optgroup' =>
true,
'option' =>
true,
'p' =>
true,
169 'rb' =>
true,
'rp' =>
true,
'rt' =>
true,
'rtc' =>
true,
170 'tbody' =>
true,
'td' =>
true,
'tfoot' =>
true,
'th' =>
true,
171 'thead' =>
true,
'tr' =>
true
176 self::HTML_NAMESPACE => [
177 'td' =>
true,
'th' =>
true
181 self::HTML_NAMESPACE => [
182 'table' =>
true,
'template' =>
true,
'html' =>
true
187 self::HTML_NAMESPACE => [
188 'tbody' =>
true,
'tfoot' =>
true,
'thead' =>
true,
189 'template' =>
true,
'html' =>
true
194 self::HTML_NAMESPACE => [
195 'tr' =>
true,
'template' =>
true,
'html' =>
true
201 self::HTML_NAMESPACE => [
202 'button' =>
true,
'fieldset' =>
true,
'input' =>
true,
203 'keygen' =>
true,
'object' =>
true,
'output' =>
true,
204 'select' =>
true,
'textarea' =>
true,
'img' =>
true
209 self::HTML_NAMESPACE => [
210 'applet' =>
true,
'caption' =>
true,
'html' =>
true,
211 'marquee' =>
true,
'object' =>
true,
212 'table' =>
true,
'td' =>
true,
'template' =>
true,
215 self::SVG_NAMESPACE => [
216 'foreignobject' =>
true,
'desc' =>
true,
'title' =>
true
218 self::MATHML_NAMESPACE => [
219 'mi' =>
true,
'mo' =>
true,
'mn' =>
true,
'ms' =>
true,
220 'mtext' =>
true,
'annotation-xml' =>
true
226 if ( self::$inListItemScopeSet === null ) {
227 self::$inListItemScopeSet = self::$inScopeSet;
228 self::$inListItemScopeSet[self::HTML_NAMESPACE][
'ol'] =
true;
229 self::$inListItemScopeSet[self::HTML_NAMESPACE][
'ul'] =
true;
231 return self::$inListItemScopeSet;
236 if ( self::$inButtonScopeSet === null ) {
237 self::$inButtonScopeSet = self::$inScopeSet;
238 self::$inButtonScopeSet[self::HTML_NAMESPACE][
'button'] =
true;
240 return self::$inButtonScopeSet;
244 self::HTML_NAMESPACE => [
245 'html' =>
true,
'table' =>
true,
'template' =>
true
250 self::HTML_NAMESPACE => [
251 'option' =>
true,
'optgroup' =>
true
256 self::MATHML_NAMESPACE => [
257 'mi' =>
true,
'mo' =>
true,
'mn' =>
true,
'ms' =>
true,
263 self::SVG_NAMESPACE => [
264 'foreignobject' =>
true,
272 self::HTML_NAMESPACE => [
273 'body' =>
true,
'blockquote' =>
true,
282 self::HTML_NAMESPACE => [
283 'a' =>
true,
'abbr' =>
true,
'acronym' =>
true,
'applet' =>
true,
284 'b' =>
true,
'basefont' =>
true,
'bdo' =>
true,
'big' =>
true,
285 'br' =>
true,
'button' =>
true,
'cite' =>
true,
'code' =>
true,
286 'dfn' =>
true,
'em' =>
true,
'font' =>
true,
'i' =>
true,
287 'iframe' =>
true,
'img' =>
true,
'input' =>
true,
'kbd' =>
true,
288 'label' =>
true,
'legend' =>
true,
'map' =>
true,
'object' =>
true,
289 'param' =>
true,
'q' =>
true,
'rb' =>
true,
'rbc' =>
true,
290 'rp' =>
true,
'rt' =>
true,
'rtc' =>
true,
'ruby' =>
true,
291 's' =>
true,
'samp' =>
true,
'select' =>
true,
'small' =>
true,
292 'span' =>
true,
'strike' =>
true,
'strong' =>
true,
'sub' =>
true,
293 'sup' =>
true,
'textarea' =>
true,
'tt' =>
true,
'u' =>
true,
379 $this->parent = null;
380 $this->children = [];
388 Assert::precondition(
389 $this->parent !==
'flat',
"Can't removeChild after flattening $this"
392 $elt->parent === $this,
'elt',
'must have $this as a parent'
394 $idx = array_search( $elt, $this->children,
true );
395 Assert::parameter( $idx !==
false,
'$elt',
'must be a child of $this' );
397 array_splice( $this->children, $idx, 1 );
406 Assert::precondition(
407 $this->parent !==
'flat',
"Can't insertBefore after flattening."
409 $idx = array_search( $a, $this->children,
true );
410 Assert::parameter( $idx !==
false,
'$a',
'must be a child of $this' );
411 if ( is_string( $b ) ) {
412 array_splice( $this->children, $idx, 0, [ $b ] );
414 Assert::parameter( $b->parent !==
'flat',
'$b',
"Can't be flat" );
415 if ( $b->parent !== null ) {
416 $b->parent->removeChild( $b );
418 array_splice( $this->children, $idx, 0, [ $b ] );
428 Assert::precondition(
429 $this->parent !==
'flat',
"Can't appendChild after flattening."
431 if ( is_string( $elt ) ) {
432 array_push( $this->children, $elt );
436 if ( $elt->parent !== null ) {
437 $elt->parent->removeChild( $elt );
439 array_push( $this->children, $elt );
440 $elt->parent = $this;
448 Assert::precondition(
449 $elt->parent !==
'flat',
"Can't adoptChildren after flattening."
451 foreach ( $elt->children
as $child ) {
452 if ( !is_string( $child ) ) {
455 $child->parent = null;
473 Assert::parameter( $this->parent !== null,
'$this',
'must be a child' );
474 Assert::parameter( $this->parent !==
'flat',
'$this',
'already flat' );
475 $idx = array_search( $this, $this->parent->children,
true );
477 $idx !==
false,
'$this',
'must be a child of its parent'
479 $tidyCompat = $config[
'tidyCompat'];
482 foreach ( $this->children
as $elt ) {
483 if ( !is_string( $elt ) ) {
484 $elt = $elt->flatten( $config );
486 if ( $blank && preg_match(
'/[^\t\n\f\r ]/', $elt ) ) {
491 $this->localName =
'p';
492 } elseif ( $blank ) {
495 if ( !count( $this->attribs ) &&
496 ( $this->localName ===
'tr' || $this->localName ===
'li' )
498 $this->attribs = [
'class' =>
"mw-empty-elt" ];
502 $flat = $blank ?
'' :
"{$this}";
506 $this->parent->children[$idx] = $flat;
507 $this->parent =
'flat';
522 $encAttribs .=
" $name=\"$encValue\"";
525 $out =
"<{$this->localName}{$encAttribs}>";
526 $len = strlen(
$out );
528 foreach ( $this->children
as $elt ) {
531 $out .=
"</{$this->localName}>";
538 $out = substr(
$out, 0, $len + 1 ) .
539 substr(
$out, $len );
542 $out =
"<{$this->localName}{$encAttribs} />";
544 count( $this->children ) === 0,
545 "Empty elements shouldn't have children."
561 public function isA( $set ) {
563 return $this === $set;
564 } elseif ( is_array( $set ) ) {
565 return isset( $set[$this->namespaceURI] ) &&
566 isset( $set[$this->namespaceURI][$this->localName] );
569 return $this->
isHtml() && $this->localName === $set;
580 && $this->localName === $tagName;
616 $this->localName ===
'annotation-xml' &&
617 isset( $this->attribs[
'encoding'] ) &&
618 ( strcasecmp( $this->attribs[
'encoding'],
'text/html' ) == 0 ||
619 strcasecmp( $this->attribs[
'encoding'],
'application/xhtml+xml' ) == 0 )
630 if ( $this->noahKey === null ) {
633 $this->noahKey =
serialize( [ $this->namespaceURI, $this->localName,
$attribs ] );
689 $this->currentNode = $this->elements[0];
701 foreach ( $this->elements[0]->children
as $elt ) {
702 $out .= is_string( $elt ) ? $elt :
703 $elt->flatten( $this->config );
726 $this->fosterParentMode &&
731 $this->config[
'tidyCompat'] && !$isComment &&
737 $this->currentNode->appendChild(
$value );
779 $this->currentNode->isHtmlNamed(
'mw:p-wrap' ) &&
786 $this->fosterParentMode &&
791 $this->currentNode->appendChild( $elt );
793 Assert::invariant( $elt->parent !== null,
"$elt must be in tree" );
794 Assert::invariant( $elt->parent !==
'flat',
"$elt must not have been previous flattened" );
795 array_push( $this->elements, $elt );
796 $this->currentNode = $elt;
849 foreach ( $this
as $elt ) {
850 if ( $elt->isA(
$tag ) ) {
868 foreach ( $this
as $elt ) {
869 if ( $elt->isA(
$tag ) ) {
872 if ( $elt->isA( $set ) ) {
886 $endTagSet = $thorough ?
889 while ( $this->currentNode ) {
890 if ( $butnot !== null && $this->currentNode->isHtmlNamed( $butnot ) ) {
893 if ( !$this->currentNode->isA( $endTagSet ) ) {
904 return ( $fragmentContext && count( $this->elements ) === 1 ) ?
924 return $this->elements[ $idx ];
933 Assert::precondition(
934 $this->elements[$idx]->parent !==
'flat',
935 'Replaced element should not have already been flattened.'
937 Assert::precondition(
938 $elt->parent !==
'flat',
939 'New element should not have already been flattened.'
941 $this->elements[$idx] = $elt;
942 if ( $idx === count( $this->elements ) - 1 ) {
943 $this->currentNode = $elt;
954 for ( $i = count( $this->elements ) - 1; $i >= 0; $i-- ) {
955 if ( $this->elements[$i]->isA(
$tag ) ) {
967 return count( $this->elements );
975 $elt = array_pop( $this->elements );
976 if ( count( $this->elements ) ) {
977 $this->currentNode = $this->elements[ count( $this->elements ) - 1 ];
979 $this->currentNode = null;
981 if ( !$elt->isHtmlNamed(
'mw:p-wrap' ) ) {
982 $elt->flatten( $this->config );
992 for ( $length = count( $this->elements ); $length > $idx; $length-- ) {
1004 while ( $this->currentNode ) {
1005 if ( $this->currentNode->isA(
$tag ) ) {
1020 for ( $length = count( $this->elements ); $length > 1; $length-- ) {
1021 if ( $this->currentNode->isA( $set ) ) {
1036 $elt->parent !==
'flat',
1038 '$elt should not already have been flattened.'
1041 $elt->parent->parent !==
'flat',
1043 'The parent of $elt should not already have been flattened.'
1045 $idx = array_search( $elt, $this->elements,
true );
1046 Assert::parameter( $idx !==
false,
'$elt',
'must be in stack' );
1047 array_splice( $this->elements, $idx, 1 );
1048 if ( $idx === count( $this->elements ) ) {
1049 $this->currentNode = $this->elements[$idx - 1];
1056 $elt->
flatten( $this->config );
1058 Assert::postcondition(
1059 array_search( $elt, $this->elements,
true ) ===
false,
1060 '$elt should no longer be in open elements stack'
1071 Assert::parameter( $idx !==
false,
'$a',
'must be in stack' );
1072 if ( $idx === count( $this->elements ) - 1 ) {
1073 array_push( $this->elements, $b );
1074 $this->currentNode = $b;
1076 array_splice( $this->elements, $idx + 1, 0, [ $b ] );
1090 $lastTable = $this->
indexOf(
'table' );
1091 $lastTemplate = $this->
indexOf(
'template' );
1095 if ( $lastTemplate >= 0 && ( $lastTable < 0 || $lastTemplate > $lastTable ) ) {
1096 $parent = $this->elements[$lastTemplate];
1097 } elseif ( $lastTable >= 0 ) {
1098 $parent = $this->elements[$lastTable]->parent;
1101 $parent !== null,
"All tables should have parents"
1103 $before = $this->elements[$lastTable];
1105 $parent = $this->elements[0];
1108 if ( $this->config[
'tidyCompat'] ) {
1109 if ( is_string( $elt ) ) {
1118 if ( $elt->isHtmlNamed(
'mw:p-wrap' ) ) {
1120 array_search( $before, $parent->children,
true ) :
1121 count( $parent->children );
1122 $after = $idx > 0 ? $parent->children[$idx - 1] :
'';
1134 $parent->insertBefore( $before, $elt );
1136 $parent->appendChild( $elt );
1157 $this->currentNode->isHtmlNamed(
$tag ) &&
1158 !$afe->isInList( $this->currentNode )
1166 for ( $outer = 0; $outer < 8; $outer++ ) {
1172 $fmtElt = $afe->findElementByTag(
$tag );
1183 $index = $this->
indexOf( $fmtElt );
1185 $afe->remove( $fmtElt );
1193 if ( !$this->
inScope( $fmtElt ) ) {
1201 $furthestBlock = null;
1202 $furthestBlockIndex = -1;
1203 $stackLength = $this->
length();
1204 for ( $i = $index+1; $i < $stackLength; $i++ ) {
1206 $furthestBlock = $this->
node( $i );
1207 $furthestBlockIndex = $i;
1218 if ( !$furthestBlock ) {
1219 $this->
popTag( $fmtElt );
1220 $afe->remove( $fmtElt );
1226 $ancestor = $this->
node( $index-1 );
1232 $BOOKMARK =
new BalanceElement(
'[bookmark]',
'[bookmark]', [] );
1233 $afe->insertAfter( $fmtElt, $BOOKMARK );
1236 $node = $furthestBlock;
1237 $lastNode = $furthestBlock;
1238 $nodeIndex = $furthestBlockIndex;
1242 for ( $inner = 1;
true; $inner++ ) {
1249 $node = $this->
node( --$nodeIndex );
1253 if ( $node === $fmtElt )
break;
1258 $isAFE = $afe->isInList( $node );
1259 if ( $inner > 3 && $isAFE ) {
1260 $afe->remove( $node );
1283 $node->namespaceURI, $node->localName, $node->attribs );
1284 $afe->replace( $node, $newElt );
1285 $this->
replaceAt( $nodeIndex, $newElt );
1291 if ( $lastNode === $furthestBlock ) {
1292 $afe->remove( $BOOKMARK );
1293 $afe->insertAfter( $newElt, $BOOKMARK );
1298 $node->appendChild( $lastNode );
1309 $this->fosterParentMode &&
1317 $ancestor->appendChild( $lastNode );
1324 $fmtElt->namespaceURI, $fmtElt->localName, $fmtElt->attribs );
1328 $newElt2->adoptChildren( $furthestBlock );
1331 $furthestBlock->appendChild( $newElt2 );
1337 $afe->remove( $fmtElt );
1338 $afe->replace( $BOOKMARK, $newElt2 );
1358 foreach ( $this->elements
as $elt ) {
1359 array_push( $r, $elt->localName );
1361 return implode( $r,
' ' );
1413 for ( $node = $this->head; $node; $node = $next ) {
1414 $next = $node->nextAFE;
1415 $node->prevAFE = $node->nextAFE = $node->nextNoah = null;
1417 $this->head = $this->tail = $this->noahTableStack = null;
1422 if ( $this->tail ) {
1423 $this->tail->nextAFE = $elt;
1429 $this->noahTableStack[] = [];
1439 if ( $elt->prevAFE !== null || $this->head === $elt ) {
1440 throw new ParameterAssertionException(
'$elt',
1441 'Cannot insert a node into the AFE list twice' );
1448 $table =& $this->noahTableStack[ count( $this->noahTableStack ) - 1 ];
1449 if ( !isset( $table[$noahKey] ) ) {
1450 $table[$noahKey] = $elt;
1454 while (
$tail->nextNoah ) {
1459 $this->
remove(
$head );
1461 $tail->nextNoah = $elt;
1464 if ( $this->tail ) {
1465 $this->tail->nextAFE = $elt;
1482 $prev =
$tail->prevAFE;
1483 $tail->prevAFE = null;
1485 $prev->nextAFE = null;
1487 $tail->nextNoah = null;
1492 $prev =
$tail->prevAFE;
1494 $prev->nextAFE = null;
1497 array_pop( $this->noahTableStack );
1500 $this->noahTableStack[0] = [];
1506 $this->tail =
$tail;
1517 if ( $elt->localName ===
$tag ) {
1520 $elt = $elt->prevAFE;
1531 return $this->head === $elt || $elt->prevAFE;
1541 if ( $this->head !== $elt && !$elt->prevAFE ) {
1542 throw new ParameterAssertionException(
'$elt',
1543 "Attempted to remove an element which is not in the AFE list" );
1546 if ( $this->head === $elt ) {
1547 $this->head = $elt->nextAFE;
1549 if ( $this->tail === $elt ) {
1550 $this->tail = $elt->prevAFE;
1553 if ( $elt->prevAFE ) {
1554 $elt->prevAFE->nextAFE = $elt->nextAFE;
1557 if ( $elt->nextAFE ) {
1558 $elt->nextAFE->prevAFE = $elt->prevAFE;
1561 $elt->prevAFE = $elt->nextAFE = null;
1568 $table =& $this->noahTableStack[ count( $this->noahTableStack ) - 1 ];
1569 if ( !isset( $table[$noahKey] ) ) {
1570 $table[$noahKey] = $elt;
1572 $tail = $table[$noahKey];
1573 while (
$tail->nextNoah ) {
1576 $tail->nextNoah = $elt;
1581 $table =& $this->noahTableStack[ count( $this->noahTableStack ) - 1 ];
1583 $noahElt = $table[$key];
1584 if ( $noahElt === $elt ) {
1585 if ( $noahElt->nextNoah ) {
1586 $table[$key] = $noahElt->nextNoah;
1587 $noahElt->nextNoah = null;
1589 unset( $table[$key] );
1593 $prevNoahElt = $noahElt;
1594 $noahElt = $prevNoahElt->nextNoah;
1595 if ( $noahElt === $elt ) {
1597 $prevNoahElt->nextNoah = $elt->nextNoah;
1598 $elt->nextNoah = null;
1601 }
while ( $noahElt );
1612 if ( $this->head !== $a && !$a->prevAFE ) {
1613 throw new ParameterAssertionException(
'$a',
1614 "Attempted to replace an element which is not in the AFE list" );
1617 if ( $this->head === $a ) {
1620 if ( $this->tail === $a ) {
1624 if ( $a->prevAFE ) {
1625 $a->prevAFE->nextAFE = $b;
1628 if ( $a->nextAFE ) {
1629 $a->nextAFE->prevAFE = $b;
1631 $b->prevAFE = $a->prevAFE;
1632 $b->nextAFE = $a->nextAFE;
1633 $a->nextAFE = $a->prevAFE = null;
1646 if ( $this->head !== $a && !$a->prevAFE ) {
1647 throw new ParameterAssertionException(
'$a',
1648 "Attempted to insert after an element which is not in the AFE list" );
1650 if ( $this->tail === $a ) {
1653 if ( $a->nextAFE ) {
1654 $a->nextAFE->prevAFE = $b;
1656 $b->nextAFE = $a->nextAFE;
1681 if ( $stack->indexOf( $entry ) >= 0 ) {
1688 while ( $entry->prevAFE ) {
1689 $entry = $entry->prevAFE;
1690 if ( $entry instanceof BalanceMarker || $stack->indexOf( $entry ) >= 0 ) {
1701 $entry = $entry->nextAFE;
1704 $newElement = $stack->insertHTMLElement(
1707 $this->
replace( $entry, $newElement );
1708 $entry = $newElement->nextAFE;
1718 for ( $node = $this->head; $node; $prev = $node, $node = $node->nextAFE ) {
1723 $s .= $node->localName .
'#' . substr( md5( spl_object_hash( $node ) ), 0, 8 );
1724 if ( $node->nextNoah ) {
1725 $s .=
" (noah sibling: {$node->nextNoah->localName}#" .
1726 substr( md5( spl_object_hash( $node->nextNoah ) ), 0, 8 ) .
1729 if ( $node->nextAFE && $node->nextAFE->prevAFE !== $node ) {
1730 $s .=
" (reverse link is wrong!)";
1734 if ( $prev !== $this->tail ) {
1735 $s .=
"(tail pointer is wrong!)\n";
1824 ( # 1. Comment match detector
1825 > | -> | # Invalid short close
1826 ( # 2. Comment contents
1836 ( # 3. Comment close
1837 --> | # Normal close
1838 --!> | # Comment end bang
1839 ( # 4. Indicate matches requiring EOF
1840 --! | # EOF in comment end bang state
1841 -- | # EOF in comment end state
1842 - | # EOF in comment end dash state
1843 # EOF in comment state
1847 ([^<]*) \z # 5. Non-tag text after the comment
1877 'allowedHtmlElements' => null,
1878 'tidyCompat' =>
false,
1879 'allowComments' =>
true,
1881 $this->allowedHtmlElements =
$config[
'allowedHtmlElements'];
1882 $this->strict =
$config[
'strict'];
1883 $this->allowComments =
$config[
'allowComments'];
1884 if ( $this->allowedHtmlElements !== null ) {
1886 $bad = array_uintersect_assoc(
1887 $this->allowedHtmlElements,
1889 function( $a, $b ) {
1895 if ( count( $bad ) > 0 ) {
1896 $badstr = implode( array_keys( $bad ),
',' );
1897 throw new ParameterAssertionException(
1899 'Balance attempted with sanitization including ' .
1900 "unsupported elements: {$badstr}"
1919 $this->parseMode =
'inBodyMode';
1926 $this->textIntegrationMode =
1927 $this->ignoreLinefeed =
1929 $this->inRAWTEXT =
false;
1933 $this->fragmentContext =
1936 $this->formElementPointer = null;
1937 for (
$e = $this->fragmentContext;
$e != null;
$e =
$e->parent ) {
1938 if (
$e->isHtmlNamed(
'form' ) ) {
1939 $this->formElementPointer =
$e;
1945 $x = $this->bitsIterator->current();
1946 $this->bitsIterator->next();
1947 $this->
insertToken(
'text', str_replace(
'>',
'>', $x ) );
1949 while ( $this->bitsIterator->valid() ) {
1953 $result = $this->stack->getOutput();
1955 $this->bitsIterator = null;
1957 $this->stack = null;
1958 $this->fragmentContext = null;
1959 $this->formElementPointer = null;
1969 if ( $token ===
'tag' || $token ===
'endtag' ) {
1975 "Unsupported $token <$value> found."
1979 } elseif ( $token ===
'text' &&
$value ===
'' ) {
1984 if ( $this->ignoreLinefeed ) {
1985 $this->ignoreLinefeed =
false;
1986 if ( $token ===
'text' ) {
1987 if (
$value[0] ===
"\n" ) {
1997 $adjusted = $this->stack->adjustedCurrentNode( $this->fragmentContext );
2001 $this->stack->length() === 0 ||
2002 $adjusted->isHtml() ||
2006 } elseif ( $adjusted->isMathmlTextIntegrationPoint() ) {
2007 if ( $token ===
'text' ) {
2017 $adjusted->localName ===
'annotation-xml' &&
2018 $token ===
'tag' &&
$value ===
'svg'
2022 $adjusted->isHtmlIntegrationPoint() &&
2023 ( $token ===
'tag' || $token ===
'text' )
2036 if ( $token ===
'text' ) {
2037 $this->stack->insertText(
$value );
2039 } elseif ( $token ===
'tag' ) {
2093 if ( $this->fragmentContext ) {
2097 $this->stack->pop();
2098 $node = $this->stack->currentNode;
2100 $node->isMathmlTextIntegrationPoint() ||
2101 $node->isHtmlIntegrationPoint() ||
2110 $adjusted = ( $this->fragmentContext && $this->stack->length()===1 ) ?
2111 $this->fragmentContext : $this->stack->currentNode;
2112 $this->stack->insertForeignElement(
2116 $this->stack->pop();
2119 } elseif ( $token ===
'endtag' ) {
2121 foreach ( $this->stack
as $i => $node ) {
2122 if ( $node->isHtml() && !$first ) {
2126 } elseif ( $i === 0 ) {
2128 } elseif ( $node->localName ===
$value ) {
2129 $this->stack->popTag( $node );
2142 $x = $this->bitsIterator->current();
2143 $this->bitsIterator->next();
2148 $this->allowComments &&
2149 !( $this->inRCDATA || $this->inRAWTEXT ) &&
2152 ( $regs[4][1] < 0 || !$this->bitsIterator->valid() )
2154 $contents = $regs[2][0];
2155 $rest = $regs[5][0];
2157 $this->
insertToken(
'text', str_replace(
'>',
'>', $rest ) );
2166 list( , $slash,
$t, $attribStr, $brace, $rest ) = $regs;
2167 $t = strtolower(
$t );
2168 if ( $this->strict ) {
2172 '/^( [:_A-Z0-9][-.:_A-Z0-9]*="[^"]*")*[ ]*$/i', $attribStr
2174 "Bad attribute string found"
2179 !$this->strict,
"< found which does not start a valid tag"
2181 $slash =
$t = $attribStr = $brace = $rest = null;
2184 if ( $this->inRCDATA ) {
2185 if ( $slash &&
$t === $this->inRCDATA ) {
2186 $this->inRCDATA =
false;
2192 if ( $this->inRAWTEXT ) {
2193 if ( $slash &&
$t === $this->inRAWTEXT ) {
2194 $this->inRAWTEXT =
false;
2200 $sanitize = $this->allowedHtmlElements !== null;
2202 $goodTag =
$t && isset( $this->allowedHtmlElements[
$t] );
2205 if ( is_callable( $this->processingCallback ) ) {
2206 call_user_func_array( $this->processingCallback, [ &$attribStr, $this->processingArgs ] );
2220 $slash ?
'endtag' :
'tag',
$t,
$attribs, $brace ===
'/>'
2224 $rest = str_replace(
'>',
'>', $rest );
2225 $this->
insertToken(
'text', str_replace(
'>',
'>', $rest ) );
2226 } elseif ( $this->inRAWTEXT ) {
2230 $this->
insertToken(
'text',
'<' . str_replace(
'>',
'>', $x ) );
2236 substr( $mode, -4 )===
'Mode',
'$mode',
'should end in Mode'
2239 $this->parseMode = $mode;
2250 foreach ( $this->stack
as $i => $node ) {
2253 if ( $this->fragmentContext ) {
2257 if ( $node->isHtml() ) {
2258 switch ( $node->localName ) {
2260 $stackLength = $this->stack->length();
2261 for ( $j = $i + 1; $j < $stackLength-1; $j++ ) {
2262 $ancestor = $this->stack->node( $stackLength-$j-1 );
2263 if ( $ancestor->isHtmlNamed(
'template' ) ) {
2266 if ( $ancestor->isHtmlNamed(
'table' ) ) {
2292 array_slice( $this->templateInsertionModes, -1 )[0]
2328 $this->stack->popTo( 1 );
2333 $this->inRAWTEXT =
$value;
2334 $this->originalInsertionMode = $this->
switchMode(
'inTextMode' );
2339 if ( $token ===
'text' ) {
2340 $this->stack->insertText(
$value );
2342 } elseif ( $token ===
'eof' ) {
2343 $this->stack->pop();
2345 $this->originalInsertionMode, $token,
$value,
$attribs, $selfClose
2347 } elseif ( $token ===
'endtag' ) {
2348 $this->stack->pop();
2349 $this->
switchMode( $this->originalInsertionMode );
2356 if ( $token ===
'text' ) {
2357 if ( preg_match(
'/^[\x09\x0A\x0C\x0D\x20]+/',
$value,
$matches ) ) {
2358 $this->stack->insertText(
$matches[0] );
2361 if ( strlen(
$value ) === 0 ) {
2365 } elseif ( $token ===
'tag' ) {
2376 $this->stack->pop();
2386 $this->afe->insertMarker();
2393 } elseif ( $token ===
'endtag' ) {
2401 if ( $this->stack->indexOf(
$value ) < 0 ) {
2404 $this->stack->generateImpliedEndTags( null,
true );
2405 $this->stack->popTag(
$value );
2406 $this->afe->clearToMarker();
2407 array_pop( $this->templateInsertionModes );
2414 } elseif ( $token ===
'comment' ) {
2415 $this->stack->insertComment(
$value );
2426 if ( $token ===
'text' ) {
2427 $this->afe->reconstruct( $this->stack );
2428 $this->stack->insertText(
$value );
2430 } elseif ( $token ===
'eof' ) {
2431 if ( !empty( $this->templateInsertionModes ) ) {
2436 } elseif ( $token ===
'tag' ) {
2477 if ( $this->stack->inButtonScope(
'p' ) ) {
2489 if ( $this->stack->inButtonScope(
'p' ) ) {
2493 $this->stack->pop();
2500 if ( $this->stack->inButtonScope(
'p' ) ) {
2504 $this->ignoreLinefeed =
true;
2510 $this->formElementPointer &&
2511 $this->stack->indexOf(
'template' ) < 0
2515 if ( $this->stack->inButtonScope(
"p" ) ) {
2519 if ( $this->stack->indexOf(
'template' ) < 0 ) {
2520 $this->formElementPointer = $elt;
2526 foreach ( $this->stack
as $node ) {
2527 if ( $node->isHtmlNamed(
'li' ) ) {
2538 if ( $this->stack->inButtonScope(
'p' ) ) {
2547 foreach ( $this->stack
as $node ) {
2548 if ( $node->isHtmlNamed(
'dd' ) ) {
2552 if ( $node->isHtmlNamed(
'dt' ) ) {
2563 if ( $this->stack->inButtonScope(
'p' ) ) {
2572 if ( $this->stack->inScope(
'button' ) ) {
2576 $this->afe->reconstruct( $this->stack );
2581 $activeElement = $this->afe->findElementByTag(
'a' );
2582 if ( $activeElement ) {
2584 if ( $this->afe->isInList( $activeElement ) ) {
2585 $this->afe->remove( $activeElement );
2589 $this->stack->removeElement( $activeElement,
false );
2605 $this->afe->reconstruct( $this->stack );
2606 $this->afe->push( $this->stack->insertHTMLElement(
$value,
$attribs ) );
2610 $this->afe->reconstruct( $this->stack );
2611 if ( $this->stack->inScope(
'nobr' ) ) {
2613 $this->afe->reconstruct( $this->stack );
2615 $this->afe->push( $this->stack->insertHTMLElement(
$value,
$attribs ) );
2621 $this->afe->reconstruct( $this->stack );
2623 $this->afe->insertMarker();
2630 if ( $this->stack->inButtonScope(
'p' ) ) {
2644 $this->afe->reconstruct( $this->stack );
2646 $this->stack->pop();
2651 $this->afe->reconstruct( $this->stack );
2653 $this->stack->pop();
2663 $this->stack->pop();
2667 if ( $this->stack->inButtonScope(
'p' ) ) {
2671 $this->stack->pop();
2682 $this->ignoreLinefeed =
true;
2683 $this->inRCDATA =
$value;
2693 $this->afe->reconstruct( $this->stack );
2695 switch ( $this->parseMode ) {
2697 case 'inCaptionMode':
2698 case 'inTableBodyMode':
2710 if ( $this->stack->currentNode->isHtmlNamed(
'option' ) ) {
2713 $this->afe->reconstruct( $this->stack );
2719 if ( $this->stack->inScope(
'ruby' ) ) {
2720 $this->stack->generateImpliedEndTags();
2727 if ( $this->stack->inScope(
'ruby' ) ) {
2728 $this->stack->generateImpliedEndTags(
'rtc' );
2734 $this->afe->reconstruct( $this->stack );
2739 $this->stack->insertForeignElement(
2744 $this->stack->pop();
2749 $this->afe->reconstruct( $this->stack );
2754 $this->stack->insertForeignElement(
2759 $this->stack->pop();
2779 $this->afe->reconstruct( $this->stack );
2782 } elseif ( $token ===
'endtag' ) {
2816 if ( !$this->stack->inScope(
$value ) ) {
2819 $this->stack->generateImpliedEndTags();
2820 $this->stack->popTag(
$value );
2824 if ( $this->stack->indexOf(
'template' ) < 0 ) {
2826 $this->formElementPointer = null;
2827 if ( !$openform || !$this->stack->inScope( $openform ) ) {
2830 $this->stack->generateImpliedEndTags();
2833 $flatten = ( $this->stack->currentNode === $openform );
2834 $this->stack->removeElement( $openform, $flatten );
2836 if ( !$this->stack->inScope(
'form' ) ) {
2839 $this->stack->generateImpliedEndTags();
2840 $this->stack->popTag(
'form' );
2845 if ( !$this->stack->inButtonScope(
'p' ) ) {
2849 $this->stack->generateImpliedEndTags(
$value );
2850 $this->stack->popTag(
$value );
2854 if ( !$this->stack->inListItemScope(
$value ) ) {
2857 $this->stack->generateImpliedEndTags(
$value );
2858 $this->stack->popTag(
$value );
2863 if ( !$this->stack->inScope(
$value ) ) {
2866 $this->stack->generateImpliedEndTags(
$value );
2867 $this->stack->popTag(
$value );
2879 $this->stack->generateImpliedEndTags();
2901 if ( $this->stack->adoptionAgency(
$value, $this->afe ) ) {
2909 if ( !$this->stack->inScope(
$value ) ) {
2912 $this->stack->generateImpliedEndTags();
2913 $this->stack->popTag(
$value );
2914 $this->afe->clearToMarker();
2923 foreach ( $this->stack
as $i => $node ) {
2924 if ( $node->isHtmlNamed(
$value ) ) {
2925 $this->stack->generateImpliedEndTags(
$value );
2926 $this->stack->popTo( $i );
2933 } elseif ( $token ===
'comment' ) {
2934 $this->stack->insertComment(
$value );
2937 Assert::invariant(
false,
"Bad token type: $token" );
2942 if ( $token ===
'text' ) {
2943 if ( $this->textIntegrationMode ) {
2946 $this->pendingTableText =
'';
2952 } elseif ( $token ===
'eof' ) {
2955 } elseif ( $token ===
'tag' ) {
2958 $this->afe->insertMarker();
2983 if ( !$this->stack->inTableScope(
$value ) ) {
2995 if ( !isset(
$attribs[
'type'] ) || strcasecmp(
$attribs[
'type'],
'hidden' ) !== 0 ) {
2999 $this->stack->pop();
3004 $this->formElementPointer ||
3005 $this->stack->indexOf(
'template' ) >= 0
3009 $this->formElementPointer =
3011 $this->stack->popTag( $this->formElementPointer );
3015 } elseif ( $token ===
'endtag' ) {
3018 if ( !$this->stack->inTableScope(
$value ) ) {
3021 $this->stack->popTag(
$value );
3040 } elseif ( $token ===
'comment' ) {
3041 $this->stack->insertComment(
$value );
3045 $this->stack->fosterParentMode =
true;
3047 $this->stack->fosterParentMode =
false;
3052 if ( $token ===
'text' ) {
3053 $this->pendingTableText .=
$value;
3058 $this->pendingTableText =
'';
3059 if ( preg_match(
'/[^\x09\x0A\x0C\x0D\x20]/', $text ) ) {
3061 $this->stack->fosterParentMode =
true;
3063 $this->stack->fosterParentMode =
false;
3066 $this->stack->insertText( $text );
3069 $this->originalInsertionMode, $token,
$value,
$attribs, $selfClose
3075 if ( !$this->stack->inTableScope(
'caption' ) ) {
3078 $this->stack->generateImpliedEndTags();
3079 $this->stack->popTag(
'caption' );
3080 $this->afe->clearToMarker();
3086 if ( $token ===
'tag' ) {
3103 } elseif ( $token ===
'endtag' ) {
3133 if ( $token ===
'text' ) {
3134 if ( preg_match(
'/^[\x09\x0A\x0C\x0D\x20]+/',
$value,
$matches ) ) {
3135 $this->stack->insertText(
$matches[0] );
3138 if ( strlen(
$value ) === 0 ) {
3142 } elseif ( $token ===
'tag' ) {
3147 $this->stack->pop();
3153 } elseif ( $token ===
'endtag' ) {
3156 if ( !$this->stack->currentNode->isHtmlNamed(
'colgroup' ) ) {
3159 $this->stack->pop();
3168 } elseif ( $token ===
'eof' ) {
3170 } elseif ( $token ===
'comment' ) {
3171 $this->stack->insertComment(
$value );
3176 if ( !$this->stack->currentNode->isHtmlNamed(
'colgroup' ) ) {
3186 $this->stack->inTableScope(
'tbody' ) ||
3187 $this->stack->inTableScope(
'thead' ) ||
3188 $this->stack->inTableScope(
'tfoot' )
3193 $this->stack->pop();
3198 if ( $token ===
'tag' ) {
3221 } elseif ( $token ===
'endtag' ) {
3231 if ( $this->stack->inTableScope(
$value ) ) {
3252 if ( !$this->stack->inTableScope(
'tr' ) ) {
3256 $this->stack->pop();
3261 if ( $token ===
'tag' ) {
3268 $this->afe->insertMarker();
3282 } elseif ( $token ===
'endtag' ) {
3296 $this->stack->inTableScope(
$value ) &&
3318 if ( $this->stack->inTableScope(
'td' ) ) {
3321 } elseif ( $this->stack->inTableScope(
'th' ) ) {
3329 if ( $token ===
'tag' ) {
3345 } elseif ( $token ===
'endtag' ) {
3349 if ( $this->stack->inTableScope(
$value ) ) {
3350 $this->stack->generateImpliedEndTags();
3351 $this->stack->popTag(
$value );
3352 $this->afe->clearToMarker();
3368 if ( $this->stack->inTableScope(
$value ) ) {
3369 $this->stack->generateImpliedEndTags();
3371 $this->afe->clearToMarker();
3383 if ( $token ===
'text' ) {
3384 $this->stack->insertText(
$value );
3386 } elseif ( $token ===
'eof' ) {
3388 } elseif ( $token ===
'tag' ) {
3392 if ( $this->stack->currentNode->isHtmlNamed(
'option' ) ) {
3393 $this->stack->pop();
3398 if ( $this->stack->currentNode->isHtmlNamed(
'option' ) ) {
3399 $this->stack->pop();
3401 if ( $this->stack->currentNode->isHtmlNamed(
'optgroup' ) ) {
3402 $this->stack->pop();
3412 if ( !$this->stack->inSelectScope(
'select' ) ) {
3421 } elseif ( $token ===
'endtag' ) {
3425 $this->stack->currentNode->isHtmlNamed(
'option' ) &&
3426 $this->stack->length() >= 2 &&
3427 $this->stack->node( $this->stack->length() - 2 )->isHtmlNamed(
'optgroup' )
3429 $this->stack->pop();
3431 if ( $this->stack->currentNode->isHtmlNamed(
'optgroup' ) ) {
3432 $this->stack->pop();
3436 if ( $this->stack->currentNode->isHtmlNamed(
'option' ) ) {
3437 $this->stack->pop();
3441 if ( !$this->stack->inSelectScope(
$value ) ) {
3444 $this->stack->popTag(
$value );
3450 } elseif ( $token ===
'comment' ) {
3451 $this->stack->insertComment(
$value );
3468 if ( $token ===
'tag' ) {
3471 } elseif ( $token ===
'endtag' ) {
3472 if ( $this->stack->inTableScope(
$value ) ) {
3484 if ( $token ===
'text' || $token ===
'comment' ) {
3486 } elseif ( $token ===
'eof' ) {
3487 if ( $this->stack->indexOf(
'template' ) < 0 ) {
3490 $this->stack->popTag(
'template' );
3491 $this->afe->clearToMarker();
3492 array_pop( $this->templateInsertionModes );
3497 } elseif ( $token ===
'tag' ) {
3539 } elseif ( $token ===
'endtag' ) {
3546 Assert::invariant(
false,
"Bad token type: $token" );
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
static decodeTagAttributes($text)
Return an associative array of attribute names and values from a partial tag string.
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
the array() calling protocol came about after MediaWiki 1.4rc1.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException'returning false will NOT prevent logging $e
Some information about database access in MediaWiki By Tim January Database layout For information about the MediaWiki database such as a description of the tables and their contents
static validateTagAttributes($attribs, $element)
Take an array of attribute names and values and normalize or discard illegal values for the given ele...
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message.Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item.Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page.Return false to stop further processing of the tag $reader:XMLReader object &$pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision.Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag.Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload.Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports.&$fullInterwikiPrefix:Interwiki prefix, may contain colons.&$pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable.Can be used to lazy-load the import sources list.&$importSources:The value of $wgImportSources.Modify as necessary.See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page.$context:IContextSource object &$pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect.&$title:Title object for the current page &$request:WebRequest &$ignoreRedirect:boolean to skip redirect check &$target:Title/string of redirect target &$article:Article object 'InternalParseBeforeLinks':during Parser's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InternalParseBeforeSanitize':during Parser's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings.Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not.Return true without providing an interwiki to continue interwiki search.$prefix:interwiki prefix we are looking for.&$iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user's email has been invalidated successfully.$user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification.Callee may modify $url and $query, URL will be constructed as $url.$query &$url:URL to index.php &$query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) &$article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() &$ip:IP being check &$result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from &$allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn't match your organization.$addr:The e-mail address entered by the user &$result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user &$result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we're looking for a messages file for &$file:The messages file path, you can override this to change the location. 'LanguageGetMagic':DEPRECATED!Use $magicWords in a file listed in $wgExtensionMessagesFiles instead.Use this to define synonyms of magic words depending of the language &$magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces.Do not use this hook to add namespaces.Use CanonicalNamespaces for that.&$namespaces:Array of namespaces indexed by their numbers 'LanguageGetSpecialPageAliases':DEPRECATED!Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead.Use to define aliases of special pages names depending of the language &$specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names.&$names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page's language links.This is called in various places to allow extensions to define the effective language links for a page.$title:The page's Title.&$links:Associative array mapping language codes to prefixed links of the form"language:title".&$linkFlags:Associative array mapping prefixed links to arrays of flags.Currently unused, but planned to provide support for marking individual language links in the UI, e.g.for featured articles. 'LanguageSelector':Hook to change the language selector available on a page.$out:The output page.$cssClassName:CSS class name of the language selector. 'LinkBegin':DEPRECATED!Use HtmlPageLinkRendererBegin instead.Used when generating internal and interwiki links in Linker::link(), before processing starts.Return false to skip default processing and return $ret.See documentation for Linker::link() for details on the expected meanings of parameters.$skin:the Skin object $target:the Title that the link is pointing to &$html:the contents that the< a > tag should have(raw HTML) $result
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
const ELEMENT_BITS_REGEX
Acceptable tag name charset from HTML5 parsing spec http://www.w3.org/TR/html5/syntax.html#tag-open-state.
static validateTag($params, $element)
Takes attribute names and values for a tag and the tag name and validates that the tag is allowed to ...
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing & $attribs
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books $tag
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
static encodeAttribute($text)
Encode an attribute value for HTML output.
Allows to change the fields on the form that will be generated $name