Skip to content

Commit

Permalink
[WIP]Should type in contenteditable div even if it has invisible chil…
Browse files Browse the repository at this point in the history
…d with contenteditable=false (closes DevExpress#2205)
  • Loading branch information
AlexKamaev committed Mar 27, 2018
1 parent 688d723 commit 5fe7023
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 18 deletions.
10 changes: 8 additions & 2 deletions src/client/core/utils/content-editable.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as domUtils from './dom';
import * as arrayUtils from './array';
import * as styleUtils from './style';


//nodes utils
Expand Down Expand Up @@ -397,13 +398,18 @@ export function calculateNodeAndOffsetByPosition (el, offset) {
}
}
else if (domUtils.isElementNode(target)) {
if (point.offset === 0 && !getContentEditableValue(target).length) {
if (!styleUtils.isElementVisible(target))
return point;

const isBreakElement = !childNodesLength && domUtils.getTagName(target) === 'br';

if (!isBreakElement && point.offset === 0 && !getContentEditableValue(target).length) {
point.node = target;
return point;
}
if (!point.node && (isNodeBlockWithBreakLine(el, target) || isNodeAfterNodeBlockWithBreakLine(el, target)))
point.offset--;
else if (!childNodesLength && domUtils.isElementNode(target) && domUtils.getTagName(target) === 'br')
else if (isBreakElement)
point.offset--;
}

Expand Down
17 changes: 1 addition & 16 deletions src/client/core/utils/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export var getElementPadding = hammerhead.utils.style.getElementPadding;
export var getElementScroll = hammerhead.utils.style.getElementScroll;
export var getOptionHeight = hammerhead.utils.style.getOptionHeight;
export var getSelectElementSize = hammerhead.utils.style.getSelectElementSize;
export var isElementVisible = hammerhead.utils.style.isElementVisible;
export var isSelectVisibleChild = hammerhead.utils.style.isVisibleChild;
export var getWidth = hammerhead.utils.style.getWidth;
export var getHeight = hammerhead.utils.style.getHeight;
Expand Down Expand Up @@ -135,22 +136,6 @@ export function hasDimensions (el) {
return el && !(el.offsetHeight <= 0 && el.offsetWidth <= 0);
}

export function isElementHidden (el) {
//NOTE: it's like jquery ':hidden' selector
if (get(el, 'display') === 'none' || !hasDimensions(el) || el.type && el.type === 'hidden')
return true;

var elements = domUtils.findDocument(el).querySelectorAll('*');
var hiddenElements = [];

for (var i = 0; i < elements.length; i++) {
if (get(elements[i], 'display') === 'none' || !hasDimensions(elements[i]))
hiddenElements.push(elements[i]);
}

return domUtils.containsElement(hiddenElements, el);
}

export function set (el, style, value) {
if (typeof style === 'string')
styleUtils.set(el, style, value);
Expand Down
92 changes: 92 additions & 0 deletions test/functional/fixtures/regression/gh-2205/pages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#editor1.focused .placeholder {
display: none;
}

#editor2.focused .placeholder {
visibility: hidden;
}

.placeholder {
color: #aaa;
font-style: italic;
height: 0;
pointer-events: none;
}

.editor {
padding: 4px 8px 4px 14px;
line-height: 1.2;
outline: none;
}

.editor {
word-wrap: break-word;
white-space: pre-wrap;
font-variant-ligatures: none;
}

.editor {
position: relative;
}

.outer-editor {
background: white;
color: black;
background-clip: padding-box;
border-radius: 4px;
border: 2px solid rgba(0, 0, 0, 0.2);
padding: 5px 0;
margin-bottom: 23px;
}

.outer-editor {
border: 1px solid grey;
}

.editor p:first-child {
margin-top: 10px;
}

.editor p {
margin-bottom: 1em;
}
</style>
</head>
<body>

<h2>Display: none</h2>
<div class="outer-editor">
<div id="editor1" contenteditable="true" class="editor"
onmousedown="event.currentTarget.className += ' focused'"></div>
</div>

<h2>Visibility: hidden</h2>
<div class="outer-editor">
<div id="editor2" contenteditable="true" class="editor"
onmousedown="event.currentTarget.className += ' focused'"></div>
</div>

<div id="placeholder1" contenteditable="false" class="placeholder">Type here...</div>
<div id="placeholder2" contenteditable="false" class="placeholder">Type here...</div>

<script type="text/javascript">
function createEditor (editor, placeholder) {
var paragraph = document.createElement('p');
var lineBreak = document.createElement('br');

editor.appendChild(paragraph);
paragraph.appendChild(placeholder);
paragraph.appendChild(lineBreak);
}

createEditor(document.getElementById('editor1'), document.getElementById('placeholder1'));
createEditor(document.getElementById('editor2'), document.getElementById('placeholder2'));
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions test/functional/fixtures/regression/gh-2205/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe('[Regression](GH-2205)', function () {
it('Should type in div if it has an invisible child with contententeditable=false', function () {
return runTests('testcafe-fixtures/index.js');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Selector } from 'testcafe';

fixture `GH-2205 - Should type in div if it has an invisible child with contententeditable=false`
.page `http://localhost:3000/fixtures/regression/gh-2205/pages/index.html`;

async function typeAndCheck (t, editorId) {
const editor = Selector(editorId);

await t
.click(editor)
.typeText(editor, 'H')
.expect(editor.innerText).contains('H');
}

test(`Click on div with display:none placeholder`, async t => {
await typeAndCheck(t, '#editor1');
});

test(`Click on div with visibility:hidden placeholder`, async t => {
await typeAndCheck(t, '#editor2');
});


0 comments on commit 5fe7023

Please sign in to comment.