Commit e85d2186 authored by Robert Knight's avatar Robert Knight Committed by GitHub

Merge pull request #159 from hypothesis/anchor-lib-update

Update to latest version of dom-anchor-text-{quote, position} libs
parents 6b9b2b26 9b9f56c9
'use strict'; 'use strict';
var html = require('../html'); var html = require('../html');
var unroll = require('../../../test/util').unroll;
var toResult = require('../../../test/promise-util').toResult;
var unroll = require('../../../test/util').unroll;
var fixture = require('./html-anchoring-fixture.html'); var fixture = require('./html-anchoring-fixture.html');
/** Return all text node children of `container`. */ /** Return all text node children of `container`. */
...@@ -120,19 +121,8 @@ var rangeSpecs = [ ...@@ -120,19 +121,8 @@ var rangeSpecs = [
*/ */
var expectedFailures = [ var expectedFailures = [
// [description, expectedFailureTypes] // [description, expectedFailureTypes]
['Full node contents with empty node at end.', {position: true, quote: true}],
['Text between br tags, elementNode ref at end', {position: true, quote: true}], // Currently empty.
['Text between br tags, with <br/> at end', {position: true, quote: true}],
['Text between br tags, with <br/><br/> at end', {position: true, quote: true}],
['Text between br tags, with <br/> at start', {position: true, quote: true}],
['Text between br tags, with <br/><br/> at start', {position: true, quote: true}],
['Text between br tags, elementNode ref at end', {position: true, quote: true}],
['Text between br tags, with <br/> at end', {position: true, quote: true}],
['Text between br tags, with <br/><p><br/></p> at end', {position: true, quote: true}],
['Text between br tags, with <p><br/></p> at the start', {position: true, quote: true}],
['Text between br tags, with <br/><p><br/></p> at the start', {position: true, quote: true}],
['No text node at the end and offset 0', {position: true, quote: true}],
['Range starting at an element node with no children', {position: true, quote: true}],
]; ];
describe('HTML anchoring', function () { describe('HTML anchoring', function () {
...@@ -201,6 +191,50 @@ describe('HTML anchoring', function () { ...@@ -201,6 +191,50 @@ describe('HTML anchoring', function () {
return Promise.all(anchored); return Promise.all(anchored);
}, testCases); }, testCases);
describe('When anchoring fails', function () {
var validQuoteSelector = {
type: 'TextQuoteSelector',
exact: 'Lorem ipsum',
};
it('throws an error if anchoring using a quote fails', function () {
var quoteSelector = {
type: 'TextQuoteSelector',
exact: 'This text does not appear in the web page',
};
return toResult(html.anchor(container, [quoteSelector])).then(function (result) {
assert.equal(result.error.message, 'Quote not found');
});
});
it('does not throw an error if anchoring using a position fails', function () {
var positionSelector = {
type: 'TextPositionSelector',
start: 1000,
end: 1010,
};
// Providing an annotation has quote selector that anchors, a position
// selector which fails to anchor should be ignored.
return html.anchor(container, [positionSelector, validQuoteSelector]);
});
it('does not throw an error if anchoring using a range fails', function () {
var rangeSelector = {
type: 'RangeSelector',
startContainer: '/main',
startOffset: 1,
endContainer: '/main',
endOffset: 5,
};
// Providing an annotation has quote selector that anchors, a range
// selector which fails to anchor should be ignored.
return html.anchor(container, [rangeSelector, validQuoteSelector]);
});
});
describe('Web page baselines', function () { describe('Web page baselines', function () {
var fixtures = require('./html-baselines'); var fixtures = require('./html-baselines');
var frame; var frame;
......
'use strict'; 'use strict';
var TextQuoteAnchor = require('dom-anchor-text-quote'); var domAnchorTextQuote = require('dom-anchor-text-quote');
var FakePDFViewerApplication = require('./fake-pdf-viewer-application'); var FakePDFViewerApplication = require('./fake-pdf-viewer-application');
var pdfAnchoring = require('../pdf'); var pdfAnchoring = require('../pdf');
...@@ -13,7 +13,7 @@ var pdfAnchoring = require('../pdf'); ...@@ -13,7 +13,7 @@ var pdfAnchoring = require('../pdf');
* @return {Range} * @return {Range}
*/ */
function findText(container, text) { function findText(container, text) {
return new TextQuoteAnchor(container, text).toRange(); return domAnchorTextQuote.toRange(container, {exact: text});
} }
var fixtures = { var fixtures = {
......
xpathRange = require('./range') domAnchorTextPosition = require('dom-anchor-text-position')
domAnchorTextQuote = require('dom-anchor-text-quote')
xpathRange = require('./range')
# Helper function for throwing common errors # Helper function for throwing common errors
missingParameter = (name) -> missingParameter = (name) ->
...@@ -47,7 +49,65 @@ class RangeAnchor ...@@ -47,7 +49,65 @@ class RangeAnchor
endOffset: range.endOffset endOffset: range.endOffset
} }
###*
# Converts between TextPositionSelector selectors and Range objects.
###
class TextPositionAnchor
constructor: (root, start, end) ->
@root = root
@start = start
@end = end
@fromRange: (root, range) ->
selector = domAnchorTextPosition.fromRange(root, range)
TextPositionAnchor.fromSelector(root, selector)
@fromSelector: (root, selector) ->
new TextPositionAnchor(root, selector.start, selector.end)
toSelector: () ->
{
type: 'TextPositionSelector',
start: @start,
end: @end,
}
toRange: () ->
domAnchorTextPosition.toRange(@root, {start: @start, end: @end})
###*
# Converts between TextQuoteSelector selectors and Range objects.
###
class TextQuoteAnchor
constructor: (root, exact, context = {}) ->
@root = root
@exact = exact
@context = context
@fromRange: (root, range, options) ->
selector = domAnchorTextQuote.fromRange(root, range, options)
TextQuoteAnchor.fromSelector(root, selector)
@fromSelector: (root, selector) ->
{prefix, suffix} = selector
new TextQuoteAnchor(root, selector.exact, {prefix, suffix})
toSelector: () ->
{
type: 'TextQuoteSelector',
exact: @exact,
prefix: @context.prefix,
suffix: @context.suffix,
}
toRange: (options = {}) ->
range = domAnchorTextQuote.toRange(@root, this.toSelector(), options)
if range == null
throw new Error('Quote not found')
range
exports.RangeAnchor = RangeAnchor exports.RangeAnchor = RangeAnchor
exports.FragmentAnchor = require('dom-anchor-fragment') exports.FragmentAnchor = require('dom-anchor-fragment')
exports.TextPositionAnchor = require('dom-anchor-text-position') exports.TextPositionAnchor = TextPositionAnchor
exports.TextQuoteAnchor = require('dom-anchor-text-quote') exports.TextQuoteAnchor = TextQuoteAnchor
...@@ -66,6 +66,11 @@ ...@@ -66,6 +66,11 @@
"from": "amdefine@>=0.0.4", "from": "amdefine@>=0.0.4",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz"
}, },
"ancestors": {
"version": "0.0.3",
"from": "ancestors@0.0.3",
"resolved": "https://registry.npmjs.org/ancestors/-/ancestors-0.0.3.tgz"
},
"angular": { "angular": {
"version": "1.5.6", "version": "1.5.6",
"from": "angular@latest", "from": "angular@latest",
...@@ -1167,14 +1172,26 @@ ...@@ -1167,14 +1172,26 @@
"resolved": "https://registry.npmjs.org/dom-anchor-fragment/-/dom-anchor-fragment-1.0.4.tgz" "resolved": "https://registry.npmjs.org/dom-anchor-fragment/-/dom-anchor-fragment-1.0.4.tgz"
}, },
"dom-anchor-text-position": { "dom-anchor-text-position": {
"version": "2.0.1", "version": "4.0.0",
"from": "dom-anchor-text-position@>=2.0.0 <3.0.0", "from": "dom-anchor-text-position@latest",
"resolved": "https://registry.npmjs.org/dom-anchor-text-position/-/dom-anchor-text-position-2.0.1.tgz" "resolved": "https://registry.npmjs.org/dom-anchor-text-position/-/dom-anchor-text-position-4.0.0.tgz",
"dependencies": {
"dom-seek": {
"version": "4.0.3",
"from": "dom-seek@>=4.0.1 <5.0.0",
"resolved": "https://registry.npmjs.org/dom-seek/-/dom-seek-4.0.3.tgz"
}
}
}, },
"dom-anchor-text-quote": { "dom-anchor-text-quote": {
"version": "2.0.1", "version": "4.0.1",
"from": "dom-anchor-text-quote@>=2.0.0 <3.0.0", "from": "dom-anchor-text-quote@latest",
"resolved": "https://registry.npmjs.org/dom-anchor-text-quote/-/dom-anchor-text-quote-2.0.1.tgz" "resolved": "https://registry.npmjs.org/dom-anchor-text-quote/-/dom-anchor-text-quote-4.0.1.tgz"
},
"dom-node-iterator": {
"version": "3.5.3",
"from": "dom-node-iterator@>=3.5.0 <4.0.0",
"resolved": "https://registry.npmjs.org/dom-node-iterator/-/dom-node-iterator-3.5.3.tgz"
}, },
"dom-seek": { "dom-seek": {
"version": "1.0.1", "version": "1.0.1",
...@@ -2192,6 +2209,11 @@ ...@@ -2192,6 +2209,11 @@
} }
} }
}, },
"index-of": {
"version": "0.2.0",
"from": "index-of@>=0.2.0 <0.3.0",
"resolved": "https://registry.npmjs.org/index-of/-/index-of-0.2.0.tgz"
},
"indexof": { "indexof": {
"version": "0.0.1", "version": "0.0.1",
"from": "indexof@0.0.1", "from": "indexof@0.0.1",
...@@ -3198,11 +3220,6 @@ ...@@ -3198,11 +3220,6 @@
} }
} }
}, },
"node-iterator-shim": {
"version": "2.0.1",
"from": "node-iterator-shim@>=2.0.1 <3.0.0",
"resolved": "https://registry.npmjs.org/node-iterator-shim/-/node-iterator-shim-2.0.1.tgz"
},
"node-sass": { "node-sass": {
"version": "3.7.0", "version": "3.7.0",
"from": "node-sass@>=3.4.1 <4.0.0", "from": "node-sass@>=3.4.1 <4.0.0",
......
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
"diff-match-patch": "^1.0.0", "diff-match-patch": "^1.0.0",
"document-base-uri": "^1.0.0", "document-base-uri": "^1.0.0",
"dom-anchor-fragment": "^1.0.1", "dom-anchor-fragment": "^1.0.1",
"dom-anchor-text-position": "^2.0.0", "dom-anchor-text-position": "^4.0.0",
"dom-anchor-text-quote": "^2.0.0", "dom-anchor-text-quote": "^4.0.1",
"dom-seek": "^1.0.1", "dom-seek": "^1.0.1",
"end-of-stream": "^1.1.0", "end-of-stream": "^1.1.0",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
......
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