Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions src/scripts/modules/BaseFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ const BaseFormatter = Module({
methods: {
init () {
const { mediator } = this;

validTags = mediator.get('config:toolbar:validTags');
blockTags = mediator.get('config:toolbar:blockTags');
listTags = mediator.get('config:toolbar:listTags');
listTags = mediator.get('config:toolbar:listTags');
},

/**
Expand Down Expand Up @@ -106,6 +107,7 @@ const BaseFormatter = Module({
formatDefault () {
const { mediator } = this;
const rootElem = mediator.get('selection:rootelement');

mediator.exec('commands:format:default');
this.removeStyledSpans(rootElem);
},
Expand All @@ -122,22 +124,19 @@ const BaseFormatter = Module({
this.ensureRootElems(rootElem);
this.removeStyleAttributes(rootElem);
this.removeEmptyNodes(rootElem, { recursive: true });

// -----

// this.removeBrNodes(rootElem);
// // this.removeEmptyNodes(rootElem);
// this.removeFontTags(rootElem);
// this.removeStyledSpans(rootElem);
// this.clearEntities(rootElem);
// this.removeZeroWidthSpaces(rootElem);
// this.defaultOrphanedTextNodes(rootElem);
// this.removeEmptyNodes(rootElem, { recursive: true });
},

/**
* PRIVATE METHODS:
*/
cloneNodes (rootElement) {
let clonedNodes = [];
rootElement.childNodes.forEach((node) => {
clonedNodes.push(node.cloneNode(true));
});
return clonedNodes;
},

injectHooks (rootElement) {
while (!/\w+/.test(rootElement.firstChild.textContent)) {
DOM.removeNode(rootElement.firstChild);
Expand Down Expand Up @@ -306,7 +305,6 @@ const BaseFormatter = Module({

defaultOrphanedTextNodes (rootElem) {
const { childNodes } = rootElem;

for (let i = 0; i < childNodes.length; i++) {
let childNode = childNodes[i];
if (childNode.nodeType === Node.TEXT_NODE && /\w+/.test(childNode.textContent)) {
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/modules/BlockFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const BlockFormatter = Module({
},

cleanupBlockquote (rootElem) {
const blockquoteParagraphs = rootElem.querySelectorAll('BLOCKQUOTE P');
const blockquoteParagraphs = rootElem.querySelectorAll('blockquote p');
blockquoteParagraphs.forEach((paragraph) => {
DOM.unwrap(paragraph);
});
Expand Down
1 change: 0 additions & 1 deletion src/scripts/modules/ContentEditable.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ const ContentEditable = Module({
} else {
let currentSelection = mediator.get('selection:current');
let currentRange = mediator.get('selection:range');

currentRange.deleteContents();

let tmpContainer = document.createElement('container');
Expand Down
140 changes: 5 additions & 135 deletions src/scripts/modules/ListFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,11 @@ const ListFormatter = Module({
process (opts) {
const { mediator } = this;
const canvasDoc = mediator.get('canvas:document');
let toggle = false;

mediator.exec('canvas:cache:selection');

switch (opts.style) {
case 'ordered':
toggle = mediator.get('selection:in:or:contains', ['OL']);
if (mediator.get('selection:in:or:contains', ['UL'])) {
mediator.exec('commands:exec', {
command: 'insertUnorderedList',
Expand All @@ -63,8 +62,8 @@ const ListFormatter = Module({
contextDocument: canvasDoc
});
break;

case 'unordered':
toggle = mediator.get('selection:in:or:contains', ['UL']);
if (mediator.get('selection:in:or:contains', ['OL'])) {
mediator.exec('commands:exec', {
command: 'insertOrderedList',
Expand All @@ -76,12 +75,14 @@ const ListFormatter = Module({
contextDocument: canvasDoc
});
break;

case 'outdent':
mediator.exec('commands:exec', {
command: 'outdent',
contextDocument: canvasDoc
});
break;

case 'indent':
mediator.exec('commands:exec', {
command: 'indent',
Expand All @@ -90,14 +91,7 @@ const ListFormatter = Module({
break;
}

if (toggle) {
// mediator.exec('canvas:select:cachedSelection');
this.postProcessToggle(opts);
} else {
mediator.exec('canvas:select:ensure:offsets');
}

// mediator.exec('canvas:select:cachedSelection');
mediator.exec('canvas:select:ensure:offsets');
},

commit () {
Expand Down Expand Up @@ -132,130 +126,6 @@ const ListFormatter = Module({
}
},

prepListItemsForToggle () {
const { mediator } = this;

const canvasDoc = mediator.get('canvas:document');
const canvasBody = mediator.get('canvas:body');

const {
anchorNode,
focusNode,
} = mediator.get('canvas:selection');

const anchorLiNode = DOM.getClosest(anchorNode, 'LI', canvasBody);
const focusLiNode = DOM.getClosest(focusNode, 'LI', canvasBody);

mediator.exec('canvas:cache:selection');

let selectedLiNodes = [anchorLiNode];
let nextLiNode = anchorLiNode.nextSibling;
while (nextLiNode && nextLiNode !== focusLiNode) {
selectedLiNodes.push(nextLiNode);
nextLiNode = nextLiNode.nextSibling;
}
selectedLiNodes.push(focusLiNode);

selectedLiNodes.forEach((selectedLiNode) => {
let contentWrapper = canvasDoc.createElement('span');
selectedLiNode.appendChild(contentWrapper);
while (selectedLiNode.firstChild !== contentWrapper) {
contentWrapper.appendChild(selectedLiNode.firstChild);
}
});

mediator.exec('canvas:select:cachedSelection');

return;
// const canvasBody = mediator.get('canvas:body');
// const canvasDoc = mediator.get('canvas:document');
//
// let rootBlock = anchorNode;
// while(rootBlock.parentNode !== canvasBody) {
// rootBlock = rootBlock.parentNode;
// }
//
// const liNodes = rootBlock.querySelectorAll('li');
// liNodes.forEach((liNode) => {
// let pNode = canvasDoc.createElement('span');
// liNode.appendChild(pNode);
// while (liNode.firstChild !== pNode) {
// pNode.appendChild(liNode.firstChild);
// }
// });
},

postProcessToggle () {
const { mediator } = this;
// return;

const canvasDoc = mediator.get('canvas:document');
const canvasBody = mediator.get('canvas:body');

mediator.exec('canvas:cache:selection');

const {
anchorNode,
focusNode
} = mediator.get('canvas:selection');

const walkToRoot = function (node) {
let rootNode = node;
while ( rootNode.parentNode !== canvasBody ) {
rootNode = rootNode.parentNode;
}
return rootNode;
};

const anchorRootNode = walkToRoot(anchorNode);
const focusRootNode = walkToRoot(focusNode);

let currentNode = anchorRootNode;
let currentParagraph;

const createParagraph = function () {
currentParagraph = canvasDoc.createElement('p');
DOM.insertBefore(currentParagraph, currentNode);
};

const handleBrNode = function (brNode) {
createParagraph();
currentNode = brNode.nextSibling;
DOM.removeNode(brNode);
};

const handleDivNode = function (divNode) {
createParagraph();
currentNode = divNode.nextSibling;
while (divNode.firstChild) {
currentParagraph.appendChild(divNode.firstChild);
}
DOM.removeNode(divNode);
};

createParagraph();

while (currentNode !== focusRootNode) {
if (currentNode.nodeName === 'BR') {
handleBrNode(currentNode);
} else if (currentNode.nodeName === 'DIV') {
handleDivNode(currentNode);
} else {
let orphanedNode = currentNode;
currentNode = currentNode.nextSibling;
currentParagraph.appendChild(orphanedNode);
}
}

if (focusRootNode.nodeName === 'DIV') {
handleDivNode(focusRootNode);
} else {
currentParagraph.appendChild(focusRootNode);
}

mediator.exec('canvas:select:cachedSelection');
},

cleanupListDOM (rootElem) {
const listContainers = rootElem.querySelectorAll('OL, UL');

Expand Down
47 changes: 41 additions & 6 deletions src/scripts/modules/Selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ const Selection = Module({

getAnchorNode () {
const currentSelection = this.getCurrentSelection();
return currentSelection.anchorNode;
return currentSelection && currentSelection.anchorNode;
},

getCommonAncestor () {
Expand Down Expand Up @@ -293,14 +293,49 @@ const Selection = Module({
endContainer,
endOffset
} = this.getCurrentRange();

let startCoordinates = [];
let endCoordinates = [];
let startPrefixTrimLength = 0;
let endPrefixTrimLength = 0;
let endSuffixTrimLength = 0;

const startTrimmablePrefix = startContainer.textContent.match(/^(\r?\n|\r)?(\s+)?/);
const endTrimmablePrefix = endContainer.textContent.match(/^(\r?\n|\r)?(\s+)?/);
const endTrimmableSuffix = endContainer.textContent.match(/(\r?\n|\r)?(\s+)?$/);
const startTrimmableSides = DOM.trimmableSides(startContainer.firstChild ? startContainer.firstChild : startContainer);
const endTrimmableSides = DOM.trimmableSides(endContainer.lastChild ? endContainer.lastChild : endContainer);

if (startTrimmablePrefix && startTrimmablePrefix[0].length) {
startPrefixTrimLength += startTrimmablePrefix[0].length;
if (!startTrimmableSides.left) {
startPrefixTrimLength -= startTrimmablePrefix[0].match(/\s/) ? 1 : 0;
}
startOffset -= startPrefixTrimLength;
if (endContainer === startContainer) {
endOffset -= startPrefixTrimLength;
}
}

if (endTrimmablePrefix && endTrimmablePrefix[0].length && endContainer !== startContainer) {
endPrefixTrimLength += endTrimmablePrefix[0].length;
if (!endTrimmableSides.left) {
endPrefixTrimLength -= endTrimmablePrefix[0].match(/\s/) ? 1 : 0;
}
endOffset -= endPrefixTrimLength;
}

if (endTrimmableSuffix && endTrimmableSuffix[0].length) {
endSuffixTrimLength += endTrimmableSuffix[0].length;
if (!endTrimmableSides.right) {
endSuffixTrimLength -= endTrimmableSuffix[0].match(/\s/) ? 1 : 0;
}
let trimmedTextLength = endContainer.textContent.length - endPrefixTrimLength - endSuffixTrimLength;
endOffset = Math.min(trimmedTextLength, endOffset);
}

startOffset -= startTrimmablePrefix ? startTrimmablePrefix[0].length : 0;
endOffset -= endTrimmablePrefix ? endTrimmablePrefix[0].length : 0;
startOffset = Math.max(0, startOffset);
endOffset = Math.min(endContainer.textContent.length, endOffset);

startCoordinates.unshift(startOffset);
endCoordinates.unshift(endOffset);
Expand Down Expand Up @@ -331,7 +366,6 @@ const Selection = Module({
}

const isIn = DOM.isIn(anchorNode, selectors, rootEl);

if (isIn) {
return isIn;
}
Expand All @@ -341,8 +375,8 @@ const Selection = Module({
let contains = false;

if (rangeFrag.childNodes.length) {
selectors.forEach(selector => {
contains = contains || rangeFrag.childNodes[0].nodeName === selector;
rangeFrag.childNodes.forEach(childNode => {
contains = contains || selectors.indexOf(childNode.nodeName) > -1;
});
}

Expand All @@ -365,6 +399,7 @@ const Selection = Module({
if (anchorNode.nodeType !== Node.ELEMENT_NODE) {
anchorNode = anchorNode.parentNode;
}

if (focusNode.nodeType !== Node.ELEMENT_NODE) {
focusNode = focusNode.parentNode;
}
Expand Down
Loading