Commit 9f4ab73f authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #254 from QualitativeDataRepository/queryFromUrl

Query from url
parents 1c1d704c 2cb0ec8c
'use strict';
var annotationIDs = require('./util/annotation-ids');
var annotationQuery = require('./util/extract-annotation-query');
var settings = require('../shared/settings');
var docs = 'https://h.readthedocs.io/en/latest/embedding.html';
......@@ -33,7 +33,7 @@ function config(window_) {
}
}
// Extract the direct linked ID from the URL.
// Extract the default query from the URL.
//
// The Chrome extension or proxy may already have provided this config
// via a tag injected into the DOM, which avoids the problem where the page's
......@@ -41,9 +41,9 @@ function config(window_) {
//
// In environments where the config has not been injected into the DOM,
// we try to retrieve it from the URL here.
var directLinkedID = annotationIDs.extractIDFromURL(window_.location.href);
var directLinkedID = annotationQuery.extractAnnotationQuery(window_.location.href);
if (directLinkedID) {
options.annotations = directLinkedID;
Object.assign(options, directLinkedID);
}
return options;
}
......
......@@ -27,7 +27,7 @@ module.exports = class Sidebar extends Host
super
this.hide()
if options.openSidebar || options.annotations
if options.openSidebar || options.annotations || options.query
this.on 'panelReady', => this.show()
if @plugins.BucketBar?
......
'use strict';
/**
* Extracts a direct-linked annotation ID from the fragment of a URL.
* Extracts an annotation selection or default filter from a url.
*
* @param {string} url - The URL which may contain a '#annotations:<ID>'
* fragment.
* @return {string?} The annotation ID if present
* @return {Object} - An object with either an annotation ID or a filter string.
*/
function extractIDFromURL(url) {
function extractAnnotationQuery(url) {
var filter = {};
try {
// Annotation IDs are url-safe-base64 identifiers
// See https://tools.ietf.org/html/rfc4648#page-7
var annotFragmentMatch = url.match(/#annotations:([A-Za-z0-9_-]+)$/);
if (annotFragmentMatch) {
return annotFragmentMatch[1];
var queryFragmentMatch = url.match(/#annotations:(query|q):(.+)$/i);
if (queryFragmentMatch) {
filter.query = decodeURI(queryFragmentMatch[2]);
} else if (annotFragmentMatch) {
filter.annotations = annotFragmentMatch[1];
} else {
return null;
filter = null;
}
} catch (err) {
return null;
// URI Error should return the page unfiltered.
filter = null;
}
return filter;
}
module.exports = {
extractIDFromURL: extractIDFromURL,
extractAnnotationQuery: extractAnnotationQuery,
};
'use strict';
var unroll = require('../../../shared/test/util').unroll;
var annotationIds = require('../extract-annotation-query');
describe('annotation queries', function () {
it ('returns null on invalid fragment', function () {
assert.equal(annotationIds.extractAnnotationQuery(
'http://localhost:3000#annotations:\"TRYINGTOGETIN\");EVILSCRIPT()'),
null);
});
unroll('accepts annotation fragment from urls', function (testCase) {
assert.equal(annotationIds.extractAnnotationQuery(testCase.url).annotations, testCase.result);
}, [{
url: 'http://localhost:3000#annotations:alphanum3ric_-only',
result: 'alphanum3ric_-only',
},
]);
unroll('accepts query from annotation fragment', function(testCase) {
assert.equal(annotationIds.extractAnnotationQuery(testCase.url).query, testCase.result);
}, [{
url: 'http://localhost:3000#annotations:q:user:USERNAME',
result: 'user:USERNAME',
},
{
url: 'http://localhost:3000#annotations:QuerY:user:USERNAME',
result: 'user:USERNAME',
}, {
url: 'http://localhost:3000#annotations:q:user:USERNAME%20tag:KEYWORD',
result: 'user:USERNAME tag:KEYWORD',
}]);
});
......@@ -16,6 +16,9 @@ function hostPageConfig(window) {
var paramWhiteList = [
// Direct-linked annotation ID
'annotations',
// Default query passed by url
'query',
// Config param added by the extension, Via etc. indicating how Hypothesis
// was added to the page.
......
......@@ -16,6 +16,7 @@ var uiConstants = require('../ui-constants');
var util = require('./util');
/**
* Default starting tab.
*/
......@@ -37,9 +38,10 @@ TAB_SORTKEYS_AVAILABLE[uiConstants.TAB_ANNOTATIONS] = ['Newest', 'Oldest', 'Loca
TAB_SORTKEYS_AVAILABLE[uiConstants.TAB_NOTES] = ['Newest', 'Oldest'];
TAB_SORTKEYS_AVAILABLE[uiConstants.TAB_ORPHANS] = ['Newest', 'Oldest', 'Location'];
function initialSelection(settings) {
var selection = {};
if (settings.annotations) {
if (settings.annotations && !settings.query) {
selection[settings.annotations] = true;
}
return freeze(selection);
......@@ -81,7 +83,7 @@ function init(settings) {
// IDs of annotations that should be highlighted
highlighted: [],
filterQuery: null,
filterQuery: settings.query || null,
selectedTab: TAB_DEFAULT,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment