aboutsummaryrefslogtreecommitdiffstats
path: root/includes/Html
diff options
context:
space:
mode:
authorLucas Werkmeister <lucas.werkmeister@wikimedia.de>2023-07-13 17:44:35 +0200
committerJames D. Forrester <jforrester@wikimedia.org>2023-07-14 13:42:02 -0400
commit3c5a0c862f834b791d6ac020a26f1d3d401bb34f (patch)
treef737f7adaa05cebfcf897e18c91631ba3cfd9894 /includes/Html
parentb45e48b35c04c93c9c1cf70b76ac92b0cbf713ea (diff)
downloadmediawikicore-3c5a0c862f834b791d6ac020a26f1d3d401bb34f.tar.gz
mediawikicore-3c5a0c862f834b791d6ac020a26f1d3d401bb34f.zip
Html: Move encodeJsVar() + encodeJsCall() from Xml
These methods really belong in the Html class, not Xml. Leave behind soft-deprecated Xml methods that forward to the Html ones, as well as a class alias for HtmlJsCode (renamed from XmlJsCode). Bug: T341779 Change-Id: I99a5f9de1411d4eb5ee30226b4e8ace3ea8b2c3b
Diffstat (limited to 'includes/Html')
-rw-r--r--includes/Html/Html.php45
-rw-r--r--includes/Html/HtmlJsCode.php81
2 files changed, 126 insertions, 0 deletions
diff --git a/includes/Html/Html.php b/includes/Html/Html.php
index ceb85f2a5ff0..e4f145b8802f 100644
--- a/includes/Html/Html.php
+++ b/includes/Html/Html.php
@@ -25,6 +25,7 @@
namespace MediaWiki\Html;
+use FormatJson;
use InvalidArgumentException;
use MediaWiki\MainConfigNames;
use MediaWiki\MediaWikiServices;
@@ -1149,6 +1150,50 @@ class Html {
return implode( ", ", $candidates );
}
+
+ /**
+ * Encode a variable of arbitrary type to JavaScript.
+ * If the value is an HtmlJsCode object, pass through the object's value verbatim.
+ *
+ * @note Only use this function for generating JavaScript code. If generating output
+ * for a proper JSON parser, just call FormatJson::encode() directly.
+ *
+ * @since 1.41 (previously on {@link Xml})
+ * @param mixed $value The value being encoded. Can be any type except a resource.
+ * @param bool $pretty If true, add non-significant whitespace to improve readability.
+ * @return string|false String if successful; false upon failure
+ */
+ public static function encodeJsVar( $value, $pretty = false ) {
+ if ( $value instanceof HtmlJsCode ) {
+ return $value->value;
+ }
+ return FormatJson::encode( $value, $pretty, FormatJson::UTF8_OK );
+ }
+
+ /**
+ * Create a call to a JavaScript function. The supplied arguments will be
+ * encoded using Html::encodeJsVar().
+ *
+ * @since 1.41 (previously on {@link Xml} since 1.17)
+ * @param string $name The name of the function to call, or a JavaScript expression
+ * which evaluates to a function object which is called.
+ * @param array $args The arguments to pass to the function.
+ * @param bool $pretty If true, add non-significant whitespace to improve readability.
+ * @return string|false String if successful; false upon failure
+ */
+ public static function encodeJsCall( $name, $args, $pretty = false ) {
+ foreach ( $args as &$arg ) {
+ $arg = self::encodeJsVar( $arg, $pretty );
+ if ( $arg === false ) {
+ return false;
+ }
+ }
+
+ return "$name(" . ( $pretty
+ ? ( ' ' . implode( ', ', $args ) . ' ' )
+ : implode( ',', $args )
+ ) . ");";
+ }
}
class_alias( Html::class, 'Html' );
diff --git a/includes/Html/HtmlJsCode.php b/includes/Html/HtmlJsCode.php
new file mode 100644
index 000000000000..e857237f3902
--- /dev/null
+++ b/includes/Html/HtmlJsCode.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MediaWiki\Html;
+
+/**
+ * A wrapper class which causes Html::encodeJsVar() and Html::encodeJsCall()
+ * (as well as their Xml::* counterparts) to interpret a given string as being
+ * a JavaScript expression, instead of string data.
+ *
+ * @par Example:
+ * @code
+ * Html::encodeJsVar( new HtmlJsCode( 'a + b' ) );
+ * @endcode
+ *
+ * This returns "a + b".
+ *
+ * @note As of 1.21, HtmlJsCode objects cannot be nested inside objects or arrays. The sole
+ * exception is the $args argument to Html::encodeJsCall() because Html::encodeJsVar() is
+ * called for each individual element in that array. If you need to encode an object or array
+ * containing HtmlJsCode objects, use HtmlJsCode::encodeObject() to re-encode it first.
+ *
+ * @since 1.41 (renamed from XmlJsCode, which existed since 1.17)
+ */
+class HtmlJsCode {
+ public $value;
+
+ public function __construct( $value ) {
+ $this->value = $value;
+ }
+
+ /**
+ * Encode an object containing HtmlJsCode objects.
+ *
+ * This takes an object or associative array where (some of) the values are HtmlJsCode objects,
+ * and re-encodes it as a single HtmlJsCode object.
+ *
+ * @since 1.33
+ * @phpcs:ignore MediaWiki.Commenting.FunctionComment.ObjectTypeHintParam
+ * @param object|array $obj Object or associative array to encode
+ * @param bool $pretty If true, add non-significant whitespace to improve readability.
+ * @return HtmlJsCode
+ */
+ public static function encodeObject( $obj, $pretty = false ) {
+ $parts = [];
+ foreach ( $obj as $key => $value ) {
+ $parts[] =
+ ( $pretty ? ' ' : '' ) .
+ Html::encodeJsVar( $key, $pretty ) .
+ ( $pretty ? ': ' : ':' ) .
+ Html::encodeJsVar( $value, $pretty );
+ }
+ return new self(
+ '{' .
+ ( $pretty ? "\n" : '' ) .
+ implode( $pretty ? ",\n" : ',', $parts ) .
+ ( $pretty ? "\n" : '' ) .
+ '}'
+ );
+ }
+}
+
+/** @deprecated since 1.41 */
+class_alias( HtmlJsCode::class, 'XmlJsCode' );