Comments (12)
I can reproduce using https://hypothes.is/docs/help and selecting exactly the same text as in the screencast.
In doing so, I see this error in the browser console:
Uncaught (in promise) TypeError: Cannot read property 'nodeType' of undefined
at Object.Util.getFirstTextNodeNotBefore (https://hypothes.is/assets/client/scripts/injector.bundle.js?bb3e58:4160:14)
at BrowserRange.Range.BrowserRange.BrowserRange.normalize (https://hypothes.is/assets/client/scripts/injector.bundle.js?bb3e58:4531:24)
at https://hypothes.is/assets/client/scripts/injector.bundle.js?bb3e58:1424:29
at https://hypothes.is/assets/client/scripts/injector.bundle.js?bb3e58:1130:24
This is the same error I think as the PDF selection issue.
from client.
I just reproduced the issue a second time but didn't see any any error in the console.
from client.
I think the reason why the draft suddenly appears when switching groups may be related to the way that, when switching groups, we first unload all annotations and then reload drafts.unsaved()
.
That's unnecessary - we should just unload the saved annotations, but it also suggests that we're relying on possibly stale copies of the annotation which might be stored in the drafts service.
from client.
OK, I've confirmed the above. Changing the _resetAnnotations()
function in widget-controller.js
to only unload saved annotations when switching groups fixes the problem:
function _resetAnnotations() {
annotationMapper.unloadAnnotations(annotationUI.savedAnnotations());
}
Where savedAnnotations()
is a function that returns all annotations currently loaded that have an ID.
from client.
I can reproduce this issue in Chrome 54.0.2816.0 but not Firefox Nightly (v51.a1)
from client.
Error reported above is the same as #73 and #124
from client.
An error occurs when serializing the range to each type of selector in describe()
in annotator/anchoring/html.coffee
but this error gets swallowed and the result is a new annotation with no associated selectors. This is why the annotation turns into a Page Note after saving.
Error describing range with type RangeAnchor(root, range) {
if (root == null) {
missingParameter('root');
}
if (range == null) {
missingParameter('range');
}
this.root = root;
this.range =… TypeError: Cannot read property 'nodeType' of undefined
at Object.Util.getLastTextNodeUpTo (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:4042:14)
at BrowserRange.Range.BrowserRange.BrowserRange.normalize (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:4455:24)
at new RangeAnchor (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:724:42)
at Function.RangeAnchor.fromRange (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:728:12)
at http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:370:23
at Object.exports.describe (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:379:5)
at getSelectors (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:1409:29)
at Array.map (native)
at Sidebar.module.exports.Guest.createAnnotation (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:1433:36)
at Sidebar.module.exports.Sidebar.createAnnotation (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:2947:40)
html.coffee:110 Error describing range with type TextPositionAnchor(root, start, end) {
_classCallCheck(this, TextPositionAnchor);
if (root === undefined) {
throw new Error('missing required parameter "root"');
}
if (… TypeError: Cannot read property 'nodeType' of null
at isText (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:8529:14)
at seek (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:8500:14)
at Function.fromRange (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:8288:50)
at http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:370:23
at Object.exports.describe (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:379:5)
at getSelectors (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:1409:29)
at Array.map (native)
at Sidebar.module.exports.Guest.createAnnotation (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:1433:36)
at Sidebar.module.exports.Sidebar.createAnnotation (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:2947:40)
at Object.onAnnotate (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:1062:14)
html.coffee:110 Error describing range with type TextQuoteAnchor(root, exact) {
var context = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
_classCallCheck(this, TextQuoteAnchor);
if (root === undefi… TypeError: Cannot read property 'nodeType' of null
at isText (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:8529:14)
at seek (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:8500:14)
at Function.fromRange (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:8288:50)
at Function.fromRange (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:8436:57)
at http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:370:23
at Object.exports.describe (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:379:5)
at getSelectors (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:1409:29)
at Array.map (native)
at Sidebar.module.exports.Guest.createAnnotation (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:1433:36)
at Sidebar.module.exports.Sidebar.createAnnotation (http://localhost:5000/assets/client/scripts/injector.bundle.js?06fae6:2947:40)
from client.
When clicking Annotate after triple-clicking to select the current sentence, the selected range in Chrome looks like this:
Range structure
commonAncestorContainer: <section>
startContainer: #text ("There are...")
startOffset: 0
endContainer: <h3>
endOffset: 0
HTML Structure
<section>
<p><span>[START]There are</span>#text</p>
<div>
<section class="feature-heading">
<h3>[END]<i class="feature-icon ..."></i>Notes
The code in BrowserRange#normalize
attempts to ensure that the range starts and ends at a text node, such that Text.splitText can be called on the start and end nodes.
If the end container is not a text node, it attempts to drill down through the children of this node, starting at endContainer[endOffset]
and then iteratively visiting the first child of the current node, until it reaches a text node. It then sets the start of that text node as the end of the selection. In this case, the <h3>
has no text child. A fallback code path then gets triggered which attempts to get the last text node in the subtree rooted at endContainer[endOffset-1]
and uses the end text position of that node. Since endOffset
is 0, there is no such node, so this logic fails.
from client.
For the text position anchor, there is also an assumption that the end node of the supplied range has a text node descendant, which is not the case here. The text quote anchor fails for the same reason, since it relies on the text position anchor.
// #fromRange method in dom-anchor-text-position
// Drill down to a text node if the range ends at the container boundary.
if (endNode.nodeType !== Node.TEXT_NODE) {
if (endOffset === endNode.childNodes.length) {
endNode = endNode.childNodes[endOffset - 1];
endNode = getFirstTextNode(endNode);
endOffset = endNode.textContent.length;
} else {
endNode = endNode.childNodes[endOffset];
// **Assumes that `endNode` has a text node descendant, which is
// not the case**
endNode = getFirstTextNode(endNode);
endOffset = 0;
}
}
var iter = (0, _nodeIteratorShim2['default'])(root, SHOW_TEXT);
var start = (0, _domSeek2['default'])(iter, startNode);
var end = start + (0, _domSeek2['default'])(iter, endNode);
from client.
This is fixed by the upstream changes in tilgovi/dom-anchor-text-position@d0d11e3 which drastically simplify how range -> selector conversion works for text positions.
from client.
Fix error capturing selectors for certain selections
from client.
The cause of this error is that the new annotation, when initially created, has a range selector but no position or quote selectors.
Anchoring always fails for annotations without quote selectors.
The failure to create position and quote anchors is captured by a set of test cases in
. Randall has changed the way position and quote anchoring works in the latest version of thedom-anchor-text-{position, quote}
libraries which fixed the problem when I tested briefly. The next step is to upgrade these libraries to the latest version, which always requires adapting to some API changes.from client.
Related Issues (20)
- Add status message confirming when a highlight is created HOT 1
- Consider keeping sidebar state when opening modals via native `dialog`.
- Use a native `dialog` in user profile modal
- Indicate links that open in new tabs to assistive technologies HOT 1
- Improve close button label specificity
- Can't annotate https://community.canvaslms.com/ (issue with tsParticles) HOT 2
- Validate max length for tags
- Error with iframe `allow` attribute when annotating pages on archive.org HOT 6
- Migrate to eslint flat config HOT 1
- Create a new toast-like notification that is displayed when there are pending updates HOT 2
- Add accessible `tabpanel` role to the panels handled by selection tabs in the sidebar
- Hide "annotate" and "highlight" icons from "Getting started" tab to screen readers
- Consider automatically closing the help panel if auto-opened and user creates annotations HOT 2
- Optionally preserve (carry over) tags for the ensuing annotation
- can't log in at Edge add-on HOT 3
- Multiple annotations by the same person have the same accessible title HOT 3
- Annotation cards can be interacted with the mouse but not with the keyboard
- Reconsider the usage of "dialogs" for non-modal sidebar panels
- When loading pending updates, consider scrolling to the "closest" one, not the latest one HOT 2
- Incorrect Conversion of Overlapping Highlights or Notes Upon Page Navigation HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from client.