summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/includes/Highlighter.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/includes/Highlighter.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/includes/Highlighter.php370
1 files changed, 370 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/includes/Highlighter.php b/www/wiki/extensions/SemanticMediaWiki/includes/Highlighter.php
new file mode 100644
index 00000000..6b659346
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/includes/Highlighter.php
@@ -0,0 +1,370 @@
+<?php
+
+namespace SMW;
+
+use Html;
+use SMWOutputs;
+
+/**
+ * Highlighter utility function for Semantic MediaWiki
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+class Highlighter {
+
+ /**
+ * Highlighter ID for no types
+ */
+ const TYPE_NOTYPE = 0;
+
+ /**
+ * Highlighter ID for properties
+ */
+ const TYPE_PROPERTY = 1;
+
+ /**
+ * Highlighter ID for text
+ */
+ const TYPE_TEXT = 2;
+
+ /**
+ * Highlighter ID for quantities
+ */
+ const TYPE_QUANTITY = 3;
+
+ /**
+ * Highlighter ID for warnings
+ */
+ const TYPE_WARNING = 4;
+
+ /**
+ * Highlighter ID for error
+ */
+ const TYPE_ERROR = 5;
+
+ /**
+ * Highlighter ID for information
+ */
+ const TYPE_INFO = 6;
+
+ /**
+ * Highlighter ID for help
+ */
+ const TYPE_HELP = 7;
+
+ /**
+ * Highlighter ID for notes
+ */
+ const TYPE_NOTE = 8;
+
+ /**
+ * Highlighter ID for service links
+ */
+ const TYPE_SERVICE = 9;
+
+ /**
+ * Highlighter ID for reference links
+ */
+ const TYPE_REFERENCE = 10;
+
+ /**
+ * @var array $options
+ */
+ private $options;
+
+ /**
+ * @var int $type
+ */
+ private $type;
+
+ /**
+ * @var string|null
+ */
+ private $language = null;
+
+ /**
+ * @since 1.9
+ *
+ * @param int $type
+ * @param string|null $language
+ */
+ public function __construct( $type, $language = null ) {
+ $this->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 booelan
+ */
+ 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(
+ [ '&amp;', '&lt;', '&gt;', '&#160;', '<nowiki>', '</nowiki>' ],
+ [ '&', '<', '>', ' ', '', '' ],
+ $text
+ );
+ }
+
+ /**
+ * Returns html output
+ *
+ * @since 1.9
+ *
+ * @return string
+ */
+ public function getHtml() {
+ SMWOutputs::requireResource( 'ext.smw.tooltips' );
+ 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 integer
+ */
+ 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;
+ $style = [];
+
+ if ( isset( $this->options['style'] ) ) {
+ $style = [ 'style' => $this->options['style'] ];
+ }
+
+ // #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
+ ] + $style,
+ Html::rawElement(
+ 'span',
+ [
+ 'class' => $captionclass
+ ],
+ $this->options['caption']
+ ) . Html::rawElement(
+ 'span',
+ [
+ 'class' => 'smwttcontent'
+ ],
+ htmlspecialchars_decode( $this->options['content'] )
+ )
+ );
+
+ return $html;
+ }
+
+ /**
+ * Returns initial configuration settings
+ *
+ * @note You could create a class per entity type but does this
+ * really make sense just to get some configuration parameters?
+ *
+ * @since 1.9
+ *
+ * @param string $type
+ *
+ * @return array
+ */
+ private function getTypeConfiguration( $type ) {
+ $settings = [];
+ $settings['type'] = $type;
+ $settings['caption'] = '';
+ $settings['content'] = '';
+
+ switch ( $type ) {
+ case self::TYPE_PROPERTY:
+ $settings['state'] = 'inline';
+ $settings['title'] = 'smw-ui-tooltip-title-property';
+ $settings['captionclass'] = 'smwbuiltin';
+ break;
+ case self::TYPE_TEXT:
+ $settings['state'] = 'persistent';
+ $settings['title'] = 'smw-ui-tooltip-title-info';
+ $settings['captionclass'] = 'smwtext';
+ break;
+ case self::TYPE_QUANTITY:
+ $settings['state'] = 'inline';
+ $settings['title'] = 'smw-ui-tooltip-title-quantity';
+ $settings['captionclass'] = 'smwtext';
+ break;
+ case self::TYPE_NOTE:
+ $settings['state'] = 'inline';
+ $settings['title'] = 'smw-ui-tooltip-title-note';
+ $settings['captionclass'] = 'smwtticon note';
+ break;
+ case self::TYPE_WARNING:
+ $settings['state'] = 'inline';
+ $settings['title'] = 'smw-ui-tooltip-title-warning';
+ $settings['captionclass'] = 'smwtticon warning';
+ break;
+ case self::TYPE_ERROR:
+ $settings['state'] = 'inline';
+ $settings['title'] = 'smw-ui-tooltip-title-error';
+ $settings['captionclass'] = 'smwtticon error';
+ break;
+ case self::TYPE_SERVICE:
+ $settings['state'] = 'persistent';
+ $settings['title'] = 'smw-ui-tooltip-title-service';
+ $settings['captionclass'] = 'smwtticon service';
+ break;
+ case self::TYPE_REFERENCE:
+ $settings['state'] = 'persistent';
+ $settings['title'] = 'smw-ui-tooltip-title-reference';
+ $settings['captionclass'] = 'smwtext';
+ break;
+ case self::TYPE_HELP:
+ case self::TYPE_INFO:
+ $settings['state'] = 'persistent';
+ $settings['title'] = 'smw-ui-tooltip-title-info';
+ $settings['captionclass'] = 'smwtticon info';
+ break;
+ case self::TYPE_NOTYPE:
+ default:
+ $settings['state'] = 'persistent';
+ $settings['title'] = 'smw-ui-tooltip-title-info';
+ $settings['captionclass'] = 'smwbuiltin';
+ };
+
+ return $settings;
+ }
+
+ private function title( $content, $language ) {
+
+ // Pre-process the content when used as title to avoid breaking elements
+ // (URLs etc.)
+ if ( strpos( $content, '[' ) !== false || strpos( $content, '//' ) !== false ) {
+ $content = Message::get( [ 'smw-parse', $content ], Message::PARSE, $language );
+ }
+
+ return strip_tags( htmlspecialchars_decode( str_replace( [ "[", '&#160;' ], [ "&#91;", ' ' ], $content ) ) );
+ }
+
+}