Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX Allow wrapping an image in a link #1579

Merged
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
2 changes: 1 addition & 1 deletion client/dist/js/TinyMCE_sslink-email.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/dist/js/TinyMCE_sslink-external.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/dist/js/TinyMCE_sslink.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions client/src/legacy/TinyMCE_sslink-email.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@ jQuery.entwine('ss', ($) => {
const handleHide = () => this.close();
const handleInsert = (...args) => this.handleInsert(...args);
const attrs = this.getOriginalAttributes();
const editor = this.getElement().getEditor();
const selection = editor.getInstance().selection;
const selectionContent = editor.getSelection();
const tagName = selection.getNode().tagName;
const requireLinkText = tagName !== 'A' && selectionContent.trim() === '';
const requireLinkText = this.getRequireLinkText();

// create/update the react component
let root = this.getReactRoot();
Expand Down
6 changes: 1 addition & 5 deletions client/src/legacy/TinyMCE_sslink-external.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ jQuery.entwine('ss', ($) => {
const handleHide = () => this.close();
const handleInsert = (...args) => this.handleInsert(...args);
const attrs = this.getOriginalAttributes();
const editor = this.getElement().getEditor();
const selection = editor.getInstance().selection;
const selectionContent = editor.getSelection();
const tagName = selection.getNode().tagName;
const requireLinkText = tagName !== 'A' && selectionContent.trim() === '';
const requireLinkText = this.getRequireLinkText();

// create/update the react component
let root = this.getReactRoot();
Expand Down
64 changes: 63 additions & 1 deletion client/src/legacy/TinyMCE_sslink.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,69 @@ jQuery.entwine('ss', ($) => {
/* noop */
},

/**
/**
* Check if one node is the same as another node (or is the same as that other node's child)
*/
checkNodeMatches(node, matchWith) {
if (node === matchWith) {
return true;
}
if (matchWith.children.length === 1) {
// In chrome, selecting an image actually results in selecting the paragraph.
// If there's exactly one child, treat that child as the selection to account for this scenario.
return node === matchWith.children[0];
}
return false;
},

/**
* @param selection The current tinyMCE selection for this WYSIWYG
* @return {Boolean}
*/
linkCanWrapSelection(editor, selection) {
const selectionContent = editor.getSelection() || '';
const node = selection.getNode();

// If there is direct selected content other than whitespace, we can wrap it.
if (selectionContent) {
return selectionContent.trim() !== '';
}

// If the selected node type can contain text, and we didn't find selected text above,
// then you haven't got a selection we can wrap in a link.
const x = document.createElement(node.nodeName);
x.textContent = 'Check the outer HTML';
if (x.outerHTML.includes('Check the outer HTML')) {
return false;
}

// Check if there is a single selected node which can be wrapped in a link.
if (this.checkNodeMatches(node, selection.getSel().focusNode) && this.checkNodeMatches(node, selection.getSel().anchorNode)) {
const parsed = tinymce.activeEditor.dom.createFragment(`<a>${node.outerHTML}</a>`);
if (parsed.childNodes.length === 1) {
return true;
}
}

return false;
},

/**
* Determine whether to show the link text field
*
* @return {Boolean}
*/
getRequireLinkText() {
const editor = this.getElement().getEditor();
const selection = editor.getInstance().selection;
const isValidSelection = this.linkCanWrapSelection(editor, selection);
const tagName = selection.getNode().tagName;
const requireLinkText = tagName !== 'A' && !isValidSelection;

return requireLinkText;
},

/**
* Default behaviour, recommended to overload this and sanitise where needed
*
* @param data
Expand Down