Gergő Tisza has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/362319 )
Change subject: [WIP] Render TOC with vivliostyle
......................................................................
[WIP] Render TOC with vivliostyle
Adds the ability to display books in vivliostyle viewer.
(Note that vivliostyle has AGPL license. It is not included
in the patch, needs to be installed via composer.)
Bug: T168004
Change-Id: I1144c57ae3d23da0aa23b40122bdcf20d0ec7b94
---
M Collection.php
M SpecialRenderBook.php
M composer.json
M includes/BookRenderer.php
D modules/offline.css
A modules/offline.less
6 files changed, 186 insertions(+), 49 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Collection
refs/changes/19/362319/1
diff --git a/Collection.php b/Collection.php
index fc989a6..adee851 100644
--- a/Collection.php
+++ b/Collection.php
@@ -258,10 +258,29 @@
'dependencies' => 'ext.collection.bookcreator'
],
'ext.collection.offline' => $collResourceTemplate + [
- 'styles' => 'offline.css',
+ 'styles' => 'offline.less',
+ ],
+ 'vivliostyle' => [
+ 'localBasePath' => __DIR__ . '/vivliostyle-viewer',
+ 'remoteExtPath' => 'Collection/vivliostyle-viewer',
+ 'scripts' => [
+ 'js/main.js',
+ 'js/load.js',
+ ],
+ 'styles' => [
+ 'resources/vivliostyle-viewport.css',
+ // skipping resources/vivliostyle-viewport-screen.css -
not relevant for print
+ 'css/vivliostyle-viewer.css',
+ 'css/ui.arrows.css',
+ 'css/ui.menu-bar.css',
+ 'css/ui.message-dialog.css',
+ 'css/ui.loading-overlay.css',
+ ],
],
];
+$wgCollectionVivlioHtml = __DIR__ .
'/vivliostyle-viewer/vivliostyle-viewer.html';
+
# register global Ajax functions:
function wfAjaxGetCollection() {
diff --git a/SpecialRenderBook.php b/SpecialRenderBook.php
index f45fa9c..2002533 100644
--- a/SpecialRenderBook.php
+++ b/SpecialRenderBook.php
@@ -2,7 +2,6 @@
use MediaWiki\Extensions\Collection\BookRenderer;
use MediaWiki\Extensions\Collection\DataProvider;
-use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
function d($x) {
@@ -30,16 +29,27 @@
}
public function execute( $subPage ) {
+ $key = null;
$out = $this->getOutput();
+ if ( substr( $subPage, 0, 6 ) === 'share/' ) {
+ $subPage = 'raw';
+ $key = substr( $subPage, 6 );
+ }
switch ( $subPage ) {
+ case 'refresh':
+ $book = $this->getBook( '-' );
+ $url = $this->getPageTitle()->getFullURL( [
'key' => $book['key'] ] );
+ $out->redirect( $url );
+ return;
+
case 'raw':
$context = new DerivativeContext(
$this->getContext() );
$context->setSkin( new SkinApi() );
$out->setContext( $context );
// fall through
case 'skinned':
- $book = $this->getBook();
+ $book = $this->getBook( $key );
$out->addModuleStyles( [
'ext.collection.offline' ] );
$out->addModules( $book['modules'] );
$out->addModuleScripts( $book['modulescripts']
);
@@ -49,11 +59,13 @@
return;
case 'electron':
+ case 'electron-vivlio':
// FIXME should just redirect to /raw instead
and make that cacheable but
// need non-session-based storage for that
$book = $this->getBook();
- $bookUrl = $this->getPageTitle( 'skinned'
)->getFullURL( [ 'key' => $book['key'] ] );
+ $mode = ( $subPage === 'electron-vivlio' ) ?
'vivlio' : 'skinned';
+ $bookUrl = $this->getUrl( $mode, $book['key'] );
// hack hack
$electronUrl =
'http://electron.local.wmftest.net:10241/pdf';
$accessKey = 'secret';
@@ -67,15 +79,23 @@
default:
$options = [
+ 'refresh' => 'purge cache & re-render
book',
'raw' => 'HTML, raw',
'skinned' => 'HTML, as wiki page',
+ 'vivlio' => 'HTML, with vivliostyle
viewer',
'electron' => 'PDF, raw',
+ 'electron-vivlio' => 'PDF, with
vivliojs',
+ 'share' => 'shareable link to raw URL',
];
$html = Html::openElement( 'ul', [] );
foreach ( $options as $mode => $description ) {
- $linkUrl = $this->getPageTitle( $mode
)->getFullURL();
- $link = Html::element( 'a', [ 'href' =>
$linkUrl ], $description );
- $html .= Html::rawElement( 'li', [],
$link );
+ $linkUrl = $this->getUrl( $mode,
$this->getRequest()->getText( 'key', null ) );
+ if ( $linkUrl === false ) {
+ $html .= Html::element( 'li',
[], $mode . ": 'key' param needed" );
+ } else {
+ $link = Html::element( 'a', [
'href' => $linkUrl ], $description );
+ $html .= Html::rawElement(
'li', [], $link );
+ }
}
$html .= Html::closeElement( 'ul' );
$out->addHTML( $html );
@@ -84,17 +104,44 @@
}
/**
- * Get the HTML source for the book, from cache or by rendering it.
- * @return string[] associative array with:
- * - 'html': HTML, not including <body> or anything outside that.
- * - 'key': WAN cache key for the HTML
+ * Returns an URL for viewing the current or specified collection in
the given mode.
+ * @param string $mode A subpage key
+ * @param string $key Collection cache key.
+ * @return bool|string False if no cache key was provided and it is
required in the given mode.
*/
- private function getBook() {
- $key = $this->getRequest()->getText( 'key' );
+ private function getUrl( $mode, $key = null ) {
+ if ( $mode === 'share' && $key ) {
+ return $this->getPageTitle( 'share/' . $key
)->getFullURL();
+ } elseif ( $mode === 'vivlio' ) {
+ if ( !$key ) {
+ return false;
+ }
+ $bookUrl = $this->getPageTitle( 'share/' . $key
)->getFullURL();
+ $baseUrl = $this->getConfig()->get(
'ExtensionAssetsPath' ) . '/Collection';
+ $url = $baseUrl .
'/vendor/vivliostyle/viewer/viewer/vivliostyle-viewer.html#x=' . $bookUrl;
+ return wfExpandUrl( $url );
+ } else {
+ return $this->getPageTitle( $mode )->getFullURL( [
'key' => $key ] );
+ }
+
+ }
+
+ /**
+ * Get the HTML source for the book, from cache or by rendering it.
+ * @param string $key Cache key
+ * @return string[] associative array with:
+ * - html: HTML, not including <body> or anything outside that.
+ * - key: WAN cache key for the HTML
+ * - modules, modulescripts, modulestyles, jsconfigvars:
ResourceLoader data
+ */
+ private function getBook( $key = null ) {
+ if ( !$key ) {
+ $key = $this->getRequest()->getText( 'key' );
+ }
if ( $key ) {
- $html = $this->htmlCache->get( $key );
- if ( $html ) {
- return [ 'key' => $key, 'html' => $html ];
+ $book = $this->htmlCache->get( $key );
+ if ( $book ) {
+ return $book;
}
}
@@ -106,18 +153,20 @@
$metadata = $dataProvider->fetchMetadata( array_keys( $pages )
);
$html = $bookRenderer->renderBook( $collection, $pages,
$metadata );
- // TODO generate the key from the collection metadata instead
- $key = $this->htmlCache->makeGlobalKey( md5( $html ) );
- $this->htmlCache->set( $key, $html, 300 );
-
- return [
- 'key' => $key,
+ $book = [
'html' => $html,
'modules' => $metadata['modules'],
'modulescripts' => $metadata['modulescripts'],
'modulestyles' => $metadata['modulestyles'],
'jsconfigvars' => $metadata['jsconfigvars'],
];
+
+ // TODO generate the key from the collection metadata instead
+ $key = $this->htmlCache->makeGlobalKey( md5( json_encode( $book
) ) );
+ $book['key'] = $key;
+ $this->htmlCache->set( $key, $book, 3600 );
+
+ return $book;
}
/**
diff --git a/composer.json b/composer.json
index a97066e..18ebcc1 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,8 @@
"license" : "GPL-2.0+",
"require": {
- "composer/installers" : ">=1.0.1"
+ "composer/installers" : ">=1.0.1",
+ "vivliostyle/viewer": "2017.6"
},
"config": {
"prepend-autoloader": false,
@@ -23,5 +24,18 @@
"parallel-lint . --exclude vendor",
"phpcs -p -s"
]
- }
+ },
+ "repositories": [
+ {
+ "type": "package",
+ "package": {
+ "name": "vivliostyle/viewer",
+ "version": "2017.6",
+ "dist": {
+ "url":
"https://vivliostyle.github.io/vivliostyle.js/downloads/vivliostyle-js-2017.6.zip",
+ "type": "zip"
+ }
+ }
+ }
+ ]
}
diff --git a/includes/BookRenderer.php b/includes/BookRenderer.php
index 2a25e8c..6eb1c2f 100644
--- a/includes/BookRenderer.php
+++ b/includes/BookRenderer.php
@@ -66,8 +66,8 @@
'fragmentName' => 'body',
] );
$final .= Html::openElement( 'article' )
- . substr(
$serializer->getResult(), 15 ) // strip "<!DOCTYPE html>"
- . Html::closeElement(
'article' );
+ . substr( $serializer->getResult(), 15
) // strip "<!DOCTYPE html>"
+ . Html::closeElement( 'article' );
}
}
@@ -139,7 +139,7 @@
return Html::rawElement( 'li', [ 'class' => $class ],
Html::element( 'a', [ 'href' => '#' .
$item['anchor'] ], $item['text'] ) );
}, $outline );
- $toc = Html::rawElement( 'nav', [ 'class' => 'toc' ],
+ $toc = Html::rawElement( 'nav', [ 'class' => 'mw-book-toc' ],
Html::element( 'h1', [], 'Table of Contents' ) . "\n"
. Html::rawElement( 'ul', [], implode( "\n", $tocItems
) ) );
diff --git a/modules/offline.css b/modules/offline.css
deleted file mode 100644
index 2ee9bbf..0000000
--- a/modules/offline.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.mw-book-tocitem-type-chapter {
- font-size: 140%;
-}
-.mw-book-tocitem-type-article {
- font-size: 120%;
- padding-left: 5px;
-}
-.mw-book-tocitem-type-section.level-2 {
- padding-left: 10px;
-}
-.mw-book-tocitem-type-section.level-3 {
- padding-left: 15px;
-}
-.mw-book-tocitem-type-section.level-4 {
- padding-left: 20px;
-}
-.mw-book-tocitem-type-section.level-5 {
- padding-left: 25px;
-}
-.mw-book-tocitem-type-section.level-6 {
- padding-left: 30px;
-}
diff --git a/modules/offline.less b/modules/offline.less
new file mode 100644
index 0000000..c03c331
--- /dev/null
+++ b/modules/offline.less
@@ -0,0 +1,77 @@
+@import "mediawiki.ui/variables.less";
+
+// basic ToC styling
+.mw-book-toc li {
+ list-style: none;
+}
+.mw-book-tocitem-type-chapter {
+ font-size: 140%;
+}
+.mw-book-tocitem-type-article {
+ font-size: 120%;
+ padding-left: 10px;
+}
+.mw-book-tocitem-type-section.level-2 {
+ padding-left: 20px;
+}
+.mw-book-tocitem-type-section.level-3 {
+ padding-left: 40px;
+}
+.mw-book-tocitem-type-section.level-4 {
+ padding-left: 50px;
+}
+.mw-book-tocitem-type-section.level-5 {
+ padding-left: 60px;
+}
+.mw-book-tocitem-type-section.level-6 {
+ padding-left: 70px;
+}
+
+.mw-book-tocitem-type-chapter,
+.mw-book-tocitem-type-article,
+.mw-book-tocitem-type-section {
+ break-inside: avoid;
+
+ a {
+ display: inline-flex;
+ width: 100%;
+ break-inside: avoid;
+ align-items: baseline;
+
+ &:before {
+ flex: auto;
+ order: 1;
+ content: '';
+ margin-left: 5px;
+ margin-right: 3px;
+ border-bottom: 1px dotted @colorText;
+ }
+ &:after {
+ flex: none;
+ order: 2;
+ align-self: flex-end;
+ text-align: right;
+ // ToC numbers, will be polyfilled by vivliostyle
+ content: target-counter(attr(href url), page)
+ }
+ }
+}
+
+// page numbers, will be polyfilled by vivliostyle
+@page :left {
+ @bottom-left {
+ content: counter(page);
+ }
+}
+@page :right {
+ @bottom-right {
+ content: counter(page);
+ }
+}
+
+h1, h2, h3, h4, h5, h6 {
+ break-after: avoid;
+}
+.mw-book-chapter, .mw-book-article {
+ break-before: page;
+}
--
To view, visit https://gerrit.wikimedia.org/r/362319
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1144c57ae3d23da0aa23b40122bdcf20d0ec7b94
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Collection
Gerrit-Branch: master
Gerrit-Owner: Gergő Tisza <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits