-The development of this software is covered by a [Code of Conduct](https://www.mediawiki.org/wiki/Code_of_Conduct).
+The development of this software is covered by a [Code of Conduct](https://www.mediawiki.org/wiki/Special:MyLanguage/Code_of_Conduct).
This action should be considered deprecated and should not be used directly.
* Extensions overriding ContentHandler::getUndoContent() will need to be
updated for the changed method signature.
+* Added a new hook, 'UserGetRightsRemove', which can be used to remove rights
+ from user. Unlike the 'UserGetRights' it will ensure that removed rights
+ will not be reinserted.
=== External library changes in 1.32 ===
$user: User to get rights for
&$rights: Current rights
+'UserGetRightsRemove': Called in User::getRights(). This hook override
+the UserGetRights hook. It can be used to remove rights from user
+and ensure that will not be reinserted by the other hook callbacks
+therefore this hook should not be used to add any rights, use UserGetRights instead.
+$user: User to get rights for
+&$rights: Current rights
+
'UserGroupsChanged': Called after user groups are changed.
$user: User whose groups changed
$added: Groups added
$this->openingText = $this->extractHeadingBeforeFirstHeading( $text );
- // Add extra spacing around break tags so text crammed together like<br>this
- // doesn't make one word.
- $text = str_replace( '<br', "\n<br", $text );
-
$formatter = new HtmlFormatter( $text );
// Strip elements from the page that we never want in the search text.
return parent::getRaw( $value );
}
+ /**
+ * @param mixed $value
+ * @return OOUI\FieldLayout
+ * @since 1.32
+ */
+ public function getOOUI( $value ) {
+ if ( !empty( $this->mParams['rawrow'] ) ) {
+ if ( !( $value instanceof OOUI\FieldLayout ) ) {
+ throw new Exception( "'default' must be a FieldLayout or subclass when using 'rawrow'" );
+ }
+ return $value;
+ }
+
+ return parent::getOOUI( $value );
+ }
+
protected function needsLabel() {
return false;
}
"config-install-mainpage-failed": "Could not insert main page: $1",
"config-install-done": "<strong>Congratulations!</strong>\nYou have installed MediaWiki.\n\nThe installer has generated a <code>LocalSettings.php</code> file.\nIt contains all your configuration.\n\nYou will need to download it and put it in the base of your wiki installation (the same directory as index.php). The download should have started automatically.\n\nIf the download was not offered, or if you cancelled it, you can restart the download by clicking the link below:\n\n$3\n\n<strong>Note:</strong> If you do not do this now, this generated configuration file will not be available to you later if you exit the installation without downloading it.\n\nWhen that has been done, you can <strong>[$2 enter your wiki]</strong>.",
"config-install-done-path": "<strong>Congratulations!</strong>\nYou have installed MediaWiki.\n\nThe installer has generated a <code>LocalSettings.php</code> file.\nIt contains all your configuration.\n\nYou will need to download it and put it at <code>$4</code>. The download should have started automatically.\n\nIf the download was not offered, or if you cancelled it, you can restart the download by clicking the link below:\n\n$3\n\n<strong>Note:</strong> If you do not do this now, this generated configuration file will not be available to you later if you exit the installation without downloading it.\n\nWhen that has been done, you can <strong>[$2 enter your wiki]</strong>.",
- "config-install-success": "MediaWiki has been successfully installed. You can now\nvisit <$1$2> to view your wiki.\nIf you have questions, check out our frequently asked questions list:\n<https://www.mediawiki.org/wiki/Manual:FAQ> or use one of the\nsupport forums linked on that page.",
+ "config-install-success": "MediaWiki has been successfully installed. You can now visit <$1$2> to view your wiki.\nIf you have questions, check out our frequently asked questions list:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> or use one of the\nsupport forums linked on that page.",
"config-download-localsettings": "Download <code>LocalSettings.php</code>",
"config-help": "help",
"config-help-tooltip": "click to expand",
"Jdforrester",
"Liuxinyu970226",
"Metalhead64",
- "Tacsipacsi"
+ "Tacsipacsi",
+ "Zoranzoki21"
]
},
"config-desc": "Short description of the installer.",
"config-unknown-collation": "Warning messages in the MediaWiki installer for the database type MySQL when an unrecognised collation is used.",
"config-db-web-account": "Fieldset legend in MediaWiki installer",
"config-db-web-help": "Help text in MediaWiki installer.",
- "config-db-web-account-same": "checkbox label",
- "config-db-web-create": "checkbox label",
+ "config-db-web-account-same": "Checkbox label about setting of database account for web access.",
+ "config-db-web-create": "Checkbox label about creating of new database account.",
"config-db-web-no-create-privs": "Error message in the MediaWiki installer.",
"config-mysql-engine": "Field label for MySQL storage engine in the MediaWiki installer.",
"config-mysql-innodb": "Option for the MySQL storage engine in the MediaWiki installer.",
$this->debugCallback( $msg );
// Wait for an exclusive lock to commit
- if ( !$dbwSerial->lock( 'jobrunner-serial-commit', __METHOD__, 30 ) ) {
+ if ( !$dbwSerial->lock( 'jobrunner-serial-commit', $fnameTrxOwner, 30 ) ) {
// This will trigger a rollback in the main loop
throw new DBError( $dbwSerial, "Timed out waiting on commit queue." );
}
- $unlocker = new ScopedCallback( function () use ( $dbwSerial ) {
- $dbwSerial->unlock( 'jobrunner-serial-commit', __METHOD__ );
+ $unlocker = new ScopedCallback( function () use ( $dbwSerial, $fnameTrxOwner ) {
+ $dbwSerial->unlock( 'jobrunner-serial-commit', $fnameTrxOwner );
} );
// Wait for the replica DBs to catch up
abstract protected function doQuery( $sql );
/**
- * Determine whether a query writes to the DB.
- * Should return true if unsure.
+ * Determine whether a query writes to the DB. When in doubt, this returns true.
+ *
+ * Main use cases:
+ *
+ * - Subsequent web requests should not need to wait for replication from
+ * the master position seen by this web request, unless this request made
+ * changes to the master. This is handled by ChronologyProtector by checking
+ * doneWrites() at the end of the request. doneWrites() returns true if any
+ * query set lastWriteTime; which query() does based on isWriteQuery().
+ *
+ * - Reject write queries to replica DBs, in query().
*
* @param string $sql
* @return bool
*/
protected function isWriteQuery( $sql ) {
+ // BEGIN and COMMIT queries are considered read queries here.
+ // Database backends and drivers (MySQL, MariaDB, php-mysqli) generally
+ // treat these as write queries, in that their results have "affected rows"
+ // as meta data as from writes, instead of "num rows" as from reads.
+ // But, we treat them as read queries because when reading data (from
+ // either replica or master) we use transactions to enable repeatable-read
+ // snapshots, which ensures we get consistent results from the same snapshot
+ // for all queries within a request. Use cases:
+ // - Treating these as writes would trigger ChronologyProtector (see method doc).
+ // - We use this method to reject writes to replicas, but we need to allow
+ // use of transactions on replicas for read snapshots. This fine given
+ // that transactions by themselves don't make changes, only actual writes
+ // within the transaction matter, which we still detect.
return !preg_match(
'/^(?:SELECT|BEGIN|ROLLBACK|COMMIT|SET|SHOW|EXPLAIN|\(SELECT)\b/i', $sql );
}
/**
* Determine whether a SQL statement is sensitive to isolation level.
+ *
* A SQL statement is considered transactable if its result could vary
* depending on the transaction isolation level. Operational commands
* such as 'SET' and 'SHOW' are not considered to be transactable.
*
+ * Main purpose: Used by query() to decide whether to begin a transaction
+ * before the current query (in DBO_TRX mode, on by default).
+ *
* @param string $sql
* @return bool
*/
protected function isTransactableQuery( $sql ) {
return !in_array(
$this->getQueryVerb( $sql ),
- [ 'BEGIN', 'COMMIT', 'ROLLBACK', 'SHOW', 'SET', 'CREATE', 'ALTER' ],
+ [ 'BEGIN', 'ROLLBACK', 'COMMIT', 'SET', 'SHOW', 'CREATE', 'ALTER' ],
true
);
}
return $this->query( "ATTACH DATABASE $file AS $name", $fname );
}
- function isWriteQuery( $sql ) {
+ protected function isWriteQuery( $sql ) {
return parent::isWriteQuery( $sql ) && !preg_match( '/^(ATTACH|PRAGMA)\b/i', $sql );
}
$this->text .= substr( $text, $start, $length );
}
function startTag( $name, Attributes $attrs, $selfClose, $sourceStart, $sourceLength ) {
- // Do nothing.
+ // Inject whitespace for typical block-level tags to
+ // prevent merging unrelated<br>words.
+ if ( $this->isBlockLevelTag( $name ) ) {
+ $this->text .= ' ';
+ }
}
function endTag( $name, $sourceStart, $sourceLength ) {
- // Do nothing.
+ // Inject whitespace for typical block-level tags to
+ // prevent merging unrelated<br>words.
+ if ( $this->isBlockLevelTag( $name ) ) {
+ $this->text .= ' ';
+ }
}
function doctype( $name, $public, $system, $quirks, $sourceStart, $sourceLength ) {
// Do nothing.
function comment( $text, $sourceStart, $sourceLength ) {
// Do nothing.
}
+
+ // Per https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
+ // retrieved on sept 12, 2018. <br> is not block level but was added anyways.
+ // The following is a complete list of all HTML block level elements
+ // (although "block-level" is not technically defined for elements that are
+ // new in HTML5).
+ // Structured as tag => true to allow O(1) membership test.
+ static private $BLOCK_LEVEL_TAGS = [
+ 'address' => true,
+ 'article' => true,
+ 'aside' => true,
+ 'blockquote' => true,
+ 'br' => true,
+ 'canvas' => true,
+ 'dd' => true,
+ 'div' => true,
+ 'dl' => true,
+ 'dt' => true,
+ 'fieldset' => true,
+ 'figcaption' => true,
+ 'figure' => true,
+ 'figcaption' => true,
+ 'footer' => true,
+ 'form' => true,
+ 'h1' => true,
+ 'h2' => true,
+ 'h3' => true,
+ 'h4' => true,
+ 'h5' => true,
+ 'h6' => true,
+ 'header' => true,
+ 'hgroup' => true,
+ 'hr' => true,
+ 'li' => true,
+ 'main' => true,
+ 'nav' => true,
+ 'noscript' => true,
+ 'ol' => true,
+ 'output' => true,
+ 'p' => true,
+ 'pre' => true,
+ 'section' => true,
+ 'table' => true,
+ 'tfoot' => true,
+ 'ul' => true,
+ 'video' => true,
+ ];
+
+ /**
+ * Detect block level tags. Of course css can make anything a block
+ * level tag, but this is still better than nothing.
+ *
+ * @param string $tagName HTML tag name
+ * @return bool True when tag is an html block level element
+ */
+ private function isBlockLevelTag( $tagName ) {
+ $key = strtolower( trim( $tagName ) );
+ return isset( self::$BLOCK_LEVEL_TAGS[$key] );
+ }
}
* @return string
*/
private static function normalizeWhitespace( $text ) {
- return preg_replace(
- '/\r\n|[\x20\x0d\x0a\x09]/',
+ return trim( preg_replace(
+ '/(?:\r\n|[\x20\x0d\x0a\x09])+/',
' ',
- $text );
+ $text ) );
}
/**
}
}
+ Hooks::run( 'UserGetRightsRemove', [ $this, &$this->mRights ] );
// Force reindexation of rights when a hook has unset one of them
$this->mRights = array_values( array_unique( $this->mRights ) );
$this->mCyLa2Arab = [
# # Punctuation -> Arabic
- '/#|№|No\./u' => '', # ؀
- '/\,/' => '،', # ،
- '/;/' => '؛', # ؛
- '/\?/' => '؟', # ؟
- '/%/' => '٪', # ٪
- '/\*/' => '٭', # ٭
+ '/#|№|No\./u' => '', # U+0600
+ '/\,/' => '،', # U+060C
+ '/;/' => '؛', # U+061B
+ '/\?/' => '؟', # U+061F
+ '/%/' => '٪', # U+066A
+ '/\*/' => '٭', # U+066D
# # Digits -> Arabic
- '/0/' => '۰', # ۰
- '/1/' => '۱', # ۱
- '/2/' => '۲', # ۲
- '/3/' => '۳', # ۳
- '/4/' => '۴', # ۴
- '/5/' => '۵', # ۵
- '/6/' => '۶', # ۶
- '/7/' => '۷', # ۷
- '/8/' => '۸', # ۸
- '/9/' => '۹', # ۹
+ '/0/' => '۰', # U+06F0
+ '/1/' => '۱', # U+06F1
+ '/2/' => '۲', # U+06F2
+ '/3/' => '۳', # U+06F3
+ '/4/' => '۴', # U+06F4
+ '/5/' => '۵', # U+06F5
+ '/6/' => '۶', # U+06F6
+ '/7/' => '۷', # U+06F7
+ '/8/' => '۸', # U+06F8
+ '/9/' => '۹', # U+06F9
# # Cyrillic -> Arabic
'/Аллаһ/ui' => 'ﷲ',
'/([АӘЕЁИОӨҰҮЭЮЯЪЬ])е/ui' => '$1يە',
'؟' => '?',
# digits
- '٠' => '0', # ٠
- '١' => '1', # ١
- '٢' => '2', # ٢
- '٣' => '3', # ٣
- '٤' => '4', # ٤
- '٥' => '5', # ٥
- '٦' => '6', # ٦
- '٧' => '7', # ٧
- '٨' => '8', # ٨
- '٩' => '9', # ٩
+ '٠' => '0', # U+0660
+ '١' => '1', # U+0661
+ '٢' => '2', # U+0662
+ '٣' => '3', # U+0663
+ '٤' => '4', # U+0664
+ '٥' => '5', # U+0665
+ '٦' => '6', # U+0666
+ '٧' => '7', # U+0667
+ '٨' => '8', # U+0668
+ '٩' => '9', # U+0669
];
public $mLatinToArabic = [
/* # deactivated for now, breaks links i.e. in header of Special:Recentchanges :-(
# digits
- '0' => '٠', # ٠
- '1' => '١', # ١
- '2' => '٢', # ٢
- '3' => '٣', # ٣
- '4' => '٤', # ٤
- '5' => '٥', # ٥
- '6' => '٦', # ٦
- '7' => '٧', # ٧
- '8' => '٨', # ٨
- '9' => '٩', # ٩
+ '0' => '٠', # U+0660
+ '1' => '١', # U+0661
+ '2' => '٢', # U+0662
+ '3' => '٣', # U+0663
+ '4' => '٤', # U+0664
+ '5' => '٥', # U+0665
+ '6' => '٦', # U+0666
+ '7' => '٧', # U+0667
+ '8' => '٨', # U+0668
+ '9' => '٩', # U+0669
*/
];
];
$digitTransformTable = [
- '0' => '٠', # ٠
- '1' => '١', # ١
- '2' => '٢', # ٢
- '3' => '٣', # ٣
- '4' => '٤', # ٤
- '5' => '٥', # ٥
- '6' => '٦', # ٦
- '7' => '٧', # ٧
- '8' => '٨', # ٨
- '9' => '٩', # ٩
+ '0' => '٠', # U+0660
+ '1' => '١', # U+0661
+ '2' => '٢', # U+0662
+ '3' => '٣', # U+0663
+ '4' => '٤', # U+0664
+ '5' => '٥', # U+0665
+ '6' => '٦', # U+0666
+ '7' => '٧', # U+0667
+ '8' => '٨', # U+0668
+ '9' => '٩', # U+0669
];
$separatorTransformTable = [
- '.' => '٫', # ٫
- ',' => '٬', # ٬
+ '.' => '٫', # U+066B
+ ',' => '٬', # U+066C
];
$namespaceNames = [
];
$digitTransformTable = [
- '0' => '০', # ০
- '1' => '১', # ১
- '2' => '২', # ২
- '3' => '৩', # ৩
- '4' => '৪', # ৪
- '5' => '৫', # ৫
- '6' => '৬', # ৬
- '7' => '৭', # ৭
- '8' => '৮', # ৮
- '9' => '৯', # ৯
+ '0' => '০', # U+09E6
+ '1' => '১', # U+09E7
+ '2' => '২', # U+09E8
+ '3' => '৩', # U+09E9
+ '4' => '৪', # U+09EA
+ '5' => '৫', # U+09EB
+ '6' => '৬', # U+09EC
+ '7' => '৭', # U+09ED
+ '8' => '৮', # U+09EE
+ '9' => '৯', # U+09EF
];
$digitGroupingPattern = "##,##,###";
];
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
*/
$digitTransformTable = [
- '0' => '༠', # ༠
- '1' => '༡', # ༡
- '2' => '༢', # ༢
- '3' => '༣', # ༣
- '4' => '༤', # ༤
- '5' => '༥', # ༥
- '6' => '༦', # ༦
- '7' => '༧', # ༧
- '8' => '༨', # ༨
- '9' => '༩', # ༩
+ '0' => '༠', # U+0F20
+ '1' => '༡', # U+0F21
+ '2' => '༢', # U+0F22
+ '3' => '༣', # U+0F23
+ '4' => '༤', # U+0F24
+ '5' => '༥', # U+0F25
+ '6' => '༦', # U+0F26
+ '7' => '༧', # U+0F27
+ '8' => '༨', # U+0F28
+ '9' => '༩', # U+0F29
];
];
$digitTransformTable = [
- '0' => '٠', # ٠
- '1' => '١', # ١
- '2' => '٢', # ٢
- '3' => '٣', # ٣
- '4' => '٤', # ٤
- '5' => '٥', # ٥
- '6' => '٦', # ٦
- '7' => '٧', # ٧
- '8' => '٨', # ٨
- '9' => '٩', # ٩
+ '0' => '٠', # U+0660
+ '1' => '١', # U+0661
+ '2' => '٢', # U+0662
+ '3' => '٣', # U+0663
+ '4' => '٤', # U+0664
+ '5' => '٥', # U+0665
+ '6' => '٦', # U+0666
+ '7' => '٧', # U+0667
+ '8' => '٨', # U+0668
+ '9' => '٩', # U+0669
];
$separatorTransformTable = [
- '.' => '٫', # ٫
- ',' => '٬', # ٬
+ '.' => '٫', # U+066B
+ ',' => '٬', # U+066C
];
$datePreferences = [
*/
$digitTransformTable = [
- '0' => '༠', # ༠
- '1' => '༡', # ༡
- '2' => '༢', # ༢
- '3' => '༣', # ༣
- '4' => '༤', # ༤
- '5' => '༥', # ༥
- '6' => '༦', # ༦
- '7' => '༧', # ༧
- '8' => '༨', # ༨
- '9' => '༩', # ༩
+ '0' => '༠', # U+0F20
+ '1' => '༡', # U+0F21
+ '2' => '༢', # U+0F22
+ '3' => '༣', # U+0F23
+ '4' => '༤', # U+0F24
+ '5' => '༥', # U+0F25
+ '6' => '༦', # U+0F26
+ '7' => '༧', # U+0F27
+ '8' => '༨', # U+0F28
+ '9' => '༩', # U+0F29
];
];
$digitTransformTable = [
- '0' => '۰', # ۰
- '1' => '۱', # ۱
- '2' => '۲', # ۲
- '3' => '۳', # ۳
- '4' => '۴', # ۴
- '5' => '۵', # ۵
- '6' => '۶', # ۶
- '7' => '۷', # ۷
- '8' => '۸', # ۸
- '9' => '۹', # ۹
- '%' => '٪', # ٪
+ '0' => '۰', # U+06F0
+ '1' => '۱', # U+06F1
+ '2' => '۲', # U+06F2
+ '3' => '۳', # U+06F3
+ '4' => '۴', # U+06F4
+ '5' => '۵', # U+06F5
+ '6' => '۶', # U+06F6
+ '7' => '۷', # U+06F7
+ '8' => '۸', # U+06F8
+ '9' => '۹', # U+06F9
+ '%' => '٪', # U+066A
];
$separatorTransformTable = [
- '.' => '٫', # ٫
- ',' => '٬', # ٬
+ '.' => '٫', # U+066B
+ ',' => '٬', # U+066C
];
/**
];
$digitTransformTable = [
- '0' => '૦', # ૦
- '1' => '૧', # ૧
- '2' => '૨', # ૨
- '3' => '૩', # ૩
- '4' => '૪', # ૪
- '5' => '૫', # ૫
- '6' => '૬', # ૬
- '7' => '૭', # ૭
- '8' => '૮', # ૮
- '9' => '૯', # ૯
+ '0' => '૦', # U+0AE6
+ '1' => '૧', # U+0AE7
+ '2' => '૨', # U+0AE8
+ '3' => '૩', # U+0AE9
+ '4' => '૪', # U+0AEA
+ '5' => '૫', # U+0AEB
+ '6' => '૬', # U+0AEC
+ '7' => '૭', # U+0AED
+ '8' => '૮', # U+0AEE
+ '9' => '૯', # U+0AEF
];
$digitGroupingPattern = "##,##,###";
];
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
$linkTrail = "/^([a-z\x{0900}-\x{0963}\x{0966}-\x{A8E0}-\x{A8FF}]+)(.*)$/sDu";
$rtl = true;
$digitTransformTable = [
- '0' => '۰', # ۰
- '1' => '۱', # ۱
- '2' => '۲', # ۲
- '3' => '۳', # ۳
- '4' => '۴', # ۴
- '5' => '۵', # ۵
- '6' => '۶', # ۶
- '7' => '۷', # ۷
- '8' => '۸', # ۸
- '9' => '۹', # ۹
+ '0' => '۰', # U+06F0
+ '1' => '۱', # U+06F1
+ '2' => '۲', # U+06F2
+ '3' => '۳', # U+06F3
+ '4' => '۴', # U+06F4
+ '5' => '۵', # U+06F5
+ '6' => '۶', # U+06F6
+ '7' => '۷', # U+06F7
+ '8' => '۸', # U+06F8
+ '9' => '۹', # U+06F9
];
$separatorTransformTable = [
- '.' => '٫', # ٫
- ',' => '٬', # ٬
+ '.' => '٫', # U+066B
+ ',' => '٬', # U+066C
];
$fallback8bitEncoding = 'windows-1256';
];
$digitTransformTable = [
- '0' => '០', # ០
- '1' => '១', # ១
- '2' => '២', # ២
- '3' => '៣', # ៣
- '4' => '៤', # ៤
- '5' => '៥', # ៥
- '6' => '៦', # ៦
- '7' => '៧', # ៧
- '8' => '៨', # ៨
- '9' => '៩', # ៩
+ '0' => '០', # U+17E0
+ '1' => '១', # U+17E1
+ '2' => '២', # U+17E2
+ '3' => '៣', # U+17E3
+ '4' => '៤', # U+17E4
+ '5' => '៥', # U+17E5
+ '6' => '៦', # U+17E6
+ '7' => '៧', # U+17E7
+ '8' => '៨', # U+17E8
+ '9' => '៩', # U+17E9
];
$separatorTransformTable = [
];
$digitTransformTable = [
- '0' => '೦', # ೦
- '1' => '೧', # ೧
- '2' => '೨', # ೨
- '3' => '೩', # ೩
- '4' => '೪', # ೪
- '5' => '೫', # ೫
- '6' => '೬', # ೬
- '7' => '೭', # ೭
- '8' => '೮', # ೮
- '9' => '೯', # ೯
+ '0' => '೦', # U+0CE6
+ '1' => '೧', # U+0CE7
+ '2' => '೨', # U+0CE8
+ '3' => '೩', # U+0CE9
+ '4' => '೪', # U+0CEA
+ '5' => '೫', # U+0CEB
+ '6' => '೬', # U+0CEC
+ '7' => '೭', # U+0CED
+ '8' => '೮', # U+0CEE
+ '9' => '೯', # U+0CEF
];
$digitGroupingPattern = "##,##,###";
];
$digitTransformTable = [
- '0' => '٠', # ٠
- '1' => '١', # ١
- '2' => '٢', # ٢
- '3' => '٣', # ٣
- '4' => '٤', # ٤
- '5' => '٥', # ٥
- '6' => '٦', # ٦
- '7' => '٧', # ٧
- '8' => '٨', # ٨
- '9' => '٩', # ٩
+ '0' => '٠', # U+0660
+ '1' => '١', # U+0661
+ '2' => '٢', # U+0662
+ '3' => '٣', # U+0663
+ '4' => '٤', # U+0664
+ '5' => '٥', # U+0665
+ '6' => '٦', # U+0666
+ '7' => '٧', # U+0667
+ '8' => '٨', # U+0668
+ '9' => '٩', # U+0669
];
$separatorTransformTable = [
- '.' => '٫', # ٫
- ',' => '٬', # ٬
+ '.' => '٫', # U+066B
+ ',' => '٬', # U+066C
];
];
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
$rtl = true;
$digitTransformTable = [
- '0' => '٠', # ٠
- '1' => '١', # ١
- '2' => '٢', # ٢
- '3' => '٣', # ٣
- '4' => '٤', # ٤
- '5' => '٥', # ٥
- '6' => '٦', # ٦
- '7' => '٧', # ٧
- '8' => '٨', # ٨
- '9' => '٩', # ٩
+ '0' => '٠', # U+0660
+ '1' => '١', # U+0661
+ '2' => '٢', # U+0662
+ '3' => '٣', # U+0663
+ '4' => '٤', # U+0664
+ '5' => '٥', # U+0665
+ '6' => '٦', # U+0666
+ '7' => '٧', # U+0667
+ '8' => '٨', # U+0668
+ '9' => '٩', # U+0669
];
$separatorTransformTable = [
- '.' => '٫', # ٫
- ',' => '٬', # ٬
+ '.' => '٫', # U+066B
+ ',' => '٬', # U+066C
];
];
$digitTransformTable = [
- '0' => '໐', # ໐
- '1' => '໑', # ໑
- '2' => '໒', # ໒
- '3' => '໓', # ໓
- '4' => '໔', # ໔
- '5' => '໕', # ໕
- '6' => '໖', # ໖
- '7' => '໗', # ໗
- '8' => '໘', # ໘
- '9' => '໙', # ໙
+ '0' => '໐', # U+0ED0
+ '1' => '໑', # U+0ED1
+ '2' => '໒', # U+0ED2
+ '3' => '໓', # U+0ED3
+ '4' => '໔', # U+0ED4
+ '5' => '໕', # U+0ED5
+ '6' => '໖', # U+0ED6
+ '7' => '໗', # U+0ED7
+ '8' => '໘', # U+0ED8
+ '9' => '໙', # U+0ED9
];
];
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
$linkTrail = "/^([\u{0900}-\u{0963}\u{0971}-\u{097F}\u{FEFF}\u{200D}]+)(.*)$/sDu";
];
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
];
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
*/
$digitTransformTable = [
- '0' => '୦', # ୦
- '1' => '୧', # ୧
- '2' => '୨', # ୨
- '3' => '୩', # ୩
- '4' => '୪', # ୪
- '5' => '୫', # ୫
- '6' => '୬', # ୬
- '7' => '୭', # ୭
- '8' => '୮', # ୮
- '9' => '୯', # ୯
+ '0' => '୦', # U+0B66
+ '1' => '୧', # U+0B67
+ '2' => '୨', # U+0B68
+ '3' => '୩', # U+0B69
+ '4' => '୪', # U+0B6A
+ '5' => '୫', # U+0B6B
+ '6' => '୬', # U+0B6C
+ '7' => '୭', # U+0B6D
+ '8' => '୮', # U+0B6E
+ '9' => '୯', # U+0B6F
];
$linkTrail = "/^([a-z\x{0B00}-\x{0B7F}]+)(.*)$/sDu";
];
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
$rtl = true;
$digitTransformTable = [
- '0' => '۰', # ᝶
- '1' => '۱', # ᝷
- '2' => '۲', # ᝸
- '3' => '۳', # ᝹
- '4' => '۴', # ក
- '5' => '۵', # ខ
- '6' => '۶', # គ
- '7' => '۷', # ឃ
- '8' => '۸', # ង
- '9' => '۹', # ច
+ '0' => '۰', # U+06F0
+ '1' => '۱', # U+06F1
+ '2' => '۲', # U+06F2
+ '3' => '۳', # U+06F3
+ '4' => '۴', # U+06F4
+ '5' => '۵', # U+06F5
+ '6' => '۶', # U+06F6
+ '7' => '۷', # U+06F7
+ '8' => '۸', # U+06F8
+ '9' => '۹', # U+06F9
];
$separatorTransformTable = [
- '.' => '٫', # ٫
- ',' => '٬', # ٬
+ '.' => '٫', # U+066B
+ ',' => '٬', # U+066C
];
$namespaceNames = [
$fallback = 'hi';
$digitTransformTable = [
- '0' => '०', # ०
- '1' => '१', # १
- '2' => '२', # २
- '3' => '३', # ३
- '4' => '४', # ४
- '5' => '५', # ५
- '6' => '६', # ६
- '7' => '७', # ७
- '8' => '८', # ८
- '9' => '९', # ९
+ '0' => '०', # U+0966
+ '1' => '१', # U+0967
+ '2' => '२', # U+0968
+ '3' => '३', # U+0969
+ '4' => '४', # U+096A
+ '5' => '५', # U+096B
+ '6' => '६', # U+096C
+ '7' => '७', # U+096D
+ '8' => '८', # U+096E
+ '9' => '९', # U+096F
];
$linkPrefixExtension = false;
$rtl = true;
$digitTransformTable = [
- '0' => '۰', # ۰
- '1' => '۱', # ۱
- '2' => '۲', # ۲
- '3' => '۳', # ۳
- '4' => '۴', # ۴
- '5' => '۵', # ۵
- '6' => '۶', # ۶
- '7' => '۷', # ۷
- '8' => '۸', # ۸
- '9' => '۹', # ۹
- '%' => '٪', # ٪
+ '0' => '۰', # U+06F0
+ '1' => '۱', # U+06F1
+ '2' => '۲', # U+06F2
+ '3' => '۳', # U+06F3
+ '4' => '۴', # U+06F4
+ '5' => '۵', # U+06F5
+ '6' => '۶', # U+06F6
+ '7' => '۷', # U+06F7
+ '8' => '۸', # U+06F8
+ '9' => '۹', # U+06F9
+ '%' => '٪', # U+066A
];
);
}
$this->total += $dbw->affectedRows();
+ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication();
}
/**
END;
$struct = $this->getStructure( $text );
$this->assertEquals( "Opening text is opening.", $struct->getOpeningText() );
- $this->assertEquals( "Opening text is opening. Then we got more text",
+ $this->assertEquals( "Opening text is opening. Then we got more text",
$struct->getMainText() );
$this->assertEquals( [ "Header table row in table another row in table" ],
$struct->getAuxiliaryText() );
}
+
+ public function testPreservesWordSpacing() {
+ $text = "<dd><dl>foo</dl><dl>bar</dl></dd><p>baz</p>";
+ $struct = $this->getStructure( $text );
+ $this->assertEquals( "foo bar baz", $struct->getMainText() );
+ }
}
public function provideStripAllTags() {
return [
[ '<p>Foo</p>', 'Foo' ],
- [ '<p id="one">Foo</p><p id="two">Bar</p>', 'FooBar' ],
+ [ '<p id="one">Foo</p><p id="two">Bar</p>', 'Foo Bar' ],
[ "<p>Foo</p>\n<p>Bar</p>", 'Foo Bar' ],
[ '<p>Hello <strong> world café</p>', 'Hello <strong> world café' ],
[