@codemirror/view 6.38.6 → 6.38.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/index.cjs +46 -17
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +46 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 6.38.8 (2025-11-17)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Improve handling of composition with multiple cursors on MacOS.
|
|
6
|
+
|
|
7
|
+
Fix an issue where computing a document position from screen coordinates would sometimes go wrong in right-to-left text.
|
|
8
|
+
|
|
9
|
+
## 6.38.7 (2025-11-14)
|
|
10
|
+
|
|
11
|
+
### Bug fixes
|
|
12
|
+
|
|
13
|
+
Make detection of transformed tooltip parent elements (forcing absolute positioning) more robust on current browsers.
|
|
14
|
+
|
|
15
|
+
Avoid an issue where on Chrome and Safari, typing over a cross-line selection can replace widgets on the line after the selection with their plain text content.
|
|
16
|
+
|
|
17
|
+
Fix a bug that broke insertion of composed input at multiple cursors when the IME keeps the selection at the start of the composed text.
|
|
18
|
+
|
|
1
19
|
## 6.38.6 (2025-10-13)
|
|
2
20
|
|
|
3
21
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -3324,6 +3324,13 @@ class DocView extends ContentView {
|
|
|
3324
3324
|
let { offsetWidth, offsetHeight } = this.view.scrollDOM;
|
|
3325
3325
|
scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, Math.max(Math.min(target.xMargin, offsetWidth), -offsetWidth), Math.max(Math.min(target.yMargin, offsetHeight), -offsetHeight), this.view.textDirection == exports.Direction.LTR);
|
|
3326
3326
|
}
|
|
3327
|
+
lineHasWidget(pos) {
|
|
3328
|
+
let { i } = this.childCursor().findPos(pos);
|
|
3329
|
+
if (i == this.children.length)
|
|
3330
|
+
return false;
|
|
3331
|
+
let scan = (child) => child instanceof WidgetView || child.children.some(scan);
|
|
3332
|
+
return scan(this.children[i]);
|
|
3333
|
+
}
|
|
3327
3334
|
}
|
|
3328
3335
|
function betweenUneditable(pos) {
|
|
3329
3336
|
return pos.node.nodeType == 1 && pos.node.firstChild &&
|
|
@@ -3541,7 +3548,7 @@ function domPosInText(node, x, y) {
|
|
|
3541
3548
|
// Check for RTL on browsers that support getting client
|
|
3542
3549
|
// rects for empty ranges.
|
|
3543
3550
|
let rectBefore = textRange(node, i).getBoundingClientRect();
|
|
3544
|
-
if (rectBefore.left
|
|
3551
|
+
if (Math.abs(rectBefore.left - rect.right) < 0.1)
|
|
3545
3552
|
after = !right;
|
|
3546
3553
|
}
|
|
3547
3554
|
if (dy <= 0)
|
|
@@ -4013,7 +4020,10 @@ class DOMChange {
|
|
|
4013
4020
|
anchor = view.state.doc.length;
|
|
4014
4021
|
}
|
|
4015
4022
|
}
|
|
4016
|
-
|
|
4023
|
+
if (view.inputState.composing > -1 && view.state.selection.ranges.length > 1)
|
|
4024
|
+
this.newSel = view.state.selection.replaceRange(state.EditorSelection.range(anchor, head));
|
|
4025
|
+
else
|
|
4026
|
+
this.newSel = state.EditorSelection.single(anchor, head);
|
|
4017
4027
|
}
|
|
4018
4028
|
}
|
|
4019
4029
|
}
|
|
@@ -4069,6 +4079,18 @@ function applyDOMChange(view, domChange) {
|
|
|
4069
4079
|
insert: view.state.doc.slice(sel.from, change.from).append(change.insert).append(view.state.doc.slice(change.to, sel.to))
|
|
4070
4080
|
};
|
|
4071
4081
|
}
|
|
4082
|
+
else if (view.state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) &&
|
|
4083
|
+
view.inputState.insertingTextAt > Date.now() - 50) {
|
|
4084
|
+
// For a cross-line insertion, Chrome and Safari will crudely take
|
|
4085
|
+
// the text of the line after the selection, flattening any
|
|
4086
|
+
// widgets, and move it into the joined line. This tries to detect
|
|
4087
|
+
// such a situation, and replaces the change with a selection
|
|
4088
|
+
// replace of the text provided by the beforeinput event.
|
|
4089
|
+
change = {
|
|
4090
|
+
from: sel.from, to: sel.to,
|
|
4091
|
+
insert: view.state.toText(view.inputState.insertingText)
|
|
4092
|
+
};
|
|
4093
|
+
}
|
|
4072
4094
|
else if (browser.chrome && change && change.from == change.to && change.from == sel.head &&
|
|
4073
4095
|
change.insert.toString() == "\n " && view.lineWrapping) {
|
|
4074
4096
|
// In Chrome, if you insert a space at the start of a wrapped
|
|
@@ -4154,8 +4176,8 @@ function applyDefaultInsert(view, change, newSel) {
|
|
|
4154
4176
|
let changes = startState.changes(change);
|
|
4155
4177
|
let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
|
|
4156
4178
|
// Try to apply a composition change to all cursors
|
|
4157
|
-
if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
|
|
4158
|
-
change.to <= sel.to && change.to >= sel.to - 10) {
|
|
4179
|
+
if (startState.selection.ranges.length > 1 && (view.inputState.composing >= 0 || view.inputState.compositionPendingChange) &&
|
|
4180
|
+
change.to <= sel.to + 10 && change.to >= sel.to - 10) {
|
|
4159
4181
|
let replaced = view.state.sliceDoc(change.from, change.to);
|
|
4160
4182
|
let compositionRange, composition = newSel && findCompositionNode(view, newSel.main.head);
|
|
4161
4183
|
if (composition) {
|
|
@@ -4165,17 +4187,17 @@ function applyDefaultInsert(view, change, newSel) {
|
|
|
4165
4187
|
else {
|
|
4166
4188
|
compositionRange = view.state.doc.lineAt(sel.head);
|
|
4167
4189
|
}
|
|
4168
|
-
let offset = sel.to - change.to
|
|
4190
|
+
let offset = sel.to - change.to;
|
|
4169
4191
|
tr = startState.changeByRange(range => {
|
|
4170
4192
|
if (range.from == sel.from && range.to == sel.to)
|
|
4171
4193
|
return { changes, range: mainSel || range.map(changes) };
|
|
4172
4194
|
let to = range.to - offset, from = to - replaced.length;
|
|
4173
|
-
if (
|
|
4195
|
+
if (view.state.sliceDoc(from, to) != replaced ||
|
|
4174
4196
|
// Unfortunately, there's no way to make multiple
|
|
4175
4197
|
// changes in the same node work without aborting
|
|
4176
4198
|
// composition, so cursors in the composition range are
|
|
4177
4199
|
// ignored.
|
|
4178
|
-
|
|
4200
|
+
to >= compositionRange.from && from <= compositionRange.to)
|
|
4179
4201
|
return { range };
|
|
4180
4202
|
let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to;
|
|
4181
4203
|
return {
|
|
@@ -4302,6 +4324,9 @@ class InputState {
|
|
|
4302
4324
|
// Used to categorize changes as part of a composition, even when
|
|
4303
4325
|
// the mutation events fire shortly after the compositionend event
|
|
4304
4326
|
this.compositionPendingChange = false;
|
|
4327
|
+
// Set by beforeinput, used in DOM change reader
|
|
4328
|
+
this.insertingText = "";
|
|
4329
|
+
this.insertingTextAt = 0;
|
|
4305
4330
|
this.mouseSelection = null;
|
|
4306
4331
|
// When a drag from the editor is active, this points at the range
|
|
4307
4332
|
// being dragged.
|
|
@@ -5056,6 +5081,10 @@ observers.contextmenu = view => {
|
|
|
5056
5081
|
};
|
|
5057
5082
|
handlers.beforeinput = (view, event) => {
|
|
5058
5083
|
var _a, _b;
|
|
5084
|
+
if (event.inputType == "insertText" || event.inputType == "insertCompositionText") {
|
|
5085
|
+
view.inputState.insertingText = event.data;
|
|
5086
|
+
view.inputState.insertingTextAt = Date.now();
|
|
5087
|
+
}
|
|
5059
5088
|
// In EditContext mode, we must handle insertReplacementText events
|
|
5060
5089
|
// directly, to make spell checking corrections work
|
|
5061
5090
|
if (event.inputType == "insertReplacementText" && view.observer.editContext) {
|
|
@@ -8562,7 +8591,7 @@ Facet that works much like
|
|
|
8562
8591
|
[`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its
|
|
8563
8592
|
inputs at the very bottom of the precedence stack, meaning mark
|
|
8564
8593
|
decorations provided here will only be split by other, partially
|
|
8565
|
-
overlapping
|
|
8594
|
+
overlapping `outerDecorations` ranges, and wrap around all
|
|
8566
8595
|
regular decorations. Use this for mark elements that should, as
|
|
8567
8596
|
much as possible, remain in one piece.
|
|
8568
8597
|
*/
|
|
@@ -10060,18 +10089,18 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
10060
10089
|
let scaleX = 1, scaleY = 1, makeAbsolute = false;
|
|
10061
10090
|
if (this.position == "fixed" && this.manager.tooltipViews.length) {
|
|
10062
10091
|
let { dom } = this.manager.tooltipViews[0];
|
|
10063
|
-
if (browser.
|
|
10064
|
-
//
|
|
10065
|
-
//
|
|
10066
|
-
//
|
|
10067
|
-
makeAbsolute = dom.offsetParent != this.container.ownerDocument.body;
|
|
10068
|
-
}
|
|
10069
|
-
else if (dom.style.top == Outside && dom.style.left == "0px") {
|
|
10070
|
-
// On other browsers, we have to awkwardly try and use other
|
|
10071
|
-
// information to detect a transform.
|
|
10092
|
+
if (browser.safari) {
|
|
10093
|
+
// Safari always sets offsetParent to null, even if a fixed
|
|
10094
|
+
// element is positioned relative to a transformed parent. So
|
|
10095
|
+
// we use this kludge to try and detect this.
|
|
10072
10096
|
let rect = dom.getBoundingClientRect();
|
|
10073
10097
|
makeAbsolute = Math.abs(rect.top + 10000) > 1 || Math.abs(rect.left) > 1;
|
|
10074
10098
|
}
|
|
10099
|
+
else {
|
|
10100
|
+
// More conforming browsers will set offsetParent to the
|
|
10101
|
+
// transformed element.
|
|
10102
|
+
makeAbsolute = !!dom.offsetParent && dom.offsetParent != this.container.ownerDocument.body;
|
|
10103
|
+
}
|
|
10075
10104
|
}
|
|
10076
10105
|
if (makeAbsolute || this.position == "absolute") {
|
|
10077
10106
|
if (this.parent) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1265,7 +1265,7 @@ declare class EditorView {
|
|
|
1265
1265
|
[`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its
|
|
1266
1266
|
inputs at the very bottom of the precedence stack, meaning mark
|
|
1267
1267
|
decorations provided here will only be split by other, partially
|
|
1268
|
-
overlapping
|
|
1268
|
+
overlapping `outerDecorations` ranges, and wrap around all
|
|
1269
1269
|
regular decorations. Use this for mark elements that should, as
|
|
1270
1270
|
much as possible, remain in one piece.
|
|
1271
1271
|
*/
|
|
@@ -2091,8 +2091,8 @@ declare const showPanel: Facet<PanelConstructor | null, readonly (PanelConstruct
|
|
|
2091
2091
|
type DialogConfig = {
|
|
2092
2092
|
/**
|
|
2093
2093
|
A function to render the content of the dialog. The result
|
|
2094
|
-
should contain at least one `<form>` element. Submit handlers
|
|
2095
|
-
handler for the Escape key will be added to the form.
|
|
2094
|
+
should contain at least one `<form>` element. Submit handlers
|
|
2095
|
+
and a handler for the Escape key will be added to the form.
|
|
2096
2096
|
|
|
2097
2097
|
If this is not given, the `label`, `input`, and `submitLabel`
|
|
2098
2098
|
fields will be used to create a simple form for you.
|
package/dist/index.d.ts
CHANGED
|
@@ -1265,7 +1265,7 @@ declare class EditorView {
|
|
|
1265
1265
|
[`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its
|
|
1266
1266
|
inputs at the very bottom of the precedence stack, meaning mark
|
|
1267
1267
|
decorations provided here will only be split by other, partially
|
|
1268
|
-
overlapping
|
|
1268
|
+
overlapping `outerDecorations` ranges, and wrap around all
|
|
1269
1269
|
regular decorations. Use this for mark elements that should, as
|
|
1270
1270
|
much as possible, remain in one piece.
|
|
1271
1271
|
*/
|
|
@@ -2091,8 +2091,8 @@ declare const showPanel: Facet<PanelConstructor | null, readonly (PanelConstruct
|
|
|
2091
2091
|
type DialogConfig = {
|
|
2092
2092
|
/**
|
|
2093
2093
|
A function to render the content of the dialog. The result
|
|
2094
|
-
should contain at least one `<form>` element. Submit handlers
|
|
2095
|
-
handler for the Escape key will be added to the form.
|
|
2094
|
+
should contain at least one `<form>` element. Submit handlers
|
|
2095
|
+
and a handler for the Escape key will be added to the form.
|
|
2096
2096
|
|
|
2097
2097
|
If this is not given, the `label`, `input`, and `submitLabel`
|
|
2098
2098
|
fields will be used to create a simple form for you.
|
package/dist/index.js
CHANGED
|
@@ -3320,6 +3320,13 @@ class DocView extends ContentView {
|
|
|
3320
3320
|
let { offsetWidth, offsetHeight } = this.view.scrollDOM;
|
|
3321
3321
|
scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, Math.max(Math.min(target.xMargin, offsetWidth), -offsetWidth), Math.max(Math.min(target.yMargin, offsetHeight), -offsetHeight), this.view.textDirection == Direction.LTR);
|
|
3322
3322
|
}
|
|
3323
|
+
lineHasWidget(pos) {
|
|
3324
|
+
let { i } = this.childCursor().findPos(pos);
|
|
3325
|
+
if (i == this.children.length)
|
|
3326
|
+
return false;
|
|
3327
|
+
let scan = (child) => child instanceof WidgetView || child.children.some(scan);
|
|
3328
|
+
return scan(this.children[i]);
|
|
3329
|
+
}
|
|
3323
3330
|
}
|
|
3324
3331
|
function betweenUneditable(pos) {
|
|
3325
3332
|
return pos.node.nodeType == 1 && pos.node.firstChild &&
|
|
@@ -3537,7 +3544,7 @@ function domPosInText(node, x, y) {
|
|
|
3537
3544
|
// Check for RTL on browsers that support getting client
|
|
3538
3545
|
// rects for empty ranges.
|
|
3539
3546
|
let rectBefore = textRange(node, i).getBoundingClientRect();
|
|
3540
|
-
if (rectBefore.left
|
|
3547
|
+
if (Math.abs(rectBefore.left - rect.right) < 0.1)
|
|
3541
3548
|
after = !right;
|
|
3542
3549
|
}
|
|
3543
3550
|
if (dy <= 0)
|
|
@@ -4009,7 +4016,10 @@ class DOMChange {
|
|
|
4009
4016
|
anchor = view.state.doc.length;
|
|
4010
4017
|
}
|
|
4011
4018
|
}
|
|
4012
|
-
|
|
4019
|
+
if (view.inputState.composing > -1 && view.state.selection.ranges.length > 1)
|
|
4020
|
+
this.newSel = view.state.selection.replaceRange(EditorSelection.range(anchor, head));
|
|
4021
|
+
else
|
|
4022
|
+
this.newSel = EditorSelection.single(anchor, head);
|
|
4013
4023
|
}
|
|
4014
4024
|
}
|
|
4015
4025
|
}
|
|
@@ -4065,6 +4075,18 @@ function applyDOMChange(view, domChange) {
|
|
|
4065
4075
|
insert: view.state.doc.slice(sel.from, change.from).append(change.insert).append(view.state.doc.slice(change.to, sel.to))
|
|
4066
4076
|
};
|
|
4067
4077
|
}
|
|
4078
|
+
else if (view.state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) &&
|
|
4079
|
+
view.inputState.insertingTextAt > Date.now() - 50) {
|
|
4080
|
+
// For a cross-line insertion, Chrome and Safari will crudely take
|
|
4081
|
+
// the text of the line after the selection, flattening any
|
|
4082
|
+
// widgets, and move it into the joined line. This tries to detect
|
|
4083
|
+
// such a situation, and replaces the change with a selection
|
|
4084
|
+
// replace of the text provided by the beforeinput event.
|
|
4085
|
+
change = {
|
|
4086
|
+
from: sel.from, to: sel.to,
|
|
4087
|
+
insert: view.state.toText(view.inputState.insertingText)
|
|
4088
|
+
};
|
|
4089
|
+
}
|
|
4068
4090
|
else if (browser.chrome && change && change.from == change.to && change.from == sel.head &&
|
|
4069
4091
|
change.insert.toString() == "\n " && view.lineWrapping) {
|
|
4070
4092
|
// In Chrome, if you insert a space at the start of a wrapped
|
|
@@ -4150,8 +4172,8 @@ function applyDefaultInsert(view, change, newSel) {
|
|
|
4150
4172
|
let changes = startState.changes(change);
|
|
4151
4173
|
let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
|
|
4152
4174
|
// Try to apply a composition change to all cursors
|
|
4153
|
-
if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
|
|
4154
|
-
change.to <= sel.to && change.to >= sel.to - 10) {
|
|
4175
|
+
if (startState.selection.ranges.length > 1 && (view.inputState.composing >= 0 || view.inputState.compositionPendingChange) &&
|
|
4176
|
+
change.to <= sel.to + 10 && change.to >= sel.to - 10) {
|
|
4155
4177
|
let replaced = view.state.sliceDoc(change.from, change.to);
|
|
4156
4178
|
let compositionRange, composition = newSel && findCompositionNode(view, newSel.main.head);
|
|
4157
4179
|
if (composition) {
|
|
@@ -4161,17 +4183,17 @@ function applyDefaultInsert(view, change, newSel) {
|
|
|
4161
4183
|
else {
|
|
4162
4184
|
compositionRange = view.state.doc.lineAt(sel.head);
|
|
4163
4185
|
}
|
|
4164
|
-
let offset = sel.to - change.to
|
|
4186
|
+
let offset = sel.to - change.to;
|
|
4165
4187
|
tr = startState.changeByRange(range => {
|
|
4166
4188
|
if (range.from == sel.from && range.to == sel.to)
|
|
4167
4189
|
return { changes, range: mainSel || range.map(changes) };
|
|
4168
4190
|
let to = range.to - offset, from = to - replaced.length;
|
|
4169
|
-
if (
|
|
4191
|
+
if (view.state.sliceDoc(from, to) != replaced ||
|
|
4170
4192
|
// Unfortunately, there's no way to make multiple
|
|
4171
4193
|
// changes in the same node work without aborting
|
|
4172
4194
|
// composition, so cursors in the composition range are
|
|
4173
4195
|
// ignored.
|
|
4174
|
-
|
|
4196
|
+
to >= compositionRange.from && from <= compositionRange.to)
|
|
4175
4197
|
return { range };
|
|
4176
4198
|
let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to;
|
|
4177
4199
|
return {
|
|
@@ -4298,6 +4320,9 @@ class InputState {
|
|
|
4298
4320
|
// Used to categorize changes as part of a composition, even when
|
|
4299
4321
|
// the mutation events fire shortly after the compositionend event
|
|
4300
4322
|
this.compositionPendingChange = false;
|
|
4323
|
+
// Set by beforeinput, used in DOM change reader
|
|
4324
|
+
this.insertingText = "";
|
|
4325
|
+
this.insertingTextAt = 0;
|
|
4301
4326
|
this.mouseSelection = null;
|
|
4302
4327
|
// When a drag from the editor is active, this points at the range
|
|
4303
4328
|
// being dragged.
|
|
@@ -5052,6 +5077,10 @@ observers.contextmenu = view => {
|
|
|
5052
5077
|
};
|
|
5053
5078
|
handlers.beforeinput = (view, event) => {
|
|
5054
5079
|
var _a, _b;
|
|
5080
|
+
if (event.inputType == "insertText" || event.inputType == "insertCompositionText") {
|
|
5081
|
+
view.inputState.insertingText = event.data;
|
|
5082
|
+
view.inputState.insertingTextAt = Date.now();
|
|
5083
|
+
}
|
|
5055
5084
|
// In EditContext mode, we must handle insertReplacementText events
|
|
5056
5085
|
// directly, to make spell checking corrections work
|
|
5057
5086
|
if (event.inputType == "insertReplacementText" && view.observer.editContext) {
|
|
@@ -8557,7 +8586,7 @@ Facet that works much like
|
|
|
8557
8586
|
[`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its
|
|
8558
8587
|
inputs at the very bottom of the precedence stack, meaning mark
|
|
8559
8588
|
decorations provided here will only be split by other, partially
|
|
8560
|
-
overlapping
|
|
8589
|
+
overlapping `outerDecorations` ranges, and wrap around all
|
|
8561
8590
|
regular decorations. Use this for mark elements that should, as
|
|
8562
8591
|
much as possible, remain in one piece.
|
|
8563
8592
|
*/
|
|
@@ -10055,18 +10084,18 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
10055
10084
|
let scaleX = 1, scaleY = 1, makeAbsolute = false;
|
|
10056
10085
|
if (this.position == "fixed" && this.manager.tooltipViews.length) {
|
|
10057
10086
|
let { dom } = this.manager.tooltipViews[0];
|
|
10058
|
-
if (browser.
|
|
10059
|
-
//
|
|
10060
|
-
//
|
|
10061
|
-
//
|
|
10062
|
-
makeAbsolute = dom.offsetParent != this.container.ownerDocument.body;
|
|
10063
|
-
}
|
|
10064
|
-
else if (dom.style.top == Outside && dom.style.left == "0px") {
|
|
10065
|
-
// On other browsers, we have to awkwardly try and use other
|
|
10066
|
-
// information to detect a transform.
|
|
10087
|
+
if (browser.safari) {
|
|
10088
|
+
// Safari always sets offsetParent to null, even if a fixed
|
|
10089
|
+
// element is positioned relative to a transformed parent. So
|
|
10090
|
+
// we use this kludge to try and detect this.
|
|
10067
10091
|
let rect = dom.getBoundingClientRect();
|
|
10068
10092
|
makeAbsolute = Math.abs(rect.top + 10000) > 1 || Math.abs(rect.left) > 1;
|
|
10069
10093
|
}
|
|
10094
|
+
else {
|
|
10095
|
+
// More conforming browsers will set offsetParent to the
|
|
10096
|
+
// transformed element.
|
|
10097
|
+
makeAbsolute = !!dom.offsetParent && dom.offsetParent != this.container.ownerDocument.body;
|
|
10098
|
+
}
|
|
10070
10099
|
}
|
|
10071
10100
|
if (makeAbsolute || this.position == "absolute") {
|
|
10072
10101
|
if (this.parent) {
|