Skip to content
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: 1 addition & 1 deletion BookReaderDemo/IADemoBr.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const initializeBookReader = (brManifest) => {
enableFSLogoShortcut: true,
plugins: {
search: {
initialSearchTerm: searchTerm ? searchTerm : '',
initialSearchTerm: searchTerm,
},
},
};
Expand Down
5 changes: 5 additions & 0 deletions src/BookReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ BookReader.prototype.init = function() {
this.pageScale = this.reduce; // preserve current reduce

const params = this.initParams();
this.urlPlugin?.pullFromAddressBar();
this.firstIndex = params.index ? params.index : 0;

// Setup Navbars and other UI
Expand Down Expand Up @@ -1960,6 +1961,10 @@ BookReader.prototype.queryStringFromParams = function(
) {
const newParams = new URLSearchParams(currQueryString);

// Never write back UI-only params that are consumed on load
// TODO: Should ideally stick around until next URL change
newParams.delete('focus');

if (params.view) {
// Set ?view=theater when fullscreen
newParams.set('view', params.view);
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/search/plugin.search.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export class SearchPlugin extends BookReaderPlugin {
this.options.initialSearchTerm,
{ goToFirstResult: this.options.goToFirstResult, suppressFragmentChange: false },
);
} else if (this.br.urlPlugin?.getUrlParam('focus') === 'search') {
this.searchView.toggleSidebar();
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/plugins/url/UrlPlugin.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
/**
* @typedef {Object} UrlSchemaEntry
* @property {string} name
* @property {'path' | 'query_param'} position
* @property {string} [default]
* @property {string} [deprecated_for]
* @property {boolean} [readOnly] - If true, the param is read from the URL but never written back
*/

export class UrlPlugin {
constructor(options = {}) {
this.bookReaderOptions = options;

// the canonical order of elements is important in the path and query string
/** @type {UrlSchemaEntry[]} */
this.urlSchema = [
{ name: 'page', position: 'path', default: 'n0' },
{ name: 'mode', position: 'path', default: '2up' },
Expand All @@ -11,6 +21,7 @@ export class UrlPlugin {
{ name: 'sort', position: 'query_param' },
{ name: 'view', position: 'query_param' },
{ name: 'admin', position: 'query_param' },
{ name: 'focus', position: 'query_param', readOnly: true },
];

this.urlState = {};
Expand All @@ -36,6 +47,7 @@ export class UrlPlugin {
if (schema?.deprecated_for) {
schema = this.urlSchema.find(schemaKey => schemaKey.name === schema.deprecated_for);
}
if (schema?.readOnly) return;
if (schema?.position == 'path') {
pathParams[schema?.name] = urlState[key];
} else {
Expand Down
9 changes: 9 additions & 0 deletions tests/jest/plugins/search/plugin.search.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ describe('Plugin: Search', () => {
.toHaveProperty('suppressFragmentChange', false);
});

test('On init with #focus=search in URL hash, it opens the search panel without searching', () => {
br.plugins.search.search = jest.fn();
br.urlPlugin = { pullFromAddressBar: jest.fn(), getUrlParam: jest.fn(() => 'search') };
br.init();

expect(br.plugins.search.searchView.toggleSidebar).toHaveBeenCalled();
expect(br.plugins.search.search).not.toHaveBeenCalled();
});

test('calling `search` fires ajax call`', () => {
br.init();
br.search('foo');
Expand Down
1 change: 1 addition & 0 deletions tests/jest/plugins/url/plugin.url.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ beforeAll(() => {
document.body.innerHTML = '<div id="BookReader">';
br = new BookReader();
const urlPluginMock = {
pullFromAddressBar: sinon.fake(),
retrieveTextFragment: sinon.fake(),
urlStringToUrlState: sinon.fake(),
parseToText: sinon.fake(),
Expand Down
Loading