Skip to content

Instantly share code, notes, and snippets.

@studds
Created December 15, 2016 00:49
Show Gist options
  • Save studds/0f10886d90f84e061280084d70ffde8a to your computer and use it in GitHub Desktop.
Save studds/0f10886d90f84e061280084d70ffde8a to your computer and use it in GitHub Desktop.
Fixes / standardises behaviour for execCommand & queryCommandValue for msedge
/**
* Created by daniel on 22/11/16.
*/
import bowser = require('bowser');
export function fixQueryCommandValueForMSEdge(): void {
if (!bowser.msedge && !bowser.msie) {
return;
}
console.debug('Fixing queryCommandValue for msedge');
const originalQueryCommandValue = document.queryCommandValue;
document.queryCommandValue = function (commandId: string): string {
let result = originalQueryCommandValue.call(document, commandId);
if (commandId.toLowerCase() === 'formatblock') {
// MS Edge returns "Heading 1" instead of "h1" and "Paragraph" instead of "p" - map the result
result = result
.split(' ')
.map((s: string): string => {
return s[0].toLowerCase();
})
.join('');
}
return result;
};
}
/**
* Created by daniel on 21/11/16.
*/
import bowser = require('bowser');
// shim for firing the input event after execCommand is called on msedge
// issue raised with MS: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9886636/
export function shimInputEventAfterExecCommandMSEdge(): void {
if (!bowser.msedge && !bowser.msie) {
return;
}
console.debug('Adding MS Edge shim for firing input event after execCommand is called');
const originalExecCommand = document.execCommand;
function dispatchEvent(element: HTMLElement, result: boolean): boolean {
if (result) {
const event = document.createEvent('Event');
event.initEvent('input', true, false);
element.dispatchEvent(event);
}
return result;
}
function isEditable(node: Node): node is HTMLElement {
return node.nodeType === 1 && node instanceof HTMLElement && node.hasAttribute('contenteditable');
}
function getEditable(initialNode: Node): HTMLElement | undefined {
let node = initialNode;
while (node && !isEditable(node)) {
node = node.parentNode;
}
return node;
}
function execCommand(commandId: string, showUI: boolean, value: any): boolean {
return originalExecCommand.call(document, commandId, showUI, value);
}
function shimExec(editable: HTMLElement, commandId: string, showUI: boolean, value: any) {
return dispatchEvent(editable, execCommand(commandId, showUI, value));
}
document.execCommand = function (commandId: string, showUI: boolean, value: any): boolean {
const selection = document.getSelection();
const editable = getEditable(selection.anchorNode);
return (editable && editable.isContentEditable)
? shimExec(editable, commandId, showUI, value)
: execCommand(commandId, showUI, value);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment