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'; 'use strict';
var annotationIDs = require('./util/annotation-ids'); var annotationQuery = require('./util/extract-annotation-query');
var settings = require('../shared/settings'); var settings = require('../shared/settings');
var docs = 'https://h.readthedocs.io/en/latest/embedding.html'; var docs = 'https://h.readthedocs.io/en/latest/embedding.html';
...@@ -33,7 +33,7 @@ function config(window_) { ...@@ -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 // 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 // via a tag injected into the DOM, which avoids the problem where the page's
...@@ -41,9 +41,9 @@ function config(window_) { ...@@ -41,9 +41,9 @@ function config(window_) {
// //
// In environments where the config has not been injected into the DOM, // In environments where the config has not been injected into the DOM,
// we try to retrieve it from the URL here. // 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) { if (directLinkedID) {
options.annotations = directLinkedID; Object.assign(options, directLinkedID);
} }
return options; return options;
} }
......
...@@ -27,7 +27,7 @@ module.exports = class Sidebar extends Host ...@@ -27,7 +27,7 @@ module.exports = class Sidebar extends Host
super super
this.hide() this.hide()
if options.openSidebar || options.annotations if options.openSidebar || options.annotations || options.query
this.on 'panelReady', => this.show() this.on 'panelReady', => this.show()
if @plugins.BucketBar? if @plugins.BucketBar?
......
'use strict'; '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>' * @param {string} url - The URL which may contain a '#annotations:<ID>'
* fragment. * 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 { try {
// Annotation IDs are url-safe-base64 identifiers // Annotation IDs are url-safe-base64 identifiers
// See https://tools.ietf.org/html/rfc4648#page-7 // See https://tools.ietf.org/html/rfc4648#page-7
var annotFragmentMatch = url.match(/#annotations:([A-Za-z0-9_-]+)$/); var annotFragmentMatch = url.match(/#annotations:([A-Za-z0-9_-]+)$/);
if (annotFragmentMatch) { var queryFragmentMatch = url.match(/#annotations:(query|q):(.+)$/i);
return annotFragmentMatch[1]; if (queryFragmentMatch) {
filter.query = decodeURI(queryFragmentMatch[2]);
} else if (annotFragmentMatch) {
filter.annotations = annotFragmentMatch[1];
} else { } else {
return null; filter = null;
} }
} catch (err) { } catch (err) {
return null; // URI Error should return the page unfiltered.
filter = null;
} }
return filter;
} }
module.exports = { 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',
}]);
});
...@@ -17,6 +17,9 @@ function hostPageConfig(window) { ...@@ -17,6 +17,9 @@ function hostPageConfig(window) {
// Direct-linked annotation ID // Direct-linked annotation ID
'annotations', 'annotations',
// Default query passed by url
'query',
// Config param added by the extension, Via etc. indicating how Hypothesis // Config param added by the extension, Via etc. indicating how Hypothesis
// was added to the page. // was added to the page.
'appType', 'appType',
......
...@@ -16,6 +16,7 @@ var uiConstants = require('../ui-constants'); ...@@ -16,6 +16,7 @@ var uiConstants = require('../ui-constants');
var util = require('./util'); var util = require('./util');
/** /**
* Default starting tab. * Default starting tab.
*/ */
...@@ -37,9 +38,10 @@ TAB_SORTKEYS_AVAILABLE[uiConstants.TAB_ANNOTATIONS] = ['Newest', 'Oldest', 'Loca ...@@ -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_NOTES] = ['Newest', 'Oldest'];
TAB_SORTKEYS_AVAILABLE[uiConstants.TAB_ORPHANS] = ['Newest', 'Oldest', 'Location']; TAB_SORTKEYS_AVAILABLE[uiConstants.TAB_ORPHANS] = ['Newest', 'Oldest', 'Location'];
function initialSelection(settings) { function initialSelection(settings) {
var selection = {}; var selection = {};
if (settings.annotations) { if (settings.annotations && !settings.query) {
selection[settings.annotations] = true; selection[settings.annotations] = true;
} }
return freeze(selection); return freeze(selection);
...@@ -81,7 +83,7 @@ function init(settings) { ...@@ -81,7 +83,7 @@ function init(settings) {
// IDs of annotations that should be highlighted // IDs of annotations that should be highlighted
highlighted: [], highlighted: [],
filterQuery: null, filterQuery: settings.query || null,
selectedTab: TAB_DEFAULT, 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