type = $type; $this->language = $language; } /** * @since 1.9 * * @param string|int $type * @param string|null $language * * @return Highlighter */ public static function factory( $type, $language = null ) { if ( $type === '' || !is_int( $type ) ) { $type = self::getTypeId( $type ); } return new Highlighter( $type, $language ); } /** * @since 3.0 * * @param string $text * @param string|null $type * * @return bool */ public static function hasHighlighterClass( $text, $type = null ) { if ( strpos( $text, 'smw-highlighter' ) === false ) { return false; } if ( $type !== null ) { return strpos( $text, 'data-type="' . self::getTypeId( $type ) . '"' ) !== false; } return true; } /** * @since 3.0 * * @param string $text * * @return string */ public static function decode( $text ) { // #2347, '[' is handled by the MediaWiki parser/sanitizer itself return str_replace( [ '&', '<', '>', ' ', '', '' ], [ '&', '<', '>', ' ', '', '' ], $text ); } /** * Returns html output * * @since 1.9 * * @return string */ public function getHtml() { SMWOutputs::requireStyle( 'ext.smw.styles' ); SMWOutputs::requireStyle( 'ext.smw.tooltip.styles' ); SMWOutputs::requireResource( 'ext.smw.tooltip' ); return $this->getContainer(); } /** * Set content * * An external class that invokes content via setContent has to ensure * that all data are appropriately escaped. * * @since 1.9 * * @param array $content * * @return array */ public function setContent( array $content ) { /** * @var $content * $content['caption'] = a text or null * $content['context'] = a text or null */ return $this->options = array_merge( $this->getTypeConfiguration( $this->type ), $content ); } /** * Returns type id * * @since 1.9 * * @param string $type * * @return int */ public static function getTypeId( $type ) { // TODO: why do we have a htmlspecialchars here?! switch ( strtolower( htmlspecialchars( $type ?? '' ) ) ) { case 'property': return self::TYPE_PROPERTY; case 'text': return self::TYPE_TEXT; case 'quantity': return self::TYPE_QUANTITY; case 'warning': return self::TYPE_WARNING; case 'error': return self::TYPE_ERROR; case 'info': return self::TYPE_INFO; case 'help': return self::TYPE_HELP; case 'note': return self::TYPE_NOTE; case 'service': return self::TYPE_SERVICE; case 'reference': return self::TYPE_REFERENCE; default: return self::TYPE_NOTYPE; } } /** * Builds Html container * * Content that is being invoked has to be escaped * @see Highlighter::setContent * * @since 1.9 * * @return string */ private function getContainer() { $captionclass = $this->options['captionclass']; // 2.4+ can display context for user-defined properties, here we ensure // to keep the style otherwise it displays italic which is by convention // reserved for predefined properties if ( $this->type === self::TYPE_PROPERTY && isset( $this->options['userDefined'] ) ) { $captionclass = $this->options['userDefined'] ? 'smwtext' : $captionclass; } $language = is_string( $this->language ) ? $this->language : Message::USER_LANGUAGE; $attribs = []; if ( isset( $this->options['style'] ) ) { $attribs['style'] = $this->options['style']; } if ( isset( $this->options['maxwidth'] ) && $this->options['maxwidth'] !== '' ) { $attribs['data-maxwidth'] = $this->options['maxwidth']; } if ( isset( $this->options['themeclass'] ) && $this->options['themeclass'] !== '' ) { $attribs['data-tooltipclass'] = $this->options['themeclass']; } // In case the text contains HTML, remove trailing line feeds to avoid breaking // the display if ( $this->options['content'] != strip_tags( $this->options['content'] ?? '' ) ) { $this->options['content'] = str_replace( [ "\n" ], [ '' ], $this->options['content'] ); } // #1875 // title attribute contains stripped content to allow for a display in // no-js environments, the tooltip will remove the element once it is // loaded $title = $this->title( $this->options['content'], $language ); $html = Html::rawElement( 'span', [ 'class' => 'smw-highlighter', 'data-type' => $this->options['type'], 'data-content' => isset( $this->options['data-content'] ) ? $this->options['data-content'] : null, 'data-state' => $this->options['state'], 'data-title' => Message::get( $this->options['title'], Message::TEXT, $language ), 'title' => $title ] + $attribs, Html::rawElement( 'span', [ 'class' => $captionclass ], $this->options['caption'] ) . Html::rawElement( 'span', [ 'class' => 'smwttcontent' ], // Embedded wiki content that has other elements like (e.g.