UNPKG

@instructure/canvas-rce

Version:

A component wrapping Canvas's usage of Tinymce

359 lines (357 loc) 18.3 kB
/* * Copyright (C) 2021 - present Instructure, Inc. * * This file is part of Canvas. * * Canvas is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, version 3 of the License. * * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ function elemsToTinyStringConfig(list) { return Object.entries(list).map(pair => { const [tag, attrs] = pair; if (attrs.length === 0) { return tag; } else { const attrStr = attrs.map(attr => { if (typeof attr === 'string') { return attr; } else if (typeof attr === 'object') { return Object.entries(attr).map(([key, value]) => `${key}=${value}`); } }).join('|'); return `${tag}[${attrStr}]`; } }).join(); } const defaultTinymceConfig = { // ============================================================================ // Values in this section have acceptable defaults which you may want // to override (though you really should provide content_css) // ============================================================================ auto_focus: false, // any values provided (in an array) will be merged into the standard then sorted // you provide the translations block_formats: undefined, // replace to provide your own body_class: 'default-theme', // urls to branding css go here content_css: [], // these are up to you directionality: 'ltr', height: undefined, // '400px' is s the standard height language: 'en', // any menubar entries here will be appended to the standard menubar menubar: undefined, // any menus here will be merged into the standard menubar menus menu: undefined, // any toolbar data here will be merged into the standard toolbars toolbar: undefined, color_map: [ // First row // tiny mce's default first row colors '#BFEDD2', 'Light Green', '#FBEEB8', 'Light Orange', '#F8CAC6', 'Light Red', '#ECCAFA', 'Light Purple', '#C2E0F4', 'Light Blue', // Second row '#03893D', // InstUI Green45 'Green', '#CF4A00', // InstUI Orange45 'Orange', '#E62429', // InstUI Red45 'Red', '#9E58BD', // InstUI Violet45 'Purple', '#2B7ABC', // InstUI Blue45 'Blue', // Third row '#027634', // InstUI Green57 'Dark Green', '#B34000', // InstUI Orange57 'Dark Orange', '#C71F23', // InstUI Red57 'Dark Red', '#9242B4', // InstUI Violet57 'Dark Purple', '#0E68B3', // InstUI Blue57 'Dark Blue', // Fourth row '#FFFFFF', 'White', '#6A7883', // InstUI Grey45 'Light Gray', '#3F515E', // InstUI Grey82 'Gray', '#273540', // InstUI Grey125 'Dark Gray', '#000000', 'Black'], // plugins included here will be added to the standard set plugins: undefined, // ================================================================================== // values below this line define standard behavior and probably shouldn't be changed // but will be used if you do // ================================================================================== branding: false, browser_spellcheck: true, content_style: '', convert_urls: false, // fonts specified here need to either be web-safe or self-hosted and loaded in app/stylesheets/bundles/fonts.scss font_formats: "Lato Extended=Lato Extended,Helvetica Neue,Helvetica,Arial,sans-serif; Balsamiq Sans=Balsamiq Sans,Lato Extended,Helvetica Neue,Helvetica,Arial,sans-serif; Architect's Daughter=Architects Daughter,Lato Extended,Helvetica Neue,Helvetica,Arial,sans-serif; Arial=arial,helvetica,sans-serif; Arial Black=arial black,avant garde; Courier New=courier new,courier; Georgia=georgia,palatino; Tahoma=tahoma,arial,helvetica,sans-serif; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Open Dyslexic=OpenDyslexic; Open Dyslexic Mono=OpenDyslexicMono, Monaco, Menlo, Consolas, Courier New, monospace;", language_load: false, language_url: 'none', toolbar_mode: 'floating', mobile: { theme: 'silver' }, preview_styles: 'font-family font-size font-weight font-style text-decoration text-transform border border-radius outline text-shadow', remove_script_host: true, resize: true, // will get set from textareaId // selector: '#textarea2', skin: false, statusbar: false, // part of unifying tinymce and canvas_sanitize's element whitelist // copied from // https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@valid_elements/#defaultruleset // then edited. // // this list needs to be kept in sync with the list in gems/canvas_sanitize/lib/canvas_sanitize/canvas_sanitize.rb valid_elements: elemsToTinyStringConfig({ '@': ['id', 'class', 'style', 'title', 'dir<ltr?rtl', 'lang', 'xml::lang', 'role'], a: ['rel', 'rev', 'charset', 'hreflang', 'tabindex', 'accesskey', 'type', 'name', 'href', 'target', 'title', 'class', 'data-old-link'], 'strong/b': [], 'em/i': [], 'strike/s': [], u: [], '#p': [], '-ol': ['type', 'compact'], '-ul': ['type', 'compact'], '-li': [], br: [], img: ['longdesc', 'usemap', 'src', 'border', 'alt', 'title', 'hspace', 'vspace', 'width', 'height', 'align', 'role', 'data-old-link'], '-sub': [], '-sup': [], '-blockquote': ['cite'], '-table': [{ border: '0' }, 'cellspacing', 'cellpadding', 'width', 'frame', 'rules', 'height', 'align', 'summary', 'bgcolor', 'background', 'bordercolor'], '-tr': ['rowspan', 'width', 'height', 'align', 'valign', 'bgcolor', 'background', 'bordercolor'], tbody: [], thead: [], tfoot: [], '#td': ['colspan', 'rowspan', 'width', 'height', 'align', 'valign', 'bgcolor', 'background', 'bordercolor', 'scope'], '#th': ['colspan', 'rowspan', 'width', 'height', 'align', 'valign', 'scope'], caption: [], '-div': [], '-span': [], '-code': [], '-pre': [], address: [], '-h1': [], '-h2': [], '-h3': [], '-h4': [], '-h5': [], '-h6': [], hr: ['size', 'noshade'], '-font': ['face', 'size', 'color'], dd: [], dl: [], dt: [], cite: [], abbr: [], acronym: [], del: ['datetime', 'cite'], ins: ['datetime', 'cite'], object: ['classid', 'width', 'height', 'codebase', '*'], param: ['name', 'value', '_value'], embed: ['type', 'width', 'height', 'src', '*'], map: ['name'], area: ['shape', 'coords', 'href', 'alt', 'target'], bdo: [], col: ['align', 'char', 'charoff', 'span', 'valign', 'width'], colgroup: ['align', 'char', 'charoff', 'span', 'valign', 'width'], dfn: [], kbd: [], q: ['cite'], samp: [], small: [], tt: [], var: [], big: [], figure: [], figcaption: [], source: ['media', 'width', 'height', 'sizes', 'src', 'srcset', 'type', 'data-old-link'], track: [], mark: [], article: [], aside: [], details: [], footer: [], header: [], nav: [], section: [], summary: [], time: [] }), extended_valid_elements: elemsToTinyStringConfig({ '@': ['id', 'accesskey', 'class', 'dir', 'lang', 'style', 'tabindex', 'title', 'contenteditable', 'contextmenu', 'draggable', 'dropzone', 'hidden', 'longdesc', 'spellcheck', 'translate', 'align', 'role', 'aria-labelledby', 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-describedby', 'aria-description', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant', 'aria-autocomplete', 'aria-checked', 'aria-disabled', 'aria-expanded', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-label', 'aria-level', 'aria-multiline', 'aria-multiselectable', 'aria-orientation', 'aria-pressed', 'aria-readonly', 'aria-required', 'aria-selected', 'aria-sort', 'aria-valuemax', 'aria-valuemin', 'aria-valuenow', 'aria-valuetext'], iframe: ['id', 'data-media-type', 'title', 'src', 'width', 'height', 'name', 'align', 'style', 'class', 'sandbox', 'loading', 'allowfullscreen', 'webkitallowfullscreen', 'mozallowfullscreen', 'allow', 'data-old-link'], i: ['iclass'], a: ['hidden', 'href', 'target', 'rel', 'media', 'hreflang', 'type', 'charset', 'name', 'rev', 'shape', 'coords', 'download', 'alt'], '#p': [], li: ['value'], '-ol': ['reversed', 'start', 'type', 'compact'], pre: ['width'], table: ['border', 'summary', 'width', 'frame', 'rules', 'cellspacing', 'cellpadding', 'bgcolor'], tbody: ['char', 'charoff', 'valign'], td: ['colspan', 'rowspan', 'headers', 'abbr', 'axis', 'scope', 'align', 'char', 'charoff', 'valign', 'nowrap', 'bgcolor', 'width', 'height'], tfoot: ['char', 'charoff', 'valign'], th: ['colspan', 'rowspan', 'headers', 'scope', 'abbr', 'axis', 'align', 'char', 'charoff', 'valign', 'nowrap', 'bgcolor', 'width', 'height'], thead: ['char', 'charoff', 'valign'], tr: ['char', 'charoff', 'valign', 'bgcolor'], '-ul': ['compact'], video: ['name', 'src', 'allowfullscreen', 'muted', 'poster', 'width', 'height', 'controls', 'playsinline'], audio: ['name', 'src', 'muted', 'controls'], annotation: ['href', 'xref', 'definitionURL', 'encoding', 'cd', 'name', 'src'], 'annotation-xml': ['href', 'xref', 'definitionURL', 'encoding', 'cd', 'name', 'src'], maction: ['href', 'xref', 'mathcolor', 'mathbackground', 'actiontype', 'selection'], maligngroup: ['href', 'xref', 'mathcolor', 'mathbackground', 'groupalign'], malignmark: ['href', 'xref', 'mathcolor', 'mathbackground', 'edge'], math: ['xmlns', 'href', 'xref', 'display', 'maxwidth', 'overflow', 'altimg', 'altimg-width', 'altimg-height', 'altimg-valign', 'alttext', 'cdgroup', 'mathcolor', 'mathbackground', 'scriptlevel', 'displaystyle', 'scriptsizemultiplier', 'scriptminsize', 'infixlinebreakstyle', 'decimalpoint', 'mathvariant', 'mathsize', 'width', 'height', 'valign', 'form', 'fence', 'separator', 'lspace', 'rspace', 'stretchy', 'symmetric', 'maxsize', 'minsize', 'largeop', 'movablelimits', 'accent', 'linebreak', 'lineleading', 'linebreakstyle', 'linebreakmultchar', 'indentalign', 'indentshift', 'indenttarget', 'indentalignfirst', 'indentshiftfirst', 'indentalignlast', 'indentshiftlast', 'depth', 'lquote', 'rquote', 'linethickness', 'munalign', 'denomalign', 'bevelled', 'voffset', 'open', 'close', 'separators', 'notation', 'subscriptshift', 'superscriptshift', 'accentunder', 'align', 'rowalign', 'columnalign', 'groupalign', 'alignmentscope', 'columnwidth', 'rowspacing', 'columnspacing', 'rowlines', 'columnlines', 'frame', 'framespacing', 'equalrows', 'equalcolumns', 'side', 'minlabelspacing', 'rowspan', 'columnspan', 'edge', 'stackalign', 'charalign', 'charspacing', 'longdivstyle', 'position', 'shift', 'location', 'crossout', 'length', 'leftoverhang', 'rightoverhang', 'mslinethickness', 'selection'], menclose: ['href', 'xref', 'mathcolor', 'mathbackground', 'notation'], merror: ['href', 'xref', 'mathcolor', 'mathbackground'], mfenced: ['href', 'xref', 'mathcolor', 'mathbackground', 'open', 'close', 'separators'], mfrac: ['href', 'xref', 'mathcolor', 'mathbackground', 'linethickness', 'munalign', 'denomalign', 'bevelled'], mglyph: ['href', 'xref', 'mathcolor', 'mathbackground', 'src', 'alt', 'width', 'height', 'valign'], mi: ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize'], mlabeledtr: ['href', 'xref', 'mathcolor', 'mathbackground'], mlongdiv: ['href', 'xref', 'mathcolor', 'mathbackground', 'longdivstyle', 'align', 'stackalign', 'charalign', 'charspacing'], mmultiscripts: ['href', 'xref', 'mathcolor', 'mathbackground', 'subscriptshift', 'superscriptshift'], mn: ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize'], mo: ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize', 'form', 'fence', 'separator', 'lspace', 'rspace', 'stretchy', 'symmetric', 'maxsize', 'minsize', 'largeop', 'movablelimits', 'accent', 'linebreak', 'lineleading', 'linebreakstyle', 'linebreakmultchar', 'indentalign', 'indentshift', 'indenttarget', 'indentalignfirst', 'indentshiftfirst', 'indentalignlast', 'indentshiftlast'], mover: ['href', 'xref', 'mathcolor', 'mathbackground', 'accent', 'align'], mpadded: ['href', 'xref', 'mathcolor', 'mathbackground', 'height', 'depth', 'width', 'lspace', 'voffset'], mphantom: ['href', 'xref', 'mathcolor', 'mathbackground'], mprescripts: ['href', 'xref', 'mathcolor', 'mathbackground'], mroot: ['href', 'xref', 'mathcolor', 'mathbackground'], mrow: ['href', 'xref', 'mathcolor', 'mathbackground'], ms: ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize', 'lquote', 'rquote'], mscarries: ['href', 'xref', 'mathcolor', 'mathbackground', 'position', 'location', 'crossout', 'scriptsizemultiplier'], mscarry: ['href', 'xref', 'mathcolor', 'mathbackground', 'location', 'crossout'], msgroup: ['href', 'xref', 'mathcolor', 'mathbackground', 'position', 'shift'], msline: ['href', 'xref', 'mathcolor', 'mathbackground', 'position', 'length', 'leftoverhang', 'rightoverhang', 'mslinethickness'], mspace: ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize'], msqrt: ['href', 'xref', 'mathcolor', 'mathbackground'], msrow: ['href', 'xref', 'mathcolor', 'mathbackground', 'position'], mstack: ['href', 'xref', 'mathcolor', 'mathbackground', 'align', 'stackalign', 'charalign', 'charspacing'], mstyle: ['href', 'xref', 'mathcolor', 'mathbackground', 'scriptlevel', 'displaystyle', 'scriptsizemultiplier', 'scriptminsize', 'infixlinebreakstyle', 'decimalpoint', 'mathvariant', 'mathsize', 'width', 'height', 'valign', 'form', 'fence', 'separator', 'lspace', 'rspace', 'stretchy', 'symmetric', 'maxsize', 'minsize', 'largeop', 'movablelimits', 'accent', 'linebreak', 'lineleading', 'linebreakstyle', 'linebreakmultchar', 'indentalign', 'indentshift', 'indenttarget', 'indentalignfirst', 'indentshiftfirst', 'indentalignlast', 'indentshiftlast', 'depth', 'lquote', 'rquote', 'linethickness', 'munalign', 'denomalign', 'bevelled', 'voffset', 'open', 'close', 'separators', 'notation', 'subscriptshift', 'superscriptshift', 'accentunder', 'align', 'rowalign', 'columnalign', 'groupalign', 'alignmentscope', 'columnwidth', 'rowspacing', 'columnspacing', 'rowlines', 'columnlines', 'frame', 'framespacing', 'equalrows', 'equalcolumns', 'side', 'minlabelspacing', 'rowspan', 'columnspan', 'edge', 'stackalign', 'charalign', 'charspacing', 'longdivstyle', 'position', 'shift', 'location', 'crossout', 'length', 'leftoverhang', 'rightoverhang', 'mslinethickness', 'selection'], msub: ['href', 'xref', 'mathcolor', 'mathbackground', 'subscriptshift'], msubsup: ['href', 'xref', 'mathcolor', 'mathbackground', 'subscriptshift', 'superscriptshift'], msup: ['href', 'xref', 'mathcolor', 'mathbackground', 'superscriptshift'], mtable: ['href', 'xref', 'mathcolor', 'mathbackground', 'align', 'rowalign', 'columnalign', 'groupalign', 'alignmentscope', 'columnwidth', 'width', 'rowspacing', 'columnspacing', 'rowlines', 'columnlines', 'frame', 'framespacing', 'equalrows', 'equalcolumns', 'displaystyle', 'side', 'minlabelspacing'], mtd: ['href', 'xref', 'mathcolor', 'mathbackground', 'rowspan', 'columnspan', 'rowalign', 'columnalign', 'groupalign'], mtext: ['href', 'xref', 'mathcolor', 'mathbackground', 'mathvariant', 'mathsize', 'width', 'height', 'depth', 'linebreak'], mtr: ['href', 'xref', 'mathcolor', 'mathbackground', 'rowalign', 'columnalign', 'groupalign'], munder: ['href', 'xref', 'mathcolor', 'mathbackground', 'accentunder', 'align'], munderover: ['href', 'xref', 'mathcolor', 'mathbackground', 'accent', 'accentunder', 'align'], none: ['href', 'xref', 'mathcolor', 'mathbackground'], semantics: ['href', 'xref', 'definitionURL', 'encoding'], picture: [], ruby: [], rp: [], rt: [], g: ['*'], circle: ['*'] }), non_empty_elements: 'td th iframe video audio object script a i area base basefont br col frame hr img input isindex link meta param embed source wbr track ruby', // tiny's external link create/edit dialog config target_list: false, // don't show the target list when creating/editing links link_title: false, // don't show the title input when creating/editing links default_link_target: '_blank', // Remove the ability to add h1 tags (since there will already be an h1 on the page) // but preserve the default Formats menu config otherwise style_formats: [{ title: 'Headings', items: [{ title: 'Heading 2', format: 'h2' }, { title: 'Heading 3', format: 'h3' }, { title: 'Heading 4', format: 'h4' }, { title: 'Heading 5', format: 'h5' }, { title: 'Heading 6', format: 'h6' }] }, { title: 'Inline', items: [{ title: 'Bold', format: 'bold' }, { title: 'Italic', format: 'italic' }, { title: 'Underline', format: 'underline' }, { title: 'Strikethrough', format: 'strikethrough' }, { title: 'Superscript', format: 'superscript' }, { title: 'Subscript', format: 'subscript' }, { title: 'Code', format: 'code' }] }, { title: 'Blocks', items: [{ title: 'Paragraph', format: 'p' }, { title: 'Blockquote', format: 'blockquote' }, { title: 'Div', format: 'div' }, { title: 'Pre', format: 'pre' }] }, { title: 'Align', items: [{ title: 'Left', format: 'alignleft' }, { title: 'Center', format: 'aligncenter' }, { title: 'Right', format: 'alignright' }, { title: 'Justify', format: 'alignjustify' }] }] }; export default defaultTinymceConfig;