*
* @param $element string The element's name, e.g., 'a'
* @param $attribs array Associative array of attributes, e.g., array(
- * 'href' => 'http://www.mediawiki.org/' ). Values will be HTML-escaped.
- * A value of false means to omit the attribute.
+ * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for
+ * further documentation.
* @param $contents string The raw HTML contents of the element: *not*
* escaped!
* @return string Raw HTML
*/
public static function rawElement( $element, $attribs = array(), $contents = '' ) {
global $wgHtml5, $wgWellFormedXml;
+ $attribs = (array)$attribs;
# This is not required in HTML 5, but let's do it anyway, for
# consistency and better compression.
$element = strtolower( $element );
*
* @param $element string Name of the element, e.g., 'a'
* @param $attribs array Associative array of attributes, e.g., array(
- * 'href' => 'http://www.mediawiki.org/' ).
+ * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for
+ * further documentation.
* @return array An array of attributes functionally identical to $attribs
*/
private static function dropDefaults( $element, $attribs ) {
+ # Don't bother doing anything if we aren't outputting HTML5; it's too
+ # much of a pain to maintain two sets of defaults.
+ global $wgHtml5;
+ if ( !$wgHtml5 ) {
+ return $attribs;
+ }
+
static $attribDefaults = array(
'area' => array( 'shape' => 'rect' ),
'button' => array(
*
* @param $attribs array Associative array of attributes, e.g., array(
* 'href' => 'http://www.mediawiki.org/' ). Values will be HTML-escaped.
- * A value of false means to omit the attribute.
+ * A value of false means to omit the attribute. For boolean attributes,
+ * you can omit the key, e.g., array( 'checked' ) instead of
+ * array( 'checked' => 'checked' ) or such.
* @return string HTML fragment that goes between element name and '>'
* (starting with a space if at least one attribute is output)
*/
global $wgHtml5, $wgWellFormedXml;
$ret = '';
+ $attribs = (array)$attribs;
foreach ( $attribs as $key => $value ) {
if ( $value === false ) {
continue;
# marks omitted, but not all. (Although a literal " is not
# permitted, we don't check for that, since it will be escaped
# anyway.)
+ #
+ # See also research done on further characters that need to be
+ # escaped: http://code.google.com/p/html5lib/issues/detail?id=93
+ $badChars = "\\x00- '=<>`/\x{00a0}\x{1680}\x{180e}\x{180F}\x{2000}\x{2001}"
+ . "\x{2002}\x{2003}\x{2004}\x{2005}\x{2006}\x{2007}\x{2008}\x{2009}"
+ . "\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}";
if ( $wgWellFormedXml || $value === ''
- || preg_match( "/[ '=<>]/", $value ) ) {
+ || preg_match( "![$badChars]!u", $value ) ) {
$quote = '"';
} else {
$quote = '';
# and we don't need <> escaped here, we may as well not call
# htmlspecialchars(). FIXME: verify that we actually need to
# escape \n\r\t here, and explain why, exactly.
- if ( $wgHtml5 ) {
- $ret .= " $key=$quote" . strtr( $value, array(
- '&' => '&',
- '"' => '"',
- "\n" => ' ',
- "\r" => ' ',
- "\t" => '	'
- ) ) . $quote;
- } else {
- $ret .= " $key=$quote" . Sanitizer::encodeAttribute( $value ) . $quote;
+ #
+ # We could call Sanitizer::encodeAttribute() for this, but we
+ # don't because we're stubborn and like our marginal savings on
+ # byte size from not having to encode unnecessary quotes.
+ $map = array(
+ '&' => '&',
+ '"' => '"',
+ "\n" => ' ',
+ "\r" => ' ',
+ "\t" => '	'
+ );
+ if ( $wgWellFormedXml ) {
+ # '<' must be escaped in attributes for XML for some
+ # reason, per spec: http://www.w3.org/TR/xml/#NT-AttValue
+ $map['<'] = '<';
}
+ $ret .= " $key=$quote" . strtr( $value, $map ) . $quote;
}
}
return $ret;