Merge pull request #12777 from Snuffleupagus/currentOutlineItem
Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This commit is contained in:
commit
7f199e7017
@ -147,6 +147,8 @@ layers.title=Show Layers (double-click to reset all layers to the default state)
|
||||
layers_label=Layers
|
||||
thumbs.title=Show Thumbnails
|
||||
thumbs_label=Thumbnails
|
||||
current_outline_item.title=Find Current Outline Item
|
||||
current_outline_item_label=Current Outline Item
|
||||
findbar.title=Find in Document
|
||||
findbar_label=Find
|
||||
|
||||
|
@ -148,6 +148,8 @@ layers.title=Lagen tonen (dubbelklik om alle lagen naar de standaardstatus terug
|
||||
layers_label=Lagen
|
||||
thumbs.title=Miniaturen tonen
|
||||
thumbs_label=Miniaturen
|
||||
current_outline_item.title=Huidige positie in documentoverzicht selecteren
|
||||
current_outline_item_label=Huidige positie in documentoverzicht
|
||||
findbar.title=Zoeken in document
|
||||
findbar_label=Zoeken
|
||||
|
||||
|
@ -148,6 +148,8 @@ layers.title=Visa lager (dubbelklicka för att återställa alla lager till stan
|
||||
layers_label=Lager
|
||||
thumbs.title=Visa miniatyrer
|
||||
thumbs_label=Miniatyrer
|
||||
current_outline_item.title=Hitta aktuell position i dokumentdispositionen
|
||||
current_outline_item_label=Aktuell position i dokumentdisposition
|
||||
findbar.title=Sök i dokument
|
||||
findbar_label=Sök
|
||||
|
||||
|
@ -32,6 +32,7 @@ import {
|
||||
ProgressBar,
|
||||
RendererType,
|
||||
ScrollMode,
|
||||
SidebarView,
|
||||
SpreadMode,
|
||||
TextLayerMode,
|
||||
} from "./ui_utils.js";
|
||||
@ -56,7 +57,6 @@ import {
|
||||
} from "pdfjs-lib";
|
||||
import { CursorTool, PDFCursorTools } from "./pdf_cursor_tools.js";
|
||||
import { PDFRenderingQueue, RenderingStates } from "./pdf_rendering_queue.js";
|
||||
import { PDFSidebar, SidebarView } from "./pdf_sidebar.js";
|
||||
import { OverlayManager } from "./overlay_manager.js";
|
||||
import { PasswordPrompt } from "./password_prompt.js";
|
||||
import { PDFAttachmentViewer } from "./pdf_attachment_viewer.js";
|
||||
@ -68,6 +68,7 @@ import { PDFLayerViewer } from "./pdf_layer_viewer.js";
|
||||
import { PDFLinkService } from "./pdf_link_service.js";
|
||||
import { PDFOutlineViewer } from "./pdf_outline_viewer.js";
|
||||
import { PDFPresentationMode } from "./pdf_presentation_mode.js";
|
||||
import { PDFSidebar } from "./pdf_sidebar.js";
|
||||
import { PDFSidebarResizer } from "./pdf_sidebar_resizer.js";
|
||||
import { PDFThumbnailViewer } from "./pdf_thumbnail_viewer.js";
|
||||
import { PDFViewer } from "./pdf_viewer.js";
|
||||
@ -1419,7 +1420,7 @@ const PDFViewerApplication = {
|
||||
|
||||
onePageRendered.then(() => {
|
||||
pdfDocument.getOutline().then(outline => {
|
||||
this.pdfOutlineViewer.render({ outline });
|
||||
this.pdfOutlineViewer.render({ outline, pdfDocument });
|
||||
});
|
||||
pdfDocument.getAttachments().then(attachments => {
|
||||
this.pdfAttachmentViewer.render({ attachments });
|
||||
|
@ -15,6 +15,9 @@
|
||||
|
||||
import { removeNullCharacters } from "pdfjs-lib";
|
||||
|
||||
const TREEITEM_OFFSET_TOP = -100; // px
|
||||
const TREEITEM_SELECTED_CLASS = "selected";
|
||||
|
||||
class BaseTreeViewer {
|
||||
constructor(options) {
|
||||
if (this.constructor === BaseTreeViewer) {
|
||||
@ -27,7 +30,9 @@ class BaseTreeViewer {
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._pdfDocument = null;
|
||||
this._lastToggleIsShow = true;
|
||||
this._currentTreeItem = null;
|
||||
|
||||
// Remove the tree from the DOM.
|
||||
this.container.textContent = "";
|
||||
@ -120,6 +125,46 @@ class BaseTreeViewer {
|
||||
render(params) {
|
||||
throw new Error("Not implemented: render");
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_updateCurrentTreeItem(treeItem = null) {
|
||||
if (this._currentTreeItem) {
|
||||
// Ensure that the current treeItem-selection is always removed.
|
||||
this._currentTreeItem.classList.remove(TREEITEM_SELECTED_CLASS);
|
||||
this._currentTreeItem = null;
|
||||
}
|
||||
if (treeItem) {
|
||||
treeItem.classList.add(TREEITEM_SELECTED_CLASS);
|
||||
this._currentTreeItem = treeItem;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_scrollToCurrentTreeItem(treeItem) {
|
||||
if (!treeItem) {
|
||||
return;
|
||||
}
|
||||
// Ensure that the treeItem is *fully* expanded, such that it will first of
|
||||
// all be visible and secondly that scrolling it into view works correctly.
|
||||
let currentNode = treeItem.parentNode;
|
||||
while (currentNode && currentNode !== this.container) {
|
||||
if (currentNode.classList.contains("treeItem")) {
|
||||
const toggler = currentNode.firstElementChild;
|
||||
toggler?.classList.remove("treeItemsHidden");
|
||||
}
|
||||
currentNode = currentNode.parentNode;
|
||||
}
|
||||
this._updateCurrentTreeItem(treeItem);
|
||||
|
||||
this.container.scrollTo(
|
||||
treeItem.offsetLeft,
|
||||
treeItem.offsetTop + TREEITEM_OFFSET_TOP
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { BaseTreeViewer };
|
||||
|
1
web/images/toolbarButton-currentOutlineItem.svg
Normal file
1
web/images/toolbarButton-currentOutlineItem.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"><path d="m14 9h-6c-1.3 0-1.3 2 0 2h6c1.3 0 1.3-2 0-2zm-5.2-8h-3.8c-1.3 0-1.3 2 0 2h1.7zm-6.8 0c-1 0-1.3 1-0.7 1.7 0.7 0.6 1.7 0.3 1.7-0.7 0-0.5-0.4-1-1-1zm3 8c-1 0-1.3 1-0.7 1.7 0.6 0.6 1.7 0.2 1.7-0.7 0-0.5-0.4-1-1-1zm0.3-4h-0.3c-1.4 0-1.4 2 0 2h2.3zm-3.3 0c-0.9 0-1.4 1-0.7 1.7 0.7 0.6 1.7 0.2 1.7-0.7 0-0.6-0.5-1-1-1zm12 8h-9c-1.3 0-1.3 2 0 2h9c1.3 0 1.3-2 0-2zm-12 0c-1 0-1.3 1-0.7 1.7 0.7 0.6 1.7 0.2 1.7-0.712 0-0.5-0.4-1-1-1z"/><path d="m7.37 4.838 3.93-3.911v2.138h3.629v3.546h-3.629v2.138l-3.93-3.911"/></svg>
|
After Width: | Height: | Size: 581 B |
@ -41,7 +41,6 @@ class PDFLayerViewer extends BaseTreeViewer {
|
||||
reset() {
|
||||
super.reset();
|
||||
this._optionalContentConfig = null;
|
||||
this._pdfDocument = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,8 +13,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { addLinkAttributes, LinkTarget } from "pdfjs-lib";
|
||||
import {
|
||||
addLinkAttributes,
|
||||
createPromiseCapability,
|
||||
LinkTarget,
|
||||
} from "pdfjs-lib";
|
||||
import { BaseTreeViewer } from "./base_tree_viewer.js";
|
||||
import { SidebarView } from "./ui_utils.js";
|
||||
|
||||
/**
|
||||
* @typedef {Object} PDFOutlineViewerOptions
|
||||
@ -26,6 +31,7 @@ import { BaseTreeViewer } from "./base_tree_viewer.js";
|
||||
/**
|
||||
* @typedef {Object} PDFOutlineViewerRenderParameters
|
||||
* @property {Array|null} outline - An array of outline objects.
|
||||
* @property {PDFDocument} pdfDocument - A {PDFDocument} instance.
|
||||
*/
|
||||
|
||||
class PDFOutlineViewer extends BaseTreeViewer {
|
||||
@ -37,11 +43,29 @@ class PDFOutlineViewer extends BaseTreeViewer {
|
||||
this.linkService = options.linkService;
|
||||
|
||||
this.eventBus._on("toggleoutlinetree", this._toggleAllTreeItems.bind(this));
|
||||
this.eventBus._on(
|
||||
"currentoutlineitem",
|
||||
this._currentOutlineItem.bind(this)
|
||||
);
|
||||
|
||||
this.eventBus._on("pagechanging", evt => {
|
||||
this._currentPageNumber = evt.pageNumber;
|
||||
});
|
||||
this.eventBus._on("pagesloaded", evt => {
|
||||
this._isPagesLoaded = !!evt.pagesCount;
|
||||
});
|
||||
this.eventBus._on("sidebarviewchanged", evt => {
|
||||
this._sidebarView = evt.view;
|
||||
});
|
||||
}
|
||||
|
||||
reset() {
|
||||
super.reset();
|
||||
this._outline = null;
|
||||
|
||||
this._pageNumberToDestHashCapability = null;
|
||||
this._currentPageNumber = 1;
|
||||
this._isPagesLoaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,6 +75,8 @@ class PDFOutlineViewer extends BaseTreeViewer {
|
||||
this.eventBus.dispatch("outlineloaded", {
|
||||
source: this,
|
||||
outlineCount,
|
||||
enableCurrentOutlineItemButton:
|
||||
outlineCount > 0 && !this._pdfDocument?.loadingParams.disableAutoFetch,
|
||||
});
|
||||
}
|
||||
|
||||
@ -71,7 +97,9 @@ class PDFOutlineViewer extends BaseTreeViewer {
|
||||
}
|
||||
|
||||
element.href = linkService.getDestinationHash(dest);
|
||||
element.onclick = () => {
|
||||
element.onclick = evt => {
|
||||
this._updateCurrentTreeItem(evt.target.parentNode);
|
||||
|
||||
if (dest) {
|
||||
linkService.goToDestination(dest);
|
||||
}
|
||||
@ -128,11 +156,12 @@ class PDFOutlineViewer extends BaseTreeViewer {
|
||||
/**
|
||||
* @param {PDFOutlineViewerRenderParameters} params
|
||||
*/
|
||||
render({ outline }) {
|
||||
render({ outline, pdfDocument }) {
|
||||
if (this._outline) {
|
||||
this.reset();
|
||||
}
|
||||
this._outline = outline || null;
|
||||
this._pdfDocument = pdfDocument || null;
|
||||
|
||||
if (!outline) {
|
||||
this._dispatchEvent(/* outlineCount = */ 0);
|
||||
@ -174,6 +203,120 @@ class PDFOutlineViewer extends BaseTreeViewer {
|
||||
|
||||
this._finishRendering(fragment, outlineCount, hasAnyNesting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find/highlight the current outline item, corresponding to the active page.
|
||||
* @private
|
||||
*/
|
||||
async _currentOutlineItem() {
|
||||
if (!this._isPagesLoaded) {
|
||||
throw new Error("_currentOutlineItem: All pages have not been loaded.");
|
||||
}
|
||||
if (!this._outline || !this._pdfDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pageNumberToDestHash = await this._getPageNumberToDestHash(
|
||||
this._pdfDocument
|
||||
);
|
||||
if (!pageNumberToDestHash) {
|
||||
return;
|
||||
}
|
||||
this._updateCurrentTreeItem(/* treeItem = */ null);
|
||||
|
||||
if (this._sidebarView !== SidebarView.OUTLINE) {
|
||||
return; // The outline view is no longer visible, hence do nothing.
|
||||
}
|
||||
// When there is no destination on the current page, always check the
|
||||
// previous ones in (reverse) order.
|
||||
for (let i = this._currentPageNumber; i > 0; i--) {
|
||||
const destHash = pageNumberToDestHash.get(i);
|
||||
if (!destHash) {
|
||||
continue;
|
||||
}
|
||||
const linkElement = this.container.querySelector(`a[href="${destHash}"]`);
|
||||
if (!linkElement) {
|
||||
continue;
|
||||
}
|
||||
this._scrollToCurrentTreeItem(linkElement.parentNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To (significantly) simplify the overall implementation, we will only
|
||||
* consider *one* destination per page when finding/highlighting the current
|
||||
* outline item (similar to e.g. Adobe Reader); more specifically, we choose
|
||||
* the *first* outline item at the *lowest* level of the outline tree.
|
||||
* @private
|
||||
*/
|
||||
async _getPageNumberToDestHash(pdfDocument) {
|
||||
if (this._pageNumberToDestHashCapability) {
|
||||
return this._pageNumberToDestHashCapability.promise;
|
||||
}
|
||||
this._pageNumberToDestHashCapability = createPromiseCapability();
|
||||
|
||||
const pageNumberToDestHash = new Map(),
|
||||
pageNumberNesting = new Map();
|
||||
const queue = [{ nesting: 0, items: this._outline }];
|
||||
while (queue.length > 0) {
|
||||
const levelData = queue.shift(),
|
||||
currentNesting = levelData.nesting;
|
||||
for (const { dest, items } of levelData.items) {
|
||||
let explicitDest, pageNumber;
|
||||
if (typeof dest === "string") {
|
||||
explicitDest = await pdfDocument.getDestination(dest);
|
||||
|
||||
if (pdfDocument !== this._pdfDocument) {
|
||||
return null; // The document was closed while the data resolved.
|
||||
}
|
||||
} else {
|
||||
explicitDest = dest;
|
||||
}
|
||||
if (Array.isArray(explicitDest)) {
|
||||
const [destRef] = explicitDest;
|
||||
|
||||
if (typeof destRef === "object") {
|
||||
pageNumber = this.linkService._cachedPageNumber(destRef);
|
||||
|
||||
if (!pageNumber) {
|
||||
try {
|
||||
pageNumber = (await pdfDocument.getPageIndex(destRef)) + 1;
|
||||
|
||||
if (pdfDocument !== this._pdfDocument) {
|
||||
return null; // The document was closed while the data resolved.
|
||||
}
|
||||
this.linkService.cachePageRef(pageNumber, destRef);
|
||||
} catch (ex) {
|
||||
// Invalid page reference, ignore it and continue parsing.
|
||||
}
|
||||
}
|
||||
} else if (Number.isInteger(destRef)) {
|
||||
pageNumber = destRef + 1;
|
||||
}
|
||||
|
||||
if (
|
||||
Number.isInteger(pageNumber) &&
|
||||
(!pageNumberToDestHash.has(pageNumber) ||
|
||||
currentNesting > pageNumberNesting.get(pageNumber))
|
||||
) {
|
||||
const destHash = this.linkService.getDestinationHash(dest);
|
||||
pageNumberToDestHash.set(pageNumber, destHash);
|
||||
pageNumberNesting.set(pageNumber, currentNesting);
|
||||
}
|
||||
}
|
||||
|
||||
if (items.length > 0) {
|
||||
queue.push({ nesting: currentNesting + 1, items });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._pageNumberToDestHashCapability.resolve(
|
||||
pageNumberToDestHash.size > 0 ? pageNumberToDestHash : null
|
||||
);
|
||||
return this._pageNumberToDestHashCapability.promise;
|
||||
}
|
||||
}
|
||||
|
||||
export { PDFOutlineViewer };
|
||||
|
@ -13,20 +13,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NullL10n, PresentationModeState } from "./ui_utils.js";
|
||||
import { NullL10n, PresentationModeState, SidebarView } from "./ui_utils.js";
|
||||
import { RenderingStates } from "./pdf_rendering_queue.js";
|
||||
|
||||
const UI_NOTIFICATION_CLASS = "pdfSidebarNotification";
|
||||
|
||||
const SidebarView = {
|
||||
UNKNOWN: -1,
|
||||
NONE: 0,
|
||||
THUMBS: 1, // Default value.
|
||||
OUTLINE: 2,
|
||||
ATTACHMENTS: 3,
|
||||
LAYERS: 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {Object} PDFSidebarOptions
|
||||
* @property {PDFSidebarElements} elements - The DOM elements.
|
||||
@ -62,6 +53,10 @@ const SidebarView = {
|
||||
* the attachments are placed.
|
||||
* @property {HTMLDivElement} layersView - The container in which
|
||||
* the layers are placed.
|
||||
* @property {HTMLDivElement} outlineOptionsContainer - The container in which
|
||||
* the outline view-specific option button(s) are placed.
|
||||
* @property {HTMLButtonElement} currentOutlineItemButton - The button used to
|
||||
* find the current outline item.
|
||||
*/
|
||||
|
||||
class PDFSidebar {
|
||||
@ -103,6 +98,9 @@ class PDFSidebar {
|
||||
this.attachmentsView = elements.attachmentsView;
|
||||
this.layersView = elements.layersView;
|
||||
|
||||
this._outlineOptionsContainer = elements.outlineOptionsContainer;
|
||||
this._currentOutlineItemButton = elements.currentOutlineItemButton;
|
||||
|
||||
this.eventBus = eventBus;
|
||||
this.l10n = l10n;
|
||||
this._disableNotification = disableNotification;
|
||||
@ -119,6 +117,7 @@ class PDFSidebar {
|
||||
this.outlineButton.disabled = false;
|
||||
this.attachmentsButton.disabled = false;
|
||||
this.layersButton.disabled = false;
|
||||
this._currentOutlineItemButton.disabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,6 +242,12 @@ class PDFSidebar {
|
||||
);
|
||||
this.layersView.classList.toggle("hidden", view !== SidebarView.LAYERS);
|
||||
|
||||
// Finally, update view-specific CSS classes.
|
||||
this._outlineOptionsContainer.classList.toggle(
|
||||
"hidden",
|
||||
view !== SidebarView.OUTLINE
|
||||
);
|
||||
|
||||
if (forceOpen && !this.isOpen) {
|
||||
this.open();
|
||||
return true; // Opening will trigger rendering and dispatch the event.
|
||||
@ -460,6 +465,11 @@ class PDFSidebar {
|
||||
this.eventBus.dispatch("resetlayers", { source: this });
|
||||
});
|
||||
|
||||
// Buttons for view-specific options.
|
||||
this._currentOutlineItemButton.addEventListener("click", () => {
|
||||
this.eventBus.dispatch("currentoutlineitem", { source: this });
|
||||
});
|
||||
|
||||
// Disable/enable views.
|
||||
const onTreeLoaded = (count, button, view) => {
|
||||
button.disabled = !count;
|
||||
@ -475,6 +485,12 @@ class PDFSidebar {
|
||||
|
||||
this.eventBus._on("outlineloaded", evt => {
|
||||
onTreeLoaded(evt.outlineCount, this.outlineButton, SidebarView.OUTLINE);
|
||||
|
||||
if (evt.enableCurrentOutlineItemButton) {
|
||||
this.pdfViewer.pagesPromise.then(() => {
|
||||
this._currentOutlineItemButton.disabled = !this.isInitialViewSet;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.eventBus._on("attachmentsloaded", evt => {
|
||||
|
@ -32,6 +32,15 @@ const PresentationModeState = {
|
||||
FULLSCREEN: 3,
|
||||
};
|
||||
|
||||
const SidebarView = {
|
||||
UNKNOWN: -1,
|
||||
NONE: 0,
|
||||
THUMBS: 1, // Default value.
|
||||
OUTLINE: 2,
|
||||
ATTACHMENTS: 3,
|
||||
LAYERS: 4,
|
||||
};
|
||||
|
||||
const RendererType = {
|
||||
CANVAS: "canvas",
|
||||
SVG: "svg",
|
||||
@ -1037,6 +1046,7 @@ export {
|
||||
isValidSpreadMode,
|
||||
isPortraitOrientation,
|
||||
PresentationModeState,
|
||||
SidebarView,
|
||||
RendererType,
|
||||
TextLayerMode,
|
||||
ScrollMode,
|
||||
|
@ -48,8 +48,8 @@
|
||||
--findbar-nextprevious-btn-bg-color: rgba(227, 228, 230, 1);
|
||||
--treeitem-color: rgba(0, 0, 0, 0.8);
|
||||
--treeitem-hover-color: rgba(0, 0, 0, 0.9);
|
||||
--treeitem-active-color: rgba(0, 0, 0, 0.08);
|
||||
--treeitem-active-bg-color: rgba(0, 0, 0, 1);
|
||||
--treeitem-selected-color: rgba(0, 0, 0, 0.9);
|
||||
--treeitem-selected-bg-color: rgba(0, 0, 0, 0.25);
|
||||
--sidebaritem-bg-color: rgba(0, 0, 0, 0.15);
|
||||
--doorhanger-bg-color: rgba(255, 255, 255, 1);
|
||||
--doorhanger-border-color: rgba(12, 12, 13, 0.2);
|
||||
@ -77,6 +77,7 @@
|
||||
--toolbarButton-viewOutline-icon: url(images/toolbarButton-viewOutline.svg);
|
||||
--toolbarButton-viewAttachments-icon: url(images/toolbarButton-viewAttachments.svg);
|
||||
--toolbarButton-viewLayers-icon: url(images/toolbarButton-viewLayers.svg);
|
||||
--toolbarButton-currentOutlineItem-icon: url(images/toolbarButton-currentOutlineItem.svg);
|
||||
--toolbarButton-search-icon: url(images/toolbarButton-search.svg);
|
||||
--findbarButton-previous-icon: url(images/findbarButton-previous.svg);
|
||||
--findbarButton-next-icon: url(images/findbarButton-next.svg);
|
||||
@ -121,8 +122,8 @@
|
||||
--findbar-nextprevious-btn-bg-color: rgba(89, 89, 89, 1);
|
||||
--treeitem-color: rgba(255, 255, 255, 0.8);
|
||||
--treeitem-hover-color: rgba(255, 255, 255, 0.9);
|
||||
--treeitem-active-color: rgba(255, 255, 255, 0.08);
|
||||
--treeitem-active-bg-color: rgba(255, 255, 255, 1);
|
||||
--treeitem-selected-color: rgba(255, 255, 255, 0.9);
|
||||
--treeitem-selected-bg-color: rgba(255, 255, 255, 0.25);
|
||||
--sidebaritem-bg-color: rgba(255, 255, 255, 0.15);
|
||||
--doorhanger-bg-color: rgba(74, 74, 79, 1);
|
||||
--doorhanger-border-color: rgba(39, 39, 43, 1);
|
||||
@ -338,6 +339,13 @@ html[dir="rtl"] #toolbarSidebar .toolbarButton {
|
||||
margin-left: 2px !important;
|
||||
}
|
||||
|
||||
html[dir="ltr"] #toolbarSidebarRight .toolbarButton {
|
||||
margin-right: 3px !important;
|
||||
}
|
||||
html[dir="rtl"] #toolbarSidebarRight .toolbarButton {
|
||||
margin-left: 3px !important;
|
||||
}
|
||||
|
||||
#sidebarResizer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -694,16 +702,22 @@ html[dir="ltr"] .doorHangerRight:before {
|
||||
}
|
||||
|
||||
html[dir="ltr"] #toolbarViewerLeft,
|
||||
html[dir="rtl"] #toolbarViewerRight {
|
||||
html[dir="rtl"] #toolbarViewerRight,
|
||||
html[dir="ltr"] #toolbarSidebarLeft,
|
||||
html[dir="rtl"] #toolbarSidebarRight {
|
||||
float: left;
|
||||
}
|
||||
html[dir="ltr"] #toolbarViewerRight,
|
||||
html[dir="rtl"] #toolbarViewerLeft {
|
||||
html[dir="rtl"] #toolbarViewerLeft,
|
||||
html[dir="ltr"] #toolbarSidebarRight,
|
||||
html[dir="rtl"] #toolbarSidebarLeft {
|
||||
float: right;
|
||||
}
|
||||
html[dir="ltr"] #toolbarViewerLeft > *,
|
||||
html[dir="ltr"] #toolbarViewerMiddle > *,
|
||||
html[dir="ltr"] #toolbarViewerRight > *,
|
||||
html[dir="ltr"] #toolbarSidebarLeft *,
|
||||
html[dir="ltr"] #toolbarSidebarRight *,
|
||||
html[dir="ltr"] .findbar * {
|
||||
position: relative;
|
||||
float: left;
|
||||
@ -711,6 +725,8 @@ html[dir="ltr"] .findbar * {
|
||||
html[dir="rtl"] #toolbarViewerLeft > *,
|
||||
html[dir="rtl"] #toolbarViewerMiddle > *,
|
||||
html[dir="rtl"] #toolbarViewerRight > *,
|
||||
html[dir="rtl"] #toolbarSidebarLeft *,
|
||||
html[dir="rtl"] #toolbarSidebarRight *,
|
||||
html[dir="rtl"] .findbar * {
|
||||
position: relative;
|
||||
float: right;
|
||||
@ -1073,6 +1089,14 @@ html[dir="rtl"] #viewOutline.toolbarButton::before {
|
||||
mask-image: var(--toolbarButton-viewLayers-icon);
|
||||
}
|
||||
|
||||
#currentOutlineItem.toolbarButton::before {
|
||||
-webkit-mask-image: var(--toolbarButton-currentOutlineItem-icon);
|
||||
mask-image: var(--toolbarButton-currentOutlineItem-icon);
|
||||
}
|
||||
html[dir="rtl"] #currentOutlineItem.toolbarButton::before {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
#viewFind.toolbarButton::before {
|
||||
-webkit-mask-image: var(--toolbarButton-search-icon);
|
||||
mask-image: var(--toolbarButton-search-icon);
|
||||
@ -1448,6 +1472,11 @@ html[dir="rtl"] .treeItemToggler::before {
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.treeItem.selected > a {
|
||||
background-color: var(--treeitem-selected-bg-color);
|
||||
color: var(--treeitem-selected-color);
|
||||
}
|
||||
|
||||
.treeItemToggler:hover,
|
||||
.treeItemToggler:hover + a,
|
||||
.treeItemToggler:hover ~ .treeItems,
|
||||
@ -1458,12 +1487,6 @@ html[dir="rtl"] .treeItemToggler::before {
|
||||
color: var(--treeitem-hover-color);
|
||||
}
|
||||
|
||||
.treeItem.selected {
|
||||
background-color: var(--treeitem-active-bg-color);
|
||||
background-clip: padding-box;
|
||||
color: var(--treeitem-active-color);
|
||||
}
|
||||
|
||||
/* TODO: file FF bug to support ::-moz-selection:window-inactive
|
||||
so we can override the opaque grey background when the window is inactive;
|
||||
see https://bugzilla.mozilla.org/show_bug.cgi?id=706209 */
|
||||
|
@ -76,19 +76,31 @@ See https://github.com/adobe-type-tools/cmap-resources
|
||||
|
||||
<div id="sidebarContainer">
|
||||
<div id="toolbarSidebar">
|
||||
<div class="splitToolbarButton toggled">
|
||||
<button id="viewThumbnail" class="toolbarButton toggled" title="Show Thumbnails" tabindex="2" data-l10n-id="thumbs">
|
||||
<span data-l10n-id="thumbs_label">Thumbnails</span>
|
||||
</button>
|
||||
<button id="viewOutline" class="toolbarButton" title="Show Document Outline (double-click to expand/collapse all items)" tabindex="3" data-l10n-id="document_outline">
|
||||
<span data-l10n-id="document_outline_label">Document Outline</span>
|
||||
</button>
|
||||
<button id="viewAttachments" class="toolbarButton" title="Show Attachments" tabindex="4" data-l10n-id="attachments">
|
||||
<span data-l10n-id="attachments_label">Attachments</span>
|
||||
</button>
|
||||
<button id="viewLayers" class="toolbarButton" title="Show Layers (double-click to reset all layers to the default state)" tabindex="5" data-l10n-id="layers">
|
||||
<span data-l10n-id="layers_label">Layers</span>
|
||||
</button>
|
||||
<div id="toolbarSidebarLeft">
|
||||
<div class="splitToolbarButton toggled">
|
||||
<button id="viewThumbnail" class="toolbarButton toggled" title="Show Thumbnails" tabindex="2" data-l10n-id="thumbs">
|
||||
<span data-l10n-id="thumbs_label">Thumbnails</span>
|
||||
</button>
|
||||
<button id="viewOutline" class="toolbarButton" title="Show Document Outline (double-click to expand/collapse all items)" tabindex="3" data-l10n-id="document_outline">
|
||||
<span data-l10n-id="document_outline_label">Document Outline</span>
|
||||
</button>
|
||||
<button id="viewAttachments" class="toolbarButton" title="Show Attachments" tabindex="4" data-l10n-id="attachments">
|
||||
<span data-l10n-id="attachments_label">Attachments</span>
|
||||
</button>
|
||||
<button id="viewLayers" class="toolbarButton" title="Show Layers (double-click to reset all layers to the default state)" tabindex="5" data-l10n-id="layers">
|
||||
<span data-l10n-id="layers_label">Layers</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="toolbarSidebarRight">
|
||||
<div id="outlineOptionsContainer" class="hidden">
|
||||
<div class="verticalToolbarSeparator"></div>
|
||||
|
||||
<button id="currentOutlineItem" class="toolbarButton" disabled="disabled" title="Find Current Outline Item" tabindex="6" data-l10n-id="current_outline_item">
|
||||
<span data-l10n-id="current_outline_item_label">Current Outline Item</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sidebarContent">
|
||||
|
@ -132,6 +132,11 @@ function getViewerConfiguration() {
|
||||
outlineView: document.getElementById("outlineView"),
|
||||
attachmentsView: document.getElementById("attachmentsView"),
|
||||
layersView: document.getElementById("layersView"),
|
||||
// View-specific options
|
||||
outlineOptionsContainer: document.getElementById(
|
||||
"outlineOptionsContainer"
|
||||
),
|
||||
currentOutlineItemButton: document.getElementById("currentOutlineItem"),
|
||||
},
|
||||
sidebarResizer: {
|
||||
outerContainer: document.getElementById("outerContainer"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user