Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
10 changes: 9 additions & 1 deletion src/BookReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1976,9 +1976,17 @@ BookReader.prototype.queryStringFromParams = function(
// the browser seems not to handle with the text fragment
if (newParams.get('text')) {
newParams.delete('text');
textFragmentParam = `text=${this.urlPlugin.retrieveTextFragment(currQueryString)}`;
textFragmentParam = `text=${this.urlPlugin.retrieveTextFragment(currQueryString, 'text')}`;
}
if (newParams.get('prefix')) {
newParams.delete('prefix');
textFragmentParam += `&prefix=${this.urlPlugin.retrieveHighlightContext(currQueryString, 'prefix')}`;
}

if (newParams.get('suffix')) {
newParams.delete('suffix');
textFragmentParam += `&suffix=${this.urlPlugin.retrieveHighlightContext(currQueryString, 'suffix')}`;
}
// https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/toString
// Note: This method returns the query string without the question mark.
let result = newParams.toString();
Expand Down
7 changes: 6 additions & 1 deletion src/css/_TextSelection.scss
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,9 @@
width: auto;
margin-left: 4px;
opacity: 1;
}
}

.BRlocalHighlight {
background-color: yellow;
pointer-events: all;
}
18 changes: 16 additions & 2 deletions src/plugins/plugin.experiments.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class ExperimentsPlugin extends BookReaderPlugin {
localStorageKey: 'BrExperiments',

/** The experiments that should be shown in the experiments panel */
enabledExperiments: ['translate', 'copyLinkToHighlight'],
enabledExperiments: ['translate', 'copyLinkToHighlight', 'annotateHighlight'],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
enabledExperiments: ['translate', 'copyLinkToHighlight', 'annotateHighlight'],
enabledExperiments: ['translate', 'copyLinkToHighlight'],

}

/** @type {ExperimentModel[]} */
Expand All @@ -60,7 +60,6 @@ export class ExperimentsPlugin extends BookReaderPlugin {
name = 'copyLinkToHighlight';
title = 'Copy to Selection URL';
description = 'Share text selection via URL';
learnMore = 'none';
icon = null;
enabled = false;
async enable ({ manual = false }) {
Expand All @@ -72,6 +71,21 @@ export class ExperimentsPlugin extends BookReaderPlugin {
});
}
}(),
new class extends ExperimentModel {
name = 'annotateHighlight';
title = 'Highlight and annotate';
description = 'Create private highlights and annotations for this book';
icon = null;
enabled = false;
async enable ({ manual = false }) {
this.br.plugins.textSelection.enableHighlightMenu();
}
async disable() {
sleep(0).then(() => {
window.location.reload();
});
}
}(),
new class extends ExperimentModel {
name = 'translate';
title = 'Translate Plugin';
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/plugin.text_selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ export class TextSelectionPlugin extends BookReaderPlugin {
this.textSelectionManager.renderSelectionMenu();
}

enableHighlightMenu() {
this.textSelectionManager.highlightAnnotationEnabled = true;
this.textSelectionManager.renderHighlightMenu();
}

/**
* @override
* @param {PageContainer} pageContainer
Expand Down
27 changes: 27 additions & 0 deletions src/plugins/url/UrlPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,31 @@ export class UrlPlugin {
retrieveTextFragment(urlString) {
return urlString.match(/(?<=[&?]?text=)[^&]*/);
}

/**
* @param {string} urlString
* @param {string} type
* @returns {string}
*/

retrieveHighlightContext(urlString, type) {
const regexString = new RegExp(String.raw`(?<=[&?]?${type}=)[^&]*`, "gis");
return urlString.match(regexString);
}

/**
* @param {string} urlString
* @returns {object}
*/
convertParamToHighlight(urlString) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be better as a single url parameter, similar to our TextFragment from before. Eg ?text=5:prefix,quote,suffix . Note the tweak that includes the page index at the front to help with disambiguation.

let quote = urlString.match(/(?<=[&?]?text=)[^&]*/);
let prefix = urlString.match(/(?<=[&?]?prefix=)[^&]*/);
let suffix = urlString.match(/(?<=[&?]?suffix=)[^&]*/);
let dIndex = urlString.match(/(?<=[&?]?dIndex=)[^&]*/);
if (quote) quote = decodeURIComponent(quote[0]);
if (prefix) prefix = decodeURIComponent(prefix[0]);
if (suffix) suffix = decodeURIComponent(suffix[0]);
if (dIndex) dIndex = decodeURIComponent(dIndex[0]);
return {prefix, quote, suffix, dIndex};
}
}
19 changes: 10 additions & 9 deletions src/plugins/url/plugin.url.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { UrlPlugin } from "./UrlPlugin.js";
import { sleep } from "../../BookReader/utils.js";

import { convertRangeToDOMSelection } from "../../util/TextSelectionManager.js";
/**
* Plugin for URL management in BookReader
* Note read more about the url "fragment" here:
Expand Down Expand Up @@ -171,8 +171,10 @@ BookReader.prototype.urlUpdateFragment = function() {
} else {
const baseWithoutSlash = this.options.urlHistoryBasePath.replace(/\/+$/, '');
const textFragment = this.urlPlugin.retrieveTextFragment(newQueryString);
this.highlightObject = this.urlPlugin.convertParamToHighlight(newQueryString);
const newUrlPath = `${baseWithoutSlash}${newFragmentWithSlash}${newQueryString}`;
const extractedPage = this.urlPlugin.urlStringToUrlState(newFragmentWithSlash)?.page;

if (!this.textFragmentPage && textFragment) {
this.textFragmentPage = extractedPage ? extractedPage : null;
this.textFragment = `:~:text=${textFragment}`;
Expand All @@ -194,6 +196,7 @@ BookReader.prototype.urlUpdateFragment = function() {
const newQueryStringSearch = this.urlParamsFiltersOnlySearch(this.readQueryString());
let textFragment = this.urlPlugin.retrieveTextFragment(this.readQueryString());
const extractedPage = this.urlPlugin.urlStringToUrlState(newFragmentWithSlash)?.page;
this.highlightObject = this.urlPlugin.convertParamToHighlight(this.readQueryString());

if (textFragment) {
textFragment = `:~:text=${textFragment[0]}`;
Expand Down Expand Up @@ -252,18 +255,16 @@ export class BookreaderUrlPlugin extends BookReader {
if (location.includes("text=")) {
this.on('textLayerVisible', async (_, {pageContainerEl}) => {
const visiblePageNum = pageContainerEl.getAttribute('data-page-num');

const foundPageNum = document.querySelector(`[data-index='${this.highlightObject['dIndex']}']`);
if (!this.highlightObject['dPageNum'] && foundPageNum) {
this.highlightObject['dPageNum'] = foundPageNum.getAttribute('data-page-num');
}
// Hack: More time mode 1up page "settle down" from user scrolling
await sleep(this.mode === 1 ? 900 : 100);
await sleep(this.mode === 1 ? 900 : 200);

// No textFragment found or the textFragment stored doesn't match current visible page loaded
if (!this.textFragment || this.textFragmentPage !== visiblePageNum) return;
if (this.options.urlMode === 'history') {
window.location.replace(`#${this.textFragment}`);
} else {
// for urlMode hash, textFragment is stored in oldLocationHash already
window.location.replace(`#${this.oldLocationHash}`);
}
convertRangeToDOMSelection(this.highlightObject);
});
}
this.bind(BookReader.eventNames.PostInit, () => {
Expand Down
Loading
Loading