diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..677166a --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "devium/toml": "*" + } +} diff --git a/extension.json b/extension.json new file mode 100644 index 0000000..b051000 --- /dev/null +++ b/extension.json @@ -0,0 +1,21 @@ +{ + "name": "AnatImageViewer", + "author": "Justin Georgi", + "url": "https://gitea.azgeorgis.net/jgeorgi/AnatImageViewer", + "description": "This extension allows the creation of .an pages in the Files namespace which will be annotated images.", + "version": "0.0.1", + "license-name": "MIT", + "type": "media", + "manifest_version": 1, + "AutoloadNamespaces": { + "MediaWiki\\Extension\\AnatImageViewer\\": "includes/" + }, + "MediaHandlers": { + "image/annotation": "MediaWiki\\Extension\\AnatImageViewer\\AnatImageHandler" + }, + "Hooks": { + "MimeMagicInit": "MediaWiki\\Extension\\AnatImageViewer\\AnatImageHooks::onMimeMagicInit", + "MimeMagicImproveFromExtension": "MediaWiki\\Extension\\AnatImageViewer\\AnatImageHooks::onMimeMagicImproveFromExtension", + "ParserFirstCallInit": "MediaWiki\\Extension\\AnatImageViewer\\AnatImageHooks::onParserFirstCallInit" + } +} \ No newline at end of file diff --git a/includes/AnatImageHandler.php b/includes/AnatImageHandler.php new file mode 100644 index 0000000..6c9eb32 --- /dev/null +++ b/includes/AnatImageHandler.php @@ -0,0 +1,63 @@ +validateParam() + * @param int $flags A bitfield, may contain self::TRANSFORM_LATER + * @return MediaTransformOutput + */ + public function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0) { + return new AnatImageTransformOutput($image, $params); + } + + /** + * Small helper function to display information on the browser console + * + * Usage: + * echo ''; + * + * @param $data information to display + * @param bool $add_script_tags true to put information is inside complete script tag + */ + public static function console_log($data, $add_script_tags = false) { + $command = 'console.log('. json_encode($data, JSON_HEX_TAG).');'; + if ($add_script_tags) { + $command = ''; + } + echo $command; + } +} \ No newline at end of file diff --git a/includes/AnatImageHooks.php b/includes/AnatImageHooks.php new file mode 100644 index 0000000..58a5197 --- /dev/null +++ b/includes/AnatImageHooks.php @@ -0,0 +1,77 @@ +addExtraTypes('image/annotation an'); + $mime->addExtraInfo('image/annotation [METAIMAGE]'); + } + + /** + * MWHook: Make sure that an files (fake) get the proper mime assignement on upload + * + * @see https://www.mediawiki.org/wiki/Manual:Hooks/MimeMagicImproveFromExtension + * + * @param MimeAnalyzer $mimeAnalyzer Instance of MW MimeAnalyzer object + * @param string $ext extention of upload file + * @param string &$mime current assigned mime type + */ + public static function onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, &$mime ) { + if ( $mime !== 'image/annotation' && in_array( $ext, ['an'] ) ) { + $mime = 'image/annotation'; + } + } + + /** + * MWHook: Called when the parser initializes for the first time + * + * @param Parser $parser: Parser object being initialized + */ + static function onParserFirstCallInit( $parser ) { + $parser->setHook('anconfig', array( __CLASS__, 'renderConfigTag')); + } + + /** + * Render the config toml in a
tag
+ *
+ * @param $input The text inside the custom tag
+ * @param array $args Any attributes given in the tag
+ * @param Parser $parser The parser object
+ * @param PPFrame $frame The parent frame calling the parser
+ * @return string HTML string of output
+ */
+ static function renderConfigTag( $input, array $args, $parser, $frame ) {
+ return '' . $input . '
';
+ }
+
+ /**
+ * Small helper function to display information on the browser console
+ *
+ * Usage:
+ * echo '';
+ *
+ * @param $data information to display
+ * @param bool $add_script_tags true to put information is inside complete script tag
+ */
+ public static function console_log($data, $add_script_tags = false) {
+ $command = 'console.log('. json_encode($data, JSON_HEX_TAG).');';
+ if ($add_script_tags) {
+ $command = '';
+ }
+ echo $command;
+ }
+}
\ No newline at end of file
diff --git a/includes/AnatImageTransformOutput.php b/includes/AnatImageTransformOutput.php
new file mode 100644
index 0000000..42ad3c4
--- /dev/null
+++ b/includes/AnatImageTransformOutput.php
@@ -0,0 +1,124 @@
+file = $file;
+ $this->parameters = $parameters;
+ }
+
+ /**
+ * Fetch HTML for this transform output
+ *
+ * @access public
+ * @param array $options Associative array of options. Boolean options
+ * should be indicated with a value of true for true, and false or
+ * absent for false.
+ * alt Alternate text or caption
+ * desc-link Boolean, show a description link
+ * file-link Boolean, show a file download link
+ * custom-url-link Custom URL to link to
+ * custom-title-link Custom Title object to link to
+ * valign vertical-align property, if the output is an inline element
+ * img-class Class applied to the "
" tag, if there is such a tag
+ * preview Boolean, render is being called from a preview page
+ *
+ * @return string HTML
+ */
+ public function toHtml($options = []) {
+ $descriptText = $this->file->getDescriptionText();
+ preg_match('/([\S\s]*?)<\/pre>/',$descriptText,$annotDescript);
+ $metadata = toml_decode($annotDescript[1], true);
+
+ if (isset($metadata['baseImage'])) {
+ $baseImage = MediaWikiServices::getInstance()->getRepoGroup()->findFile(`File:` . $metadata['baseImage']);
+ } else {
+ $baseImage = false;
+ }
+
+ return self::buildSvg($metadata,$baseImage);
+ }
+
+ /**
+ * Build annotated SVG from TOML metadata
+ *
+ * This takes in the metadata text from the file page (or the current editor)
+ * and produces the html string for the svg with base image and annotations.
+ *
+ * @param string $metadata The metadata object parsed from the text
+ * @param string $baseImageUrl The full url pointing to the base image to annotate
+ * @param array $frameParams The additional user defined parameters for the viewer such as hotspot and view classes
+ * @return string Html string of the complete model-viewer element inside a div container
+ */
+ private function buildSvg($metadata, $baseImage) {
+ //Gather basic data
+ $elBaseImg = '';
+ $vbHeight = 100;
+ $vbWidth = 100;
+ if ($baseImage) {
+ $baseImageUrl = $baseImage->getFullUrl();
+ $baseHeight = $baseImage->getHeight();
+ $baseWidth = $baseImage->getWidth();
+ $baseAspect = $baseHeight / $baseWidth;
+ $vbWidth = 100 / sqrt($baseAspect);
+ $vbHeight = $baseAspect * $vbWidth;
+ $attrBase = array(
+ 'class' => 'annot-base',
+ 'preserveAspectRatio' => 'none',
+ 'width' => $vbWidth,
+ 'height' => $vbHeight,
+ 'href' => $baseImageUrl
+ );
+ $elBaseImg = Html::rawElement('image', $attrBase);
+ }
+ $mainConfig = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+ $context = RequestContext::getMain();
+
+ //Render and return svg
+ $attrSvg = array(
+ 'class' => 'annot-svg',
+ 'version' => '1.1',
+ 'viewBox' => "0 0 {$vbWidth} {$vbHeight}",
+ 'xml:space' => 'preserve',
+ 'xmlns' => 'http://www.w3.org/2000/svg'
+ );
+
+ return Html::rawElement('svg', $attrSvg, $elBaseImg);
+ }
+
+ /**
+ * Small helper function to display information on the browser console
+ *
+ * Usage:
+ * echo '';
+ *
+ * @param $data information to display
+ * @param bool $add_script_tags true to put information is inside complete script tag
+ */
+ public static function console_log($data, $add_script_tags = false) {
+ $command = 'console.log('. json_encode($data, JSON_HEX_TAG).');';
+ if ($add_script_tags) {
+ $command = '';
+ }
+ echo $command;
+ }
+}
\ No newline at end of file