Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Improve page navigation UI #56

Merged
merged 6 commits into from
Aug 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/html/vivliostyle-viewer.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
<!-- MENU BAR -->
<div id="vivliostyle-menu-bar">
<ul class="vivliostyle-menu" id="vivliostyle-menu_move" data-bind="visible: !navigation.hidePageNavigation">
<li class="vivliostyle-menu-item vivliostyle-menu-disabled" id="vivliostyle-menu-item_move-first" data-bind="click: navigation.navigateToFirst, css: {'vivliostyle-menu-disabled': navigation.isNavigateToFirstDisabled}"><span class="vivliostyle-menu-icon-button" title="Move: First" data-bind="menuButton: true"></span></li>
<li class="vivliostyle-menu-item vivliostyle-menu-disabled" id="vivliostyle-menu-item_move-previous" data-bind="click: navigation.navigateToPrevious, css: {'vivliostyle-menu-disabled': navigation.isNavigateToPreviousDisabled}"><span class="vivliostyle-menu-icon-button" title="Move: Previous" data-bind="menuButton: true"></span></li>
<li class="vivliostyle-menu-item vivliostyle-menu-disabled" id="vivliostyle-menu-item_move-next" data-bind="click: navigation.navigateToNext, css: {'vivliostyle-menu-disabled': navigation.isNavigateToNextDisabled}"><span class="vivliostyle-menu-icon-button" title="Move: Next" data-bind="menuButton: true"></span></li>
<li class="vivliostyle-menu-item vivliostyle-menu-disabled" id="vivliostyle-menu-item_move-last" data-bind="click: navigation.navigateToLast, css: {'vivliostyle-menu-disabled': navigation.isNavigateToLastDisabled}"><span class="vivliostyle-menu-icon-button" title="Move: Last" data-bind="menuButton: true"></span></li>
</ul>
<ul class="vivliostyle-menu" id="vivliostyle-menu_zoom" data-bind="visible: !navigation.hideZoom">
<li class="vivliostyle-menu-item vivliostyle-menu-disabled" id="vivliostyle-menu-item_zoom-out" data-bind="click: navigation.zoomOut, css: {'vivliostyle-menu-disabled': navigation.isZoomOutDisabled}"><span class="vivliostyle-menu-icon-button" title="Zoom: Out" data-bind="menuButton: true"></span></li>
Expand Down
110 changes: 92 additions & 18 deletions src/js/viewmodels/navigation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2015 Trim-marks Inc.
* Copyright 2018 Vivliostyle Foundation
*
* This file is part of Vivliostyle UI.
*
Expand All @@ -20,44 +21,117 @@
import ko from "knockout";
import ViewerOptions from "../models/viewer-options";
import {Keys} from "../utils/key-util";
import vivliostyle from "../models/vivliostyle";

class Navigation {
constructor(viewerOptions, viewer, settingsPanel, navigationOptions) {
this.viewerOptions_ = viewerOptions;
this.viewer_ = viewer;
this.settingsPanel_ = settingsPanel;

this.isDisabled = ko.pureComputed(function() {
this.isDisabled = ko.pureComputed(() => {
return this.settingsPanel_.opened() || !this.viewer_.state.navigatable();
}, this);
});

const navigationDisabled = ko.pureComputed(function() {
const navigationDisabled = ko.pureComputed(() => {
return navigationOptions.disablePageNavigation || this.isDisabled();
}, this);

this.isNavigateToPreviousDisabled = navigationDisabled;
this.isNavigateToNextDisabled = navigationDisabled;
this.isNavigateToLeftDisabled = navigationDisabled;
this.isNavigateToRightDisabled = navigationDisabled;
this.isNavigateToFirstDisabled = navigationDisabled;
this.isNavigateToLastDisabled = navigationDisabled;
});

const getSpreadContainerElement = () => {
const viewportElement = document.getElementById("vivliostyle-viewer-viewport");
const outerZoomBoxElement = viewportElement && viewportElement.firstElementChild;
return outerZoomBoxElement && outerZoomBoxElement.firstElementChild;
}

this.isNavigateToPreviousDisabled = ko.pureComputed(() => {
if (navigationDisabled()) {
return true;
}
if (this.viewer_.state.status === undefined) {
return false; // needed for test/spec/viewmodels/navigation-spec.js
}
const spreadContainerElement = getSpreadContainerElement();
const firstPageContainer = spreadContainerElement && spreadContainerElement.firstElementChild;
return !firstPageContainer || firstPageContainer.style.display != "none";
});

this.isNavigateToNextDisabled = ko.pureComputed(() => {
if (navigationDisabled()) {
return true;
}
if (this.viewer_.state.status === undefined) {
return false; // needed for test/spec/viewmodels/navigation-spec.js
}
if (this.viewer_.state.status() != vivliostyle.constants.ReadyState.COMPLETE) {
return false;
}
const spreadContainerElement = getSpreadContainerElement();
const lastPageContainer = spreadContainerElement && spreadContainerElement.lastElementChild;
return !lastPageContainer || lastPageContainer.style.display != "none";
});

this.isNavigateToLeftDisabled = ko.pureComputed(() => {
if (navigationDisabled()) {
return true;
}
if (this.viewer_.state.pageProgression === undefined) {
return false; // needed for test/spec/viewmodels/navigation-spec.js
}
if (this.viewer_.state.pageProgression() === vivliostyle.constants.PageProgression.LTR) {
return this.isNavigateToPreviousDisabled();
} else {
return this.isNavigateToNextDisabled();
}
});

this.isNavigateToRightDisabled = ko.pureComputed(() => {
if (navigationDisabled()) {
return true;
}
if (this.viewer_.state.pageProgression === undefined) {
return false; // needed for test/spec/viewmodels/navigation-spec.js
}
if (this.viewer_.state.pageProgression() === vivliostyle.constants.PageProgression.LTR) {
return this.isNavigateToNextDisabled();
} else {
return this.isNavigateToPreviousDisabled();
}
});

this.isNavigateToFirstDisabled = this.isNavigateToPreviousDisabled;

this.isNavigateToLastDisabled = ko.pureComputed(() => {
if (navigationDisabled()) {
return true;
}
if (this.viewer_.state.status === undefined) {
return false; // needed for test/spec/viewmodels/navigation-spec.js
}
if (this.viewer_.state.status() != vivliostyle.constants.ReadyState.COMPLETE) {
return true;
}
const spreadContainerElement = getSpreadContainerElement();
const lastPageContainer = spreadContainerElement && spreadContainerElement.lastElementChild;
return !lastPageContainer || lastPageContainer.style.display != "none";
});

this.hidePageNavigation = !!navigationOptions.disablePageNavigation;

const zoomDisabled = ko.pureComputed(function() {
const zoomDisabled = ko.pureComputed(() => {
return navigationOptions.disableZoom || this.isDisabled();
}, this);
});

this.isZoomOutDisabled = zoomDisabled;
this.isZoomInDisabled = zoomDisabled;
this.isZoomToActualSizeDisabled = zoomDisabled;
this.isToggleFitToScreenDisabled = zoomDisabled;
this.hideZoom = !!navigationOptions.disableZoom;

this.fitToScreen = ko.pureComputed(() => viewerOptions.zoom().fitToScreen, this);
this.fitToScreen = ko.pureComputed(() => viewerOptions.zoom().fitToScreen);

const fontSizeChangeDisabled = ko.pureComputed(function() {
const fontSizeChangeDisabled = ko.pureComputed(() => {
return navigationOptions.disableFontSizeChange || this.isDisabled();
}, this);
});

this.isIncreaseFontSizeDisabled = fontSizeChangeDisabled;
this.isDecreaseFontSizeDisabled = fontSizeChangeDisabled;
Expand All @@ -79,9 +153,9 @@ class Navigation {
"decreaseFontSize",
"defaultFontSize",
"handleKey"
].forEach(function(methodName) {
].forEach(methodName => {
this[methodName] = this[methodName].bind(this);
}, this);
});
}

navigateToPrevious() {
Expand Down
20 changes: 18 additions & 2 deletions src/js/viewmodels/viewer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright 2015 Trim-marks Inc.
* Copyright 2018 Vivliostyle Foundation
*
* This file is part of Vivliostyle UI.
*
Expand Down Expand Up @@ -29,7 +30,7 @@ class Viewer {
this.viewer_ = new vivliostyle.viewer.Viewer(viewerSettings, viewerOptions.toObject());
const state_ = this.state_= {
status: obs.readonlyObservable(vivliostyle.constants.ReadyState.LOADING),
pageProgression: obs.readonlyObservable(vivliostyle.constants.LTR)
pageProgression: obs.readonlyObservable(vivliostyle.constants.PageProgression.LTR)
};
this.state = {
status: state_.status.getter.extend({
Expand Down Expand Up @@ -59,7 +60,7 @@ class Viewer {
});
this.viewer_.addListener("readystatechange", () => {
const readyState = this.viewer_.readyState;
if (readyState === vivliostyle.constants.ReadyState.INTERACTIVE || vivliostyle.constants.ReadyState.COMPLETE) {
if (readyState === vivliostyle.constants.ReadyState.INTERACTIVE || readyState === vivliostyle.constants.ReadyState.COMPLETE) {
this.state_.pageProgression.value(this.viewer_.getCurrentPageProgression());
}
this.state_.status.value(readyState);
Expand All @@ -78,6 +79,7 @@ class Viewer {
this.viewer_.addListener("hyperlink", payload => {
if (payload.internal) {
this.viewer_.navigateToInternalUrl(payload.href);
this.afterNavigateToPage();
} else {
window.location.href = payload.href;
}
Expand All @@ -104,28 +106,42 @@ class Viewer {
}
}

afterNavigateToPage() {
setTimeout(() => {
// Update page navigation disable/enable
this.state_.status.value(vivliostyle.constants.ReadyState.LOADING);
this.state_.status.value(this.viewer_.readyState);
}, 1);
}

navigateToPrevious() {
this.viewer_.navigateToPage("previous");
this.afterNavigateToPage();
}

navigateToNext() {
this.viewer_.navigateToPage("next");
this.afterNavigateToPage();
}

navigateToLeft() {
this.viewer_.navigateToPage("left");
this.afterNavigateToPage();
}

navigateToRight() {
this.viewer_.navigateToPage("right");
this.afterNavigateToPage();
}

navigateToFirst() {
this.viewer_.navigateToPage("first");
this.afterNavigateToPage();
}

navigateToLast() {
this.viewer_.navigateToPage("last");
this.afterNavigateToPage();
}

queryZoomFactor(type) {
Expand Down
3 changes: 3 additions & 0 deletions src/scss/ui.arrows.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ $button-offset: 0;
background: rgba(0, 0, 0, 0.00);
@include transition(.25s ease-out);
}
&:not(.vivliostyle-menu-enabled) {
display: none;
}
&[data-vivliostyle-ui-state="attention"] {
color: rgba(255, 255, 255, 0.75);
background: rgba(0, 0, 0, 0.25);
Expand Down
8 changes: 6 additions & 2 deletions src/scss/ui.menu-bar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ $animation-FLIP: FLIP 2s ease 0s infinite normal;
height: $menu-icon-height * 0.5;
text-align: center;
transition: linear .2s;
@media screen and (max-width: 680px) {
@media screen and (max-width: 824px) {
right: $menu-icon-width + $menu-icon-offset-x * 4;
width: 362px / (80px / ($menu-icon-height * 0.5));
text-align: right;
}
@media screen and (max-width: 440px) {
@media screen and (max-width: 512px) {
animation: none !important;
opacity: 0 !important;
}
Expand Down Expand Up @@ -189,9 +189,11 @@ $animation-FLIP: FLIP 2s ease 0s infinite normal;
ul.vivliostyle-menu {
li.vivliostyle-menu-item {
// &#vivliostyle-menu-item_move-left >.vivliostyle-menu-icon-button:before { content: $fa-var-arrow-left; }
&#vivliostyle-menu-item_move-first >.vivliostyle-menu-icon-button:before { content: $fa-var-chevron-up; }
&#vivliostyle-menu-item_move-previous >.vivliostyle-menu-icon-button:before { content: $fa-var-chevron-up; }
// &#vivliostyle-menu-item_move-right >.vivliostyle-menu-icon-button:before { content: $fa-var-arrow-right; }
&#vivliostyle-menu-item_move-next >.vivliostyle-menu-icon-button:before { content: $fa-var-chevron-down; }
&#vivliostyle-menu-item_move-last >.vivliostyle-menu-icon-button:before { content: $fa-var-chevron-down; }
&#vivliostyle-menu-item_zoom-out >.vivliostyle-menu-icon-button:before { content: $fa-var-search-minus; }
// &#vivliostyle-menu-item_zoom-default >.vivliostyle-menu-icon-button:before { content: $fa-var-search; }
&#vivliostyle-menu-item_zoom-fit-to-screen >.vivliostyle-menu-icon-button:before { content: $fa-var-arrows-alt/*$fa-var-search*/; top: .05em; /*font-size: $menu-icon-height * 0.36;*/ }
Expand All @@ -200,6 +202,8 @@ $animation-FLIP: FLIP 2s ease 0s infinite normal;
&#vivliostyle-menu-item_text-size-smaller >.vivliostyle-menu-icon-button:before { content: $fa-var-font; }
&#vivliostyle-menu-item_text-size-default >.vivliostyle-menu-icon-button:before { content: $fa-var-font; }
&#vivliostyle-menu-item_text-size-larger >.vivliostyle-menu-icon-button:before { content: $fa-var-font; }
&#vivliostyle-menu-item_move-first >.vivliostyle-menu-icon-button:after { content: ""; border-top: solid 2px; top: 8px; left: 8px; width: 16px; }
&#vivliostyle-menu-item_move-last >.vivliostyle-menu-icon-button:after { content: ""; border-bottom: solid 2px; bottom: 7px; left: 8px; width: 16px; }
// &#vivliostyle-menu-item_zoom-default >.vivliostyle-menu-icon-button:after { content: "="; left: $menu-icon-width * 0.2625; top: $menu-icon-height * 0.2; }
// &#vivliostyle-menu-item_zoom-default >.vivliostyle-menu-icon-button:after { content: ""; border: solid 1px; border-radius: 2px; width: 2.1em; height: 2.1em; left: $menu-icon-width * 0.17; top: $menu-icon-height * 0.18; }
&#vivliostyle-menu-item_zoom-to-actual-size >.vivliostyle-menu-icon-button:after { content: "1"; left: calc(46% - 1em / 2); top: $menu-icon-height * 0.297; font-size: $menu-icon-height * 0.22;}
Expand Down