New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

prosemirror-view

Package Overview
Dependencies
Maintainers
1
Versions
287
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prosemirror-view - npm Package Compare versions

Comparing version

to
1.16.0

10

CHANGELOG.md

@@ -0,1 +1,11 @@

## 1.16.0 (2020-10-01)
### Bug fixes
Fix an issue where a drag starting briefly after an aborted drag could confuse the view and break the second drag. Allow callers of coordsAtPos to specify a side
### New features
`EditorView.coordsAtPos` now takes a `side` argument that determines which side of the position to look, if ambiguous.
## 1.15.7 (2020-09-11)

@@ -2,0 +12,0 @@

2

package.json
{
"name": "prosemirror-view",
"version": "1.15.7",
"version": "1.16.0",
"description": "ProseMirror's view component",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -15,4 +15,9 @@ import browser from "./browser"

let reusedRange = null
// Note that this will always return the same range, because DOM range
// objects are every expensive, and keep slowing down subsequent DOM
// updates, for some reason.
export const textRange = function(node, from, to) {
let range = document.createRange()
let range = reusedRange || (reusedRange = document.createRange())
range.setEnd(node, to == null ? node.nodeValue.length : to)

@@ -19,0 +24,0 @@ range.setStart(node, from || 0)

@@ -1,2 +0,2 @@

import {nodeSize, textRange, parentNode} from "./dom"
import {nodeSize, textRange, parentNode, domIndex} from "./dom"
import browser from "./browser"

@@ -288,11 +288,16 @@

// : (EditorView, number) → {left: number, top: number, right: number, bottom: number}
const BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/
// : (EditorView, number, number) → {left: number, top: number, right: number, bottom: number}
// Given a position in the document model, get a bounding box of the
// character at that position, relative to the window.
export function coordsAtPos(view, pos) {
export function coordsAtPos(view, pos, side) {
let {node, offset} = view.docView.domFromPos(pos)
let $pos = view.state.doc.resolve(pos), inline = $pos.parent.inlineContent
// These browsers support querying empty text ranges
if (node.nodeType == 3 && (browser.webkit || browser.gecko)) {
let rect = singleRect(textRange(node, offset, offset), 0)
// These browsers support querying empty text ranges. Prefer that in
// bidi context.
let supportEmptyRange = browser.webkit || browser.gecko
if (node.nodeType == 3 && supportEmptyRange && BIDI.test(node.nodeValue)) {
let rect = singleRect(textRange(node, offset, offset), side)
// Firefox returns bad results (the position before the space)

@@ -312,43 +317,49 @@ // when querying a position directly after line-broken

if (node.nodeType == 1 && !view.state.doc.resolve(pos).parent.inlineContent) {
// Return a horizontal line in block context
let top = true, rect
if (offset < node.childNodes.length) {
let after = node.childNodes[offset]
if (after.nodeType == 1) rect = after.getBoundingClientRect()
// Move up the DOM as far as possible when in inline context.
if (inline) {
let parent = $pos.depth ? view.docView.domAfterPos($pos.before()) : view.dom
while (side < 0 && !offset && node != parent) {
offset = domIndex(node)
node = node.parentNode
}
if (!rect && offset) {
let before = node.childNodes[offset - 1]
if (before.nodeType == 1) { rect = before.getBoundingClientRect(); top = false }
while (side >= 0 && offset == nodeSize(node) && node != parent) {
offset = domIndex(node) + 1
node = node.parentNode
}
return flattenH(rect || node.getBoundingClientRect(), top)
}
// Not Firefox/Chrome, or not in a text node, so we have to use
// actual element/character rectangles to get a solution (this part
// is not very bidi-safe)
//
// Try the left side first, fall back to the right one if that
// doesn't work.
for (let dir = -1; dir < 2; dir += 2) {
if (dir < 0 && offset) {
let prev, target = node.nodeType == 3 ? textRange(node, offset - 1, offset)
: (prev = node.childNodes[offset - 1]).nodeType == 3 ? textRange(prev)
: prev.nodeType == 1 && prev.nodeName != "BR" ? prev : null // BR nodes tend to only return the rectangle before them
if (target) {
let rect = singleRect(target, 1)
if (rect.top < rect.bottom) return flattenV(rect, false)
}
} else if (dir > 0 && offset < nodeSize(node)) {
let next, target = node.nodeType == 3 ? textRange(node, offset, offset + 1)
: (next = node.childNodes[offset]).nodeType == 3 ? textRange(next)
: next.nodeType == 1 ? next : null
if (target) {
let rect = singleRect(target, -1)
if (rect.top < rect.bottom) return flattenV(rect, true)
}
if (node.nodeType == 3) {
if (side < 0) return flattenV(singleRect(textRange(node, offset - 1, offset), 1), false)
return flattenV(singleRect(textRange(node, offset, offset + 1), -1), true)
}
// Return a horizontal line in block context
if (!inline) {
if (offset && (side < 0 || offset == nodeSize(node))) {
let before = node.childNodes[offset - 1]
if (before.nodeType == 1) return flattenH(before.getBoundingClientRect(), false)
}
if (offset < nodeSize(node)) {
let after = node.childNodes[offset]
if (after.nodeType == 1) return flattenH(after.getBoundingClientRect(), true)
}
return flattenH(node.getBoundingClientRect(), side >= 0)
}
// Inline, not in text node (this is not Bidi-safe)
if (offset && (side < 0 || offset == nodeSize(node))) {
let before = node.childNodes[offset - 1]
let target = before.nodeType == 3 ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1))
// BR nodes tend to only return the rectangle before them
: before.nodeType == 1 && before.nodeName != "BR" ? before : null
if (target) return flattenV(singleRect(target, 1), false)
}
if (offset < nodeSize(node)) {
let after = node.childNodes[offset]
let target = after.nodeType == 3 ? textRange(after, 0, (supportEmptyRange ? 0 : 1))
: after.nodeType == 1 ? after : null
if (target) return flattenV(singleRect(target, -1), true)
}
// All else failed, just try to get a rectangle for the target node
return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, 0), false)
return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, -side), side >= 0)
}

@@ -394,3 +405,3 @@

}
let coords = coordsAtPos(view, $pos.pos)
let coords = coordsAtPos(view, $pos.pos, 1)
for (let child = dom.firstChild; child; child = child.nextSibling) {

@@ -397,0 +408,0 @@ let boxes

@@ -192,3 +192,3 @@ import {NodeSelection} from "prosemirror-state"

else
scrollRectIntoView(this, this.coordsAtPos(state.selection.head), startDOM)
scrollRectIntoView(this, this.coordsAtPos(state.selection.head, 1), startDOM)
} else if (oldScrollPos) {

@@ -279,8 +279,11 @@ resetScrollPos(oldScrollPos)

// :: (number) → {left: number, right: number, top: number, bottom: number}
// Returns the viewport rectangle at a given document position. `left`
// and `right` will be the same number, as this returns a flat
// cursor-ish rectangle.
coordsAtPos(pos) {
return coordsAtPos(this, pos)
// :: (number, number) → {left: number, right: number, top: number, bottom: number}
// Returns the viewport rectangle at a given document position.
// `left` and `right` will be the same number, as this returns a
// flat cursor-ish rectangle. If the position is between two things
// that aren't directly adjacent, `side` determines which element is
// used. When < 0, the element before the position is used,
// otherwise the element after.
coordsAtPos(pos, side = 1) {
return coordsAtPos(this, pos, side)
}

@@ -287,0 +290,0 @@

@@ -585,3 +585,6 @@ import {Selection, NodeSelection, TextSelection} from "prosemirror-state"

handlers.dragend = view => {
window.setTimeout(() => view.dragging = null, 50)
let dragging = view.dragging
window.setTimeout(() => {
if (view.dragging == dragging) view.dragging = null
}, 50)
}

@@ -588,0 +591,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet