V11: Update the rich text editor TinyMCE to v6 (#13013)

* update 'tinymce' from v4 to v6

* add/remove plugin & file changes

* remove unsupported plugins

* update changes to tinymce api

* bump tinymce to 6.2.0

* reinstate fastdev task

* update rte prevalues

* fix styling of tinymce inline mode

* document new files

* update builtin allowed elements, plugins and styles

* update upload_image_handler to new format

* set correct startup plugins and config

* remove old config for "Paste from Word" which is no longer supported

* update naming in default toolbar

* replace fire() with dispatch()

* support resizing of other elements besides objects, e.g. tables

* replace fire() with dispatch()

* change classes for fullscreen styling

* handle special parsing of AngularJS json response

* remove deprecated tinymce options

* use EditorOptions API to get settings

* send in correct toolbar config

* update icons to use tinymce's new icon pack

* remove unused functions

* configure custom styles

* update docs

* add initial toolbars to grid rte

* change htmlId selector to support html id's with numbers

* remove pintoolbar as it is not compatible with tiny 6

* register custom option maxImageSize through the OptionsManager

* remove custom option

* Revert "register custom option maxImageSize through the OptionsManager"

This reverts commit 342354d6cdacea67349d9d6d97b944999f8cd136.

* register custom option maxImageSize and fetch through EditorOptions

* add rounding to forced image size

* remove fullscreen plugin as it is not available in prod build anyway and it does not work

* update API for uploadImages() function

* update string extensions IsFullPath to support more filepaths with new built-in Path.IsPathFullyQualified

* resolve TODO to switch to Path.IsPathFullyQualified supported from .NET Standard 2.1

* ensure that files are copied from the TEMP folder in the web root

* add dragstart event to drag-events series

* optimise isMediaPickerEnabled function with newer array function 'includes'

* add TEMP folder to gitignore (fx fileuploads)

* update selector for "Insert Macro" button in rte test

* remove old documentation

* Use content root instead of web root for uploaded images

* test IsFullPath without tricky UNC paths that are not useful

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
This commit is contained in:
Jacob Overgaard
2022-09-20 15:20:20 +02:00
committed by GitHub
parent 084153157b
commit 510d8bf252
18 changed files with 1865 additions and 2024 deletions

View File

@@ -8,14 +8,13 @@ namespace Umbraco.Cms.Core.Configuration.Models;
public class RichTextEditorSettings
{
internal const string StaticValidElements =
"+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],-sub[style|class],-sup[style|class],-blockquote[dir|style|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[class|align|style],-pre[class|align|style],address[class|align|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*],figure,figcaption";
"+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],-sub[style|class],-sup[style|class],-blockquote[dir|style|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[class|align|style],-pre[class|align|style],address[class|align|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*],figure,figcaption,video[*],audio[*],picture[*],source[*],canvas[*]";
internal const string StaticInvalidElements = "font";
private static readonly string[] Default_plugins =
{
"paste", "anchor", "charmap", "table", "lists", "advlist", "hr", "autolink", "directionality", "tabfocus",
"searchreplace",
"anchor", "charmap", "table", "lists", "advlist", "autolink", "directionality", "searchreplace",
};
private static readonly RichTextEditorCommand[] Default_commands =
@@ -35,7 +34,7 @@ public class RichTextEditorSettings
new RichTextEditorCommand { Alias = "paste", Name = "Paste", Mode = RichTextEditorCommandMode.All },
new RichTextEditorCommand
{
Alias = "styleselect", Name = "Style select", Mode = RichTextEditorCommandMode.All,
Alias = "styles", Name = "Style select", Mode = RichTextEditorCommandMode.All,
},
new RichTextEditorCommand { Alias = "bold", Name = "Bold", Mode = RichTextEditorCommandMode.Selection },
new RichTextEditorCommand { Alias = "italic", Name = "Italic", Mode = RichTextEditorCommandMode.Selection },

View File

@@ -1326,8 +1326,6 @@ public static class StringExtensions
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
// From: http://stackoverflow.com/a/35046453/5018
// Updated from .NET 2.1+: https://stackoverflow.com/a/58250915
public static bool IsFullPath(this string path) => Path.IsPathFullyQualified(path);
// FORMAT STRINGS

View File

@@ -152,13 +152,11 @@ namespace Umbraco.Cms.Infrastructure.WebAssets {
/// Looks up a localized string similar to [
/// &apos;lib/tinymce/tinymce.min.js&apos;,
///
/// &apos;lib/tinymce/plugins/paste/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/anchor/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/charmap/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/table/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/lists/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/advlist/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/hr/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/autolink/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/directionality/plugin.min.js&apos;,
/// &apos;lib/tinymce/plugins/t [rest of string was truncated]&quot;;.

View File

@@ -1,17 +1,12 @@
[
'lib/tinymce/tinymce.min.js',
'lib/tinymce/plugins/paste/plugin.min.js',
'lib/tinymce/plugins/anchor/plugin.min.js',
'lib/tinymce/plugins/charmap/plugin.min.js',
'lib/tinymce/plugins/table/plugin.min.js',
'lib/tinymce/plugins/lists/plugin.min.js',
'lib/tinymce/plugins/advlist/plugin.min.js',
'lib/tinymce/plugins/hr/plugin.min.js',
'lib/tinymce/plugins/autolink/plugin.min.js',
'lib/tinymce/plugins/directionality/plugin.min.js',
'lib/tinymce/plugins/tabfocus/plugin.min.js',
'lib/tinymce/plugins/searchreplace/plugin.min.js',
'lib/tinymce/plugins/fullscreen/plugin.min.js',
'lib/tinymce/plugins/noneditable/plugin.min.js'
'lib/tinymce/plugins/searchreplace/plugin.min.js'
]

View File

@@ -240,7 +240,7 @@ function dependencies() {
{
"name": "signalr",
"src": [
"./node_modules/@microsoft/signalr/dist/browser/signalr.min.js",
"./node_modules/@microsoft/signalr/dist/browser/signalr.min.js"
],
"base": "./node_modules/@microsoft/signalr/dist/browser"
},
@@ -258,7 +258,9 @@ function dependencies() {
"./node_modules/tinymce/tinymce.min.js",
"./node_modules/tinymce/plugins/**",
"./node_modules/tinymce/skins/**",
"./node_modules/tinymce/themes/**"
"./node_modules/tinymce/themes/**",
"./node_modules/tinymce/models/**",
"./node_modules/tinymce/icons/**"
],
"base": "./node_modules/tinymce"
},

View File

@@ -35,7 +35,8 @@ exports.buildDev = series(setDevelopmentMode, coreBuild);
exports.coreBuild = coreBuild;
exports.dev = series(setDevelopmentMode, coreBuild, runUnitTestServer, watchTask);
exports.watch = series(watchTask);
exports.fastdev = series(setDevelopmentMode, coreBuild, watchTask);
exports.watch = series(setDevelopmentMode, watchTask);
//
exports.runTests = series(setTestMode, series(js, testUnit));
exports.runUnit = series(setTestMode, series(js, runUnitTestServer), watchTask);

View File

@@ -39,7 +39,7 @@
"ng-file-upload": "12.2.13",
"nouislider": "15.6.1",
"spectrum-colorpicker2": "2.0.9",
"tinymce": "4.9.11",
"tinymce": "6.2.0",
"typeahead.js": "0.11.1",
"underscore": "1.13.4",
"wicg-inert": "3.1.2"
@@ -5086,9 +5086,13 @@
"optional": true,
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^3.2.1",
"domutils": "^1.7.0",
"nth-check": "^1.0.2"
"css-what": "^6.0.1",
"domhandler": "^4.3.1",
"domutils": "^2.8.0",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-select-base-adapter": {
@@ -5098,6 +5102,75 @@
"dev": true,
"optional": true
},
"node_modules/css-select/node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
"integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
"dev": true,
"optional": true,
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/css-select/node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"optional": true
},
"node_modules/css-select/node_modules/domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
"dev": true,
"optional": true,
"dependencies": {
"domelementtype": "^2.2.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/css-select/node_modules/domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"dev": true,
"optional": true,
"dependencies": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/css-select/node_modules/entities": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"dev": true,
"optional": true,
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@@ -5123,11 +5196,10 @@
}
},
"node_modules/css-what": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
"integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"dev": true,
"optional": true,
"engines": {
"node": ">= 6"
},
@@ -6142,15 +6214,15 @@
"get-intrinsic": "^1.1.1",
"get-symbol-description": "^1.0.0",
"has": "^1.0.3",
"has-symbols": "^1.0.2",
"has-symbols": "^1.0.3",
"internal-slot": "^1.0.3",
"is-callable": "^1.2.4",
"is-negative-zero": "^2.0.1",
"is-negative-zero": "^2.0.2",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.1",
"is-shared-array-buffer": "^1.0.2",
"is-string": "^1.0.7",
"is-weakref": "^1.0.1",
"object-inspect": "^1.11.0",
"is-weakref": "^1.0.2",
"object-inspect": "^1.12.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.2",
"string.prototype.trimend": "^1.0.4",
@@ -9053,9 +9125,9 @@
}
},
"node_modules/has-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"dev": true,
"engines": {
"node": ">= 0.4"
@@ -9927,9 +9999,9 @@
}
},
"node_modules/is-negative-zero": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
"integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
"dev": true,
"optional": true,
"engines": {
@@ -10088,11 +10160,14 @@
}
},
"node_modules/is-shared-array-buffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
"integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
"dev": true,
"optional": true,
"dependencies": {
"call-bind": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -10183,13 +10258,13 @@
}
},
"node_modules/is-weakref": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz",
"integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
"dev": true,
"optional": true,
"dependencies": {
"call-bind": "^1.0.0"
"call-bind": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -12305,13 +12380,16 @@
}
},
"node_modules/nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
"optional": true,
"dependencies": {
"boolbase": "~1.0.0"
"boolbase": "^1.0.0"
},
"funding": {
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/number-is-nan": {
@@ -12424,9 +12502,9 @@
}
},
"node_modules/object-inspect": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
"dev": true,
"optional": true,
"funding": {
@@ -13626,18 +13704,6 @@
"node": ">=8.0.0"
}
},
"node_modules/postcss-svgo/node_modules/css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"dev": true,
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/postcss-svgo/node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -15968,9 +16034,9 @@
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"node_modules/tinymce": {
"version": "4.9.11",
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-4.9.11.tgz",
"integrity": "sha512-nkSLsax+VY5DBRjMFnHFqPwTnlLEGHCco82FwJF2JNH6W+5/ClvNC1P4uhD5lXPDNiDykSHR0XJdEh7w/ICHzA=="
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.2.0.tgz",
"integrity": "sha512-zLjbFrg0hbtJ6PxmZUjQY6zyIOM/mLrWGTvhBec7XwYwoW1E0xXMQzy2tgMTh3OvJpsclgqf2ZMjmwcv4Cludw=="
},
"node_modules/tmp": {
"version": "0.0.33",
@@ -21234,9 +21300,60 @@
"optional": true,
"requires": {
"boolbase": "^1.0.0",
"css-what": "^3.2.1",
"domutils": "^1.7.0",
"nth-check": "^1.0.2"
"css-what": "^6.0.1",
"domhandler": "^4.3.1",
"domutils": "^2.8.0",
"nth-check": "^2.0.1"
},
"dependencies": {
"dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
"integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
"dev": true,
"optional": true,
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
}
},
"domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"dev": true,
"optional": true
},
"domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
"dev": true,
"optional": true,
"requires": {
"domelementtype": "^2.2.0"
}
},
"domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"dev": true,
"optional": true,
"requires": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
}
},
"entities": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"dev": true,
"optional": true
}
}
},
"css-select-base-adapter": {
@@ -21267,11 +21384,10 @@
}
},
"css-what": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
"integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==",
"dev": true,
"optional": true
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"dev": true
},
"cssesc": {
"version": "3.0.0",
@@ -22089,15 +22205,15 @@
"get-intrinsic": "^1.1.1",
"get-symbol-description": "^1.0.0",
"has": "^1.0.3",
"has-symbols": "^1.0.2",
"has-symbols": "^1.0.3",
"internal-slot": "^1.0.3",
"is-callable": "^1.2.4",
"is-negative-zero": "^2.0.1",
"is-negative-zero": "^2.0.2",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.1",
"is-shared-array-buffer": "^1.0.2",
"is-string": "^1.0.7",
"is-weakref": "^1.0.1",
"object-inspect": "^1.11.0",
"is-weakref": "^1.0.2",
"object-inspect": "^1.12.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.2",
"string.prototype.trimend": "^1.0.4",
@@ -24406,9 +24522,9 @@
"optional": true
},
"has-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"dev": true
},
"has-to-string-tag-x": {
@@ -25050,9 +25166,9 @@
"dev": true
},
"is-negative-zero": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
"integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
"dev": true,
"optional": true
},
@@ -25165,11 +25281,14 @@
"optional": true
},
"is-shared-array-buffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
"integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
"dev": true,
"optional": true
"optional": true,
"requires": {
"call-bind": "^1.0.2"
}
},
"is-stream": {
"version": "1.1.0",
@@ -25230,13 +25349,13 @@
"dev": true
},
"is-weakref": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz",
"integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
"dev": true,
"optional": true,
"requires": {
"call-bind": "^1.0.0"
"call-bind": "^1.0.2"
}
},
"is-what": {
@@ -26890,13 +27009,13 @@
}
},
"nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
"optional": true,
"requires": {
"boolbase": "~1.0.0"
"boolbase": "^1.0.0"
}
},
"number-is-nan": {
@@ -26986,9 +27105,9 @@
}
},
"object-inspect": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
"dev": true,
"optional": true
},
@@ -27816,12 +27935,6 @@
"source-map": "^0.6.1"
}
},
"css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"dev": true
},
"dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -29681,9 +29794,9 @@
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"tinymce": {
"version": "4.9.11",
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-4.9.11.tgz",
"integrity": "sha512-nkSLsax+VY5DBRjMFnHFqPwTnlLEGHCco82FwJF2JNH6W+5/ClvNC1P4uhD5lXPDNiDykSHR0XJdEh7w/ICHzA=="
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.2.0.tgz",
"integrity": "sha512-zLjbFrg0hbtJ6PxmZUjQY6zyIOM/mLrWGTvhBec7XwYwoW1E0xXMQzy2tgMTh3OvJpsclgqf2ZMjmwcv4Cludw=="
},
"tmp": {
"version": "0.0.33",

View File

@@ -50,7 +50,7 @@
"ng-file-upload": "12.2.13",
"nouislider": "15.6.1",
"spectrum-colorpicker2": "2.0.9",
"tinymce": "4.9.11",
"tinymce": "6.2.0",
"typeahead.js": "0.11.1",
"underscore": "1.13.4",
"wicg-inert": "3.1.2"

View File

@@ -29,10 +29,6 @@ angular.module("umbraco.directives")
//for the grid by default, we don't want to include the macro toolbar
editorConfig.toolbar = _.without(editorConfig, "umbmacro");
}
//make sure there's a max image size
if (!scope.configuration.maxImageSize && scope.configuration.maxImageSize !== 0) {
editorConfig.maxImageSize = tinyMceService.defaultPrevalues().maxImageSize;
}
//ensure the grid's global config is being passed up to the RTE, these 2 properties need to be in this format
//since below we are just passing up `scope` as the actual model and for 2 way binding to work with `value` that
@@ -56,23 +52,14 @@ angular.module("umbraco.directives")
mode: editorConfig.mode
}));
// pin toolbar to top of screen if we have focus and it scrolls off the screen
function pinToolbar() {
tinyMceService.pinToolbar(tinyMceEditor);
}
// unpin toolbar to top of screen
function unpinToolbar() {
tinyMceService.unpinToolbar(tinyMceEditor);
}
$q.all(promises).then(function (result) {
var standardConfig = result[promises.length - 1];
//create a baseline Config to extend upon
var baseLineConfigObj = {
maxImageSize: editorConfig.maxImageSize
maxImageSize: editorConfig.maxImageSize,
toolbar_sticky: true
};
Utilities.extend(baseLineConfigObj, standardConfig);
@@ -85,6 +72,7 @@ angular.module("umbraco.directives")
//initialize the standard editor functionality for Umbraco
tinyMceService.initializeEditor({
editor: editor,
toolbar: editorConfig.toolbar,
model: scope,
// Form is found in the scope of the grid controller above us, not in our isolated scope
// https://github.com/umbraco/Umbraco-CMS/issues/7461
@@ -108,35 +96,6 @@ angular.module("umbraco.directives")
}, 400);
});
// TODO: Perhaps we should pin the toolbar for the rte always, regardless of if it's in the grid or not?
// this would mean moving this code into the tinyMceService.initializeEditor
//when we leave the editor (maybe)
editor.on('blur', function (e) {
angularHelper.safeApply(scope, function () {
unpinToolbar();
$('.umb-panel-body').off('scroll', pinToolbar);
});
});
// Focus on editor
editor.on('focus', function (e) {
angularHelper.safeApply(scope, function () {
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
// Click on editor
editor.on('click', function (e) {
angularHelper.safeApply(scope, function () {
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
};
/** Loads in the editor */
@@ -173,7 +132,6 @@ angular.module("umbraco.directives")
scope.$on('$destroy', function () {
eventsService.unsubscribe(tabShownListener);
//ensure we unbind this in case the blur doesn't fire above
$('.umb-panel-body').off('scroll', pinToolbar);
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}

View File

@@ -4,7 +4,9 @@
*
*
* @description
* A service containing all logic for all of the Umbraco TinyMCE plugins
* A service containing all logic for all of the Umbraco TinyMCE v6 plugins
*
* @doc https://www.tiny.cloud/docs/tinymce/6/
*/
function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, stylesheetResource, macroResource, macroService,
$routeParams, umbRequestHelper, angularHelper, userService, editorService, entityResource, eventsService, localStorageService, mediaHelper) {
@@ -12,7 +14,25 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
//These are absolutely required in order for the macros to render inline
//we put these as extended elements because they get merged on top of the normal allowed elements by tiny mce
var extendedValidElements = "@[id|class|style],-div[id|dir|class|align|style],ins[datetime|cite],-ul[class|style],-li[class|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align],span[id|class|style|lang],figure,figcaption";
var fallbackStyles = [{ title: "Page header", block: "h2" }, { title: "Section header", block: "h3" }, { title: "Paragraph header", block: "h4" }, { title: "Normal", block: "p" }, { title: "Quote", block: "blockquote" }, { title: "Code", block: "code" }];
var fallbackStyles = [
{
title: 'Headers', items: [
{ title: "Page header", block: "h2" },
{ title: "Section header", block: "h3" },
{ title: "Paragraph header", block: "h4" }
]
},
{
title: 'Blocks', items: [
{ title: "Normal", block: "p" }
]
},
{
title: 'Containers', items: [
{ title: "Quote", block: "blockquote" },
{ title: "Code", block: "code" }
]
}];
// these languages are available for localization
var availableLanguages = [
'ar',
@@ -106,7 +126,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
var promises = [$q.when(true)]; //a collection of promises, the first one is an empty promise
//queue rules loading
if (configuredStylesheets) {
if (configuredStylesheets?.length) {
configuredStylesheets.forEach(function (val, key) {
if (val.indexOf(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/") === 0) {
@@ -182,50 +202,12 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
return language;
}
/**
* Gets toolbars for the inlite theme
* @param {any} configuredToolbar
* @param {any} tinyMceConfig
*/
function getToolbars(configuredToolbar, tinyMceConfig) {
//the commands for selection/all
var allowedSelectionToolbar = _.map(_.filter(tinyMceConfig.commands,
function(f) {
return f.mode === "Selection" || f.mode === "All";
}),
function(f) {
return f.alias;
});
//the commands for insert/all
var allowedInsertToolbar = _.map(_.filter(tinyMceConfig.commands,
function(f) {
return f.mode === "Insert" || f.mode === "All";
}),
function(f) {
return f.alias;
});
var insertToolbar = _.filter(configuredToolbar, function (t) {
return allowedInsertToolbar.indexOf(t) !== -1;
}).join(" | ");
var selectionToolbar = _.filter(configuredToolbar, function (t) {
return allowedSelectionToolbar.indexOf(t) !== -1;
}).join(" | ");
return {
insertToolbar: insertToolbar,
selectionToolbar: selectionToolbar
}
}
function uploadImageHandler(blobInfo, success, failure, progress){
function uploadImageHandler(blobInfo, progress) {
return new Promise(function (resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open('POST', Umbraco.Sys.ServerVariables.umbracoUrls.tinyMceApiBaseUrl + 'UploadImage');
xhr.onloadstart = function(e) {
xhr.onloadstart = function () {
angularHelper.safeApply($rootScope, function () {
eventsService.emit("rte.file.uploading");
});
@@ -242,12 +224,12 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
};
xhr.onerror = function () {
failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
};
xhr.onload = function () {
if (xhr.status < 200 || xhr.status >= 300) {
failure('HTTP Error: ' + xhr.status);
reject('HTTP Error: ' + xhr.status);
return;
}
@@ -257,7 +239,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
data = data.split("\n");
if (!data.length > 1) {
failure('Unrecognized text string: ' + data);
reject('Unrecognized text string: ' + data);
return;
}
@@ -266,12 +248,12 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
try {
json = JSON.parse(data[1]);
} catch (e) {
failure('Invalid JSON: ' + data + ' - ' + e.message);
reject('Invalid JSON: ' + data + ' - ' + e.message);
return;
}
if (!json || typeof json.tmpLocation !== 'string') {
failure('Invalid JSON: ' + data);
reject('Invalid JSON: ' + data);
return;
}
@@ -281,17 +263,17 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
// We set the img src url to be the same as we started
// The Blob URI is stored in TinyMce's cache
// so the img still shows in the editor
success(blobInfo.blobUri());
resolve(blobInfo.blobUri());
};
const formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.blob().name);
xhr.send(formData);
});
}
function cleanupPasteData(plugin, args) {
function cleanupPasteData(_editor, args) {
// Remove spans
args.content = args.content.replace(/<\s*span[^>]*>(.*?)<\s*\/\s*span>/g, "$1");
@@ -306,12 +288,12 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
function sizeImageInEditor(editor, imageDomElement, imgUrl) {
var size = editor.dom.getSize(imageDomElement);
var maxImageSize = editor.options.get('maxImageSize');
if (editor.settings.maxImageSize && editor.settings.maxImageSize !== 0) {
var newSize = imageHelper.scaleToMaxSize(editor.settings.maxImageSize, size.w, size.h);
if (maxImageSize && maxImageSize > 0) {
var newSize = imageHelper.scaleToMaxSize(maxImageSize, size.w, size.h);
editor.dom.setAttrib(imageDomElement, 'width', newSize.width);
editor.dom.setAttrib(imageDomElement, 'height', newSize.height);
editor.dom.setAttribs(imageDomElement, { 'width': Math.round(newSize.width), 'height': Math.round(newSize.height) });
// Images inserted via Media Picker will have a URL we can use for ImageResizer QueryStrings
// Images pasted/dragged in are not persisted to media until saved & thus will need to be added
@@ -331,13 +313,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
}
function isMediaPickerEnabled(toolbarItemArray) {
var insertMediaButtonFound = false;
toolbarItemArray.forEach(toolbarItem => {
if(toolbarItem.indexOf("umbmediapicker") > -1){
insertMediaButtonFound = true;
}
});
return insertMediaButtonFound;
return toolbarItemArray.includes('umbmediapicker');
}
return {
@@ -363,51 +339,30 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
var tinyMceConfig = result[0];
var styles = result[1];
var toolbars = getToolbars(args.toolbar, tinyMceConfig);
var plugins = _.map(tinyMceConfig.plugins, function (plugin) {
return plugin.name;
});
// Plugins that must always be active
plugins.push("autoresize");
plugins.push("noneditable");
// Table plugin use color picker plugin in table properties
if (plugins.includes("table")) {
plugins.push("colorpicker");
}
var modeTheme = '';
var modeInline = false;
var toolbar = args.toolbar.join(" ");
// Based on mode set
// classic = Theme: modern, inline: false
// inline = Theme: modern, inline: true,
// distraction-free = Theme: inlite, inline: true
switch (args.mode) {
case "classic":
modeTheme = "modern";
modeInline = false;
break;
case "distraction-free":
modeTheme = "inlite";
if (args.mode === "inline") {
modeInline = true;
break;
default:
//Will default to 'classic'
modeTheme = "modern";
modeInline = false;
break;
}
else if (args.mode === "distraction-free") {
modeInline = true;
toolbar = false;
}
//create a baseline Config to exten upon
//create a baseline Config to extend upon
var config = {
theme: modeTheme,
inline: modeInline,
plugins: plugins,
valid_elements: tinyMceConfig.validElements,
@@ -419,18 +374,15 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
autoresize_bottom_margin: 10,
content_css: styles.stylesheets,
style_formats: styles.styleFormats,
style_formats_autohide: true,
language: getLanguage(),
//this would be for a theme other than inlite
toolbar: args.toolbar.join(" "),
//these are for the inlite theme to work
insert_toolbar: toolbars.insertToolbar,
selection_toolbar: toolbars.selectionToolbar,
toolbar: toolbar,
body_class: "umb-rte",
//see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix
//see https://www.tiny.cloud/docs/tinymce/6/editor-important-options/#cache_suffix
cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster
};
@@ -453,35 +405,12 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
config.target = args.target;
}
/*
// We are not ready to limit the pasted elements further than default, we will return to this feature. ( TODO: Make this feature an option. )
// We keep spans here, cause removing spans here also removes b-tags inside of them, instead we strip them out later. (TODO: move this definition to the config file... )
var validPasteElements = "-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody,img[src|alt|width|height],ul,ol,li,hr,pre,dl,dt,figure,figcaption,wbr"
// add elements from user configurated styleFormats to our list of validPasteElements.
// (This means that we only allow H3-element if its configured as a styleFormat on this specific propertyEditor.)
var style, i = 0;
for(; i < styles.styleFormats.length; i++) {
style = styles.styleFormats[i];
if(style.block) {
validPasteElements += "," + style.block;
}
}
*/
/**
The default paste config can be overwritten by defining these properties in the customConfig.
*/
var pasteConfig = {
paste_remove_styles: true,
paste_text_linebreaktype: true, //Converts plaintext linebreaks to br or p elements.
paste_strip_class_attributes: "none",
//paste_word_valid_elements: validPasteElements,
paste_remove_styles_if_webkit: true,
paste_preprocess: cleanupPasteData
};
Utilities.extend(config, pasteConfig);
@@ -558,7 +487,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
*/
defaultPrevalues: function () {
var cfg = {};
cfg.toolbar = ["ace", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link", "umbmediapicker", "umbmacro", "umbembeddialog"];
cfg.toolbar = ["ace", "styles", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link", "umbmediapicker", "umbmacro", "umbembeddialog"];
cfg.stylesheets = [];
cfg.maxImageSize = 500;
return cfg;
@@ -575,11 +504,11 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
* @param {Object} editor the TinyMCE editor instance
*/
createInsertEmbeddedMedia: function (editor, callback) {
editor.addButton('umbembeddialog', {
icon: 'custom icon-tv',
editor.ui.registry.addButton('umbembeddialog', {
icon: 'embed',
tooltip: 'Embed',
stateSelector: 'div[data-embed-url]',
onclick: function () {
onAction: function () {
// Get the selected element
// Check nodename is a DIV and the claslist contains 'embeditem'
@@ -637,10 +566,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
createAceCodeEditor: function (editor, callback) {
editor.addButton("ace", {
icon: "code",
editor.ui.registry.addButton("ace", {
icon: "sourcecode",
tooltip: "View Source Code",
onclick: function(){
onAction: function () {
if (callback) {
angularHelper.safeApply($rootScope, function () {
callback();
@@ -662,11 +591,11 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
* @param {Object} editor the TinyMCE editor instance
*/
createMediaPicker: function (editor, callback) {
editor.addButton('umbmediapicker', {
icon: 'custom icon-picture',
editor.ui.registry.addButton('umbmediapicker', {
icon: 'image',
tooltip: 'Media Picker',
stateSelector: 'img[data-udi]',
onclick: function () {
onAction: function () {
var selectedElm = editor.selection.getNode(),
currentTarget;
@@ -759,7 +688,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
// When image is loaded we are ready to call sizeImageInEditor.
var onImageLoaded = function () {
sizeImageInEditor(editor, imgElm, img.url);
editor.fire("Change");
editor.dispatch("Change");
}
// Check if image already is loaded.
@@ -806,7 +735,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
});
/** when the contents load we need to find any macros declared and load in their content */
editor.on("SetContent", function (o) {
editor.on("SetContent", function () {
//get all macro divs and load their content
$(editor.dom.select(".umb-macro-holder.mceNonEditable")).each(function () {
@@ -835,13 +764,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
}
/** Adds the button instance */
editor.addButton('umbmacro', {
icon: 'custom icon-settings-alt',
editor.ui.registry.addButton('umbmacro', {
icon: 'preferences',
tooltip: 'Insert macro',
onPostRender: function () {
let ctrl = this;
onSetup: function (buttonApi) {
/**
* Check if the macro is currently selected and toggle the menu button
*/
@@ -851,19 +777,21 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
activeMacroElement = getRealMacroElem(evt.element);
//set the button active/inactive
ctrl.active(activeMacroElement !== null);
buttonApi.setEnabled(activeMacroElement === null);
}
//NOTE: This could be another way to deal with the active/inactive state
//editor.on('ObjectSelected', function (e) {});
//set onNodeChanged event listener
editor.on('NodeChange', onNodeChanged);
return function () {
//remove the event listener
editor.off('NodeChange', onNodeChanged);
}
},
/** The insert macro button click event handler */
onclick: function () {
onAction: function () {
var dialogData = {
//flag for use in rte so we only show macros flagged for the editor
@@ -984,14 +912,13 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
function createLinkList(callback) {
return function () {
var linkList = editor.settings.link_list;
var linkList = editor.options.get('link_list');
if (typeof (linkList) === "string") {
tinymce.util.XHR.send({
url: linkList,
success: function (text) {
callback(tinymce.util.JSON.parse(text));
}
if (linkList && typeof linkList === "string") {
fetch(linkList).then(function (response) {
callback(response.json());
}).catch(function (error) {
console.log(error);
});
} else {
callback(linkList);
@@ -1039,13 +966,16 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
value: ''
}];
tinymce.each(editor.settings.rel_list, function (rel) {
var linkRelList = editor.options.get('link_rel_list');
if (linkRelList) {
tinymce.each(linkRelList, function (rel) {
relListItems.push({
text: rel.text || rel.title,
value: rel.value,
selected: relValue === rel.value
});
});
}
return relListItems;
}
@@ -1056,61 +986,25 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
value: ''
}];
if (!editor.settings.target_list) {
targetListItems.push({
text: 'New window',
value: '_blank'
});
}
tinymce.each(editor.settings.target_list, function (target) {
var linkList = editor.options.get('link_list');
if (linkList) {
tinymce.each(linkList, function (target) {
targetListItems.push({
text: target.text || target.title,
value: target.value,
selected: targetValue === target.value
});
});
} else {
targetListItems.push({
text: 'New window',
value: '_blank'
});
}
return targetListItems;
}
function buildAnchorListControl(url) {
var anchorList = [];
tinymce.each(editor.dom.select('a:not([href])'), function (anchor) {
var id = anchor.name || anchor.id;
if (id) {
anchorList.push({
text: id,
value: '#' + id,
selected: url.indexOf('#' + id) !== -1
});
}
});
if (anchorList.length) {
anchorList.unshift({
text: 'None',
value: ''
});
return {
name: 'anchor',
type: 'listbox',
label: 'Anchors',
values: anchorList,
onselect: linkListChangeHandler
};
}
}
function updateText() {
if (!initialText && data.text.length === 0) {
this.parent().parent().find('#text')[0].value(this.value());
}
}
selectedElm = selection.getNode();
anchorElm = dom.getParent(selectedElm, 'a[href]');
@@ -1134,7 +1028,8 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
};
}
if (editor.settings.target_list !== false) {
var optionsLinkList = editor.options.get('link_list');
if (optionsLinkList !== false) {
targetListCtrl = {
name: 'target',
type: 'listbox',
@@ -1143,7 +1038,8 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
};
}
if (editor.settings.rel_list) {
var linkRelList = editor.options.get('link_rel_list');
if (linkRelList) {
relListCtrl = {
name: 'rel',
type: 'listbox',
@@ -1195,29 +1091,31 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
});
}
editor.addButton('link', {
editor.ui.registry.addButton('link', {
icon: 'link',
tooltip: 'Insert/edit link',
shortcut: 'Ctrl+K',
onclick: createLinkList(showDialog),
onAction: createLinkList(showDialog),
stateSelector: 'a[href]'
});
editor.addButton('unlink', {
editor.ui.registry.addButton('unlink', {
icon: 'unlink',
tooltip: 'Remove link',
cmd: 'unlink',
onAction: () => {
editor.execCommand('unlink');
},
stateSelector: 'a[href]'
});
editor.addShortcut('Ctrl+K', '', createLinkList(showDialog));
this.showDialog = showDialog;
editor.addMenuItem('link', {
editor.ui.registry.addMenuItem('link', {
icon: 'link',
text: 'Insert link',
shortcut: 'Ctrl+K',
onclick: createLinkList(showDialog),
onAction: createLinkList(showDialog),
stateSelector: 'a[href]',
context: 'insert',
prependToContext: true
@@ -1339,54 +1237,6 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
},
pinToolbar : function (editor) {
//we can't pin the toolbar if this doesn't exist (i.e. when in distraction free mode)
if (!editor.editorContainer) {
return;
}
var tinyMce = $(editor.editorContainer);
var toolbar = tinyMce.find(".mce-toolbar");
var toolbarHeight = toolbar.height();
var tinyMceRect = editor.editorContainer.getBoundingClientRect();
var tinyMceTop = tinyMceRect.top;
var tinyMceBottom = tinyMceRect.bottom;
var tinyMceWidth = tinyMceRect.width;
var tinyMceEditArea = tinyMce.find(".mce-edit-area");
// set padding in top of mce so the content does not "jump" up
tinyMceEditArea.css("padding-top", toolbarHeight);
if (tinyMceTop < 177 && ((177 + toolbarHeight) < tinyMceBottom)) {
toolbar
.css("position", "fixed")
.css("top", "177px")
.css("left", "auto")
.css("right", "auto")
.css("width", tinyMceWidth);
} else {
toolbar
.css("position", "absolute")
.css("left", "")
.css("right", "")
.css("top", "")
.css("width", "");
}
},
unpinToolbar: function (editor) {
var tinyMce = $(editor.editorContainer);
var toolbar = tinyMce.find(".mce-toolbar");
var tinyMceEditArea = tinyMce.find(".mce-edit-area");
// reset padding in top of mce so the content does not "jump" up
tinyMceEditArea.css("padding-top", "0");
toolbar.css("position", "static");
},
/** Helper method to initialize the tinymce editor within Umbraco */
initializeEditor: function (args) {
@@ -1400,6 +1250,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
// force TinyMCE to load plugins/themes from minified files (see http://archive.tinymce.com/wiki.php/api4:property.tinymce.suffix.static)
args.editor.suffix = ".min";
// Register custom option maxImageSize
args.editor.options.register('maxImageSize', { processor: 'number', default: 500 });
var unwatch = null;
//Starts a watch on the model value so that we can update TinyMCE if the model changes behind the scenes or from the server
@@ -1410,9 +1263,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
//uses an empty string in the editor when the value is null
args.editor.setContent(newVal || "", { format: 'raw' });
//we need to manually fire this event since it is only ever fired based on loading from the DOM, this
//we need to manually dispatch this event since it is only ever dispatchd based on loading from the DOM, this
// is required for our plugins listening to this event to execute
args.editor.fire('LoadContent', null);
args.editor.dispatch('LoadContent', null);
}
});
}
@@ -1454,11 +1307,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
// Then we need to add an event listener to the editor
// That will update native browser drag & drop events
// To update the icon to show you can NOT drop something into the editor
var toolbarItems = args.editor.settings.toolbar === false ? [] : args.editor.settings.toolbar.split(" ");
if(isMediaPickerEnabled(toolbarItems) === false){
if (args.toolbar && isMediaPickerEnabled(args.toolbar) === false) {
// Wire up the event listener
args.editor.on('dragend dragover draggesture dragdrop drop drag', function (e) {
args.editor.on('dragstart dragend dragover draggesture dragdrop drop drag', function (e) {
e.preventDefault();
e.dataTransfer.effectAllowed = "none";
e.dataTransfer.dropEffect = "none";
@@ -1473,9 +1324,14 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
// find src attribute where value starts with `blob:`
// search is case-insensitive and allows single or double quotes
if (content.search(/src=["']blob:.*?["']/gi) !== -1) {
args.editor.uploadImages(function(data) {
args.editor.uploadImages().then(function (data) {
// Once all images have been uploaded
data.forEach(function (item) {
// Skip items that failed upload
if (item.status === false) {
return;
}
// Select img element
var img = item.element;
@@ -1486,7 +1342,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
// Select the img & add new attr which we can search for
// When its being persisted in RTE property editor
// To create a media item & delete this tmp one etc
tinymce.activeEditor.$(img).attr({ "data-tmpimg": tmpLocation });
args.editor.dom.setAttrib(img, "data-tmpimg", tmpLocation);
// Resize the image to the max size configured
// NOTE: no imagesrc passed into func as the src is blob://...
@@ -1494,9 +1350,6 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
sizeImageInEditor(args.editor, img);
});
});
// Get all img where src starts with blob: AND does NOT have a data=tmpimg attribute
// This is most likely seen as a duplicate image that has already been uploaded
// editor.uploadImages() does not give us any indiciation that the image been uploaded already
@@ -1517,6 +1370,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
args.editor.dom.setAttrib(imageElement, "data-tmpimg", tmpLocation);
}
});
});
}
@@ -1534,7 +1388,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
});
args.editor.on('init', function (e) {
args.editor.on('init', function () {
if (args.model.value) {
args.editor.setContent(args.model.value);
@@ -1543,7 +1397,6 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
//enable browser based spell checking
args.editor.getBody().setAttribute('spellcheck', true);
/** Setup sanitization for preventing injecting arbitrary JavaScript execution in attributes:
* https://github.com/advisories/GHSA-w7jx-j77m-wp65
* https://github.com/advisories/GHSA-5vm8-hhgr-jcjp
@@ -1620,6 +1473,11 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
args.editor.on('ObjectResized', function (e) {
var srcAttr = $(e.target).attr("src");
if (!srcAttr) {
return;
}
var path = srcAttr.split("?")[0];
mediaHelper.getProcessedImageUrl(path, {
width: e.width,
@@ -1744,7 +1602,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
view: 'views/propertyeditors/rte/codeeditor.html',
submit: function (model) {
args.editor.setContent(model.content);
args.editor.fire('Change');
args.editor.dispatch('Change');
editorService.close();
},
close: function () {

View File

@@ -140,6 +140,13 @@
}
}
.tox-tinymce-inline {
z-index: 999;
}
.tox-tinymce-fullscreen {
position: absolute;
}
.mce-menu {
border-radius: 3px;
@@ -170,16 +177,3 @@
border: 1px solid @gray-8;
max-width: none;
}
.mce-fullscreen {
position: absolute;
.mce-in {
position: fixed;
top: 35px !important;
}
umb-editor__overlay, .umb-editor {
position: fixed;
}
}

View File

@@ -15,10 +15,6 @@ angular.module("umbraco")
if (!editorConfig || Utilities.isString(editorConfig)) {
editorConfig = tinyMceService.defaultPrevalues();
}
//make sure there's a max image size
if (!editorConfig.maxImageSize && editorConfig.maxImageSize !== 0) {
editorConfig.maxImageSize = tinyMceService.defaultPrevalues().maxImageSize;
}
var width = editorConfig.dimensions ? parseInt(editorConfig.dimensions.width, 10) || null : null;
var height = editorConfig.dimensions ? parseInt(editorConfig.dimensions.height, 10) || null : null;
@@ -81,6 +77,7 @@ angular.module("umbraco")
//initialize the standard editor functionality for Umbraco
tinyMceService.initializeEditor({
editor: editor,
toolbar: editorConfig.toolbar,
model: $scope.model,
currentFormInput: $scope.rteForm.modelValue
});

View File

@@ -40,8 +40,9 @@
<umb-control-group label="Mode" description="Select mode">
<div class="vertical-align-items">
<select ng-model="model.value.mode">
<option value="classic">Classic</option> <!-- Theme:modern & inline:false-->
<option value="distraction-free">Distraction Free</option> <!-- Theme:inlite & inline:true -->
<option value="classic">Classic</option> <!-- Theme:silver & inline:false-->
<option value="inline">Inline</option> <!-- Theme:silver & inline:true-->
<option value="distraction-free">Distraction Free</option> <!-- Theme:silver & toolbars:null & inline:true -->
</select>
</div>
</umb-control-group>

View File

@@ -41,18 +41,6 @@
"RuntimeMinification": {
"useInMemoryCache": true,
"cacheBuster": "Timestamp"
},
"RichTextEditor": {
"Commands": [
{
"Alias": "fullscreen",
"Name": "Full Screen",
"Mode": "All"
}
],
"Plugins": [
"fullscreen"
]
}
}
}

View File

@@ -675,7 +675,7 @@ context('Content', () => {
cy.umbracoTreeItem("content", [viewMacroName]).click();
// Insert macro
cy.get('#mceu_13-button').click();
cy.get('button[title="Insert macro"]').click();
cy.get('.umb-card-grid-item').contains(viewMacroName).click();
// Save and publish

View File

@@ -2339,10 +2339,16 @@
}
},
"dependencies": {
"@colors/colors": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
"integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
"dev": true
},
"@cypress/request": {
"version": "2.88.7",
"resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.7.tgz",
"integrity": "sha512-FTULIP2rnDJvZDT9t6B4nSfYR40ue19tVmv3wUcY05R9/FPCoMl1nAPJkzWzBCo7ltVn5ThQTbxiMoGBN7k0ig==",
"version": "2.88.10",
"resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz",
"integrity": "sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
@@ -2352,8 +2358,7 @@
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.3",
"http-signature": "~1.2.0",
"http-signature": "~1.3.6",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
@@ -2459,18 +2464,6 @@
}
}
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@@ -2535,9 +2528,9 @@
"dev": true
},
"async": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
"integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==",
"dev": true
},
"asynckit": {
@@ -2683,13 +2676,12 @@
}
},
"cli-table3": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz",
"integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==",
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz",
"integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==",
"dev": true,
"requires": {
"colors": "^1.1.2",
"object-assign": "^4.1.0",
"@colors/colors": "1.5.0",
"string-width": "^4.2.0"
}
},
@@ -2730,12 +2722,6 @@
"integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==",
"dev": true
},
"colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -2790,9 +2776,9 @@
}
},
"cy-verify-downloads": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/cy-verify-downloads/-/cy-verify-downloads-0.0.5.tgz",
"integrity": "sha512-aRK7VvKG5rmDJK4hjZ27KM2oOOz0cMO7z/j4zX8qCc4ffXZS1XRJkofUY0w5u6MCB/wUsNMs03VuvkeR2tNPoQ==",
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/cy-verify-downloads/-/cy-verify-downloads-0.1.5.tgz",
"integrity": "sha512-8iviQ+LhZ9z7bUEfN5YOGqYy292tSDHVDNsz9eaGZ97dVybgx9NhkSyk//2rVXIV97JBIdx8GIeGBBD+JBB27w==",
"dev": true
},
"cycle": {
@@ -2802,9 +2788,9 @@
"dev": true
},
"cypress": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-8.4.1.tgz",
"integrity": "sha512-itJXq0Vx3sXCUrDyBi2IUrkxVu/gTTp1VhjB5tzGgkeCR8Ae+/T8WV63rsZ7fS8Tpq7LPPXiyoM/sEdOX7cR6A==",
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-8.7.0.tgz",
"integrity": "sha512-b1bMC3VQydC6sXzBMFnSqcvwc9dTZMgcaOzT0vpSD+Gq1yFc+72JDWi55sfUK5eIeNLAtWOGy1NNb6UlhMvB+Q==",
"dev": true,
"requires": {
"@cypress/request": "^2.88.6",
@@ -2841,6 +2827,7 @@
"minimist": "^1.2.5",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
"proxy-from-env": "1.0.0",
"ramda": "~0.27.1",
"request-progress": "^3.0.0",
"supports-color": "^8.1.1",
@@ -3021,12 +3008,6 @@
"integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=",
"dev": true
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-glob": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
@@ -3040,12 +3021,6 @@
"micromatch": "^4.0.4"
}
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
"fastq": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
@@ -3196,22 +3171,6 @@
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
"dev": true
},
"har-validator": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"dev": true,
"requires": {
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3219,14 +3178,14 @@
"dev": true
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
"integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
"dev": true,
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
"jsprim": "^2.0.2",
"sshpk": "^1.14.1"
}
},
"human-signals": {
@@ -3358,15 +3317,9 @@
"dev": true
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
"dev": true
},
"json-stringify-safe": {
@@ -3386,14 +3339,14 @@
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
"integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
"dev": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"json-schema": "0.4.0",
"verror": "1.10.0"
}
},
@@ -3500,18 +3453,18 @@
}
},
"mime-db": {
"version": "1.51.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
"integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true
},
"mime-types": {
"version": "2.1.34",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
"integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"requires": {
"mime-db": "1.51.0"
"mime-db": "1.52.0"
}
},
"mimic-fn": {
@@ -3562,12 +3515,6 @@
"path-key": "^3.0.0"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -3650,25 +3597,23 @@
"dev": true
},
"prompt": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/prompt/-/prompt-1.2.0.tgz",
"integrity": "sha512-iGerYRpRUg5ZyC+FJ/25G5PUKuWAGRjW1uOlhX7Pi3O5YygdK6R+KEaBjRbHSkU5vfS5PZCltSPZdDtUYwRCZA==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/prompt/-/prompt-1.3.0.tgz",
"integrity": "sha512-ZkaRWtaLBZl7KKAKndKYUL8WqNT+cQHKRZnT4RYYms48jQkFw3rrBL+/N5K/KtdEveHkxs982MX2BkDKub2ZMg==",
"dev": true,
"requires": {
"async": "~0.9.0",
"colors": "^1.1.2",
"@colors/colors": "1.5.0",
"async": "3.2.3",
"read": "1.0.x",
"revalidator": "0.1.x",
"winston": "2.x"
}
},
"dependencies": {
"async": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
"proxy-from-env": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
"dev": true
}
}
},
"psl": {
"version": "1.8.0",
@@ -3693,9 +3638,9 @@
"dev": true
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
"dev": true
},
"querystring": {
@@ -3711,9 +3656,9 @@
"dev": true
},
"ramda": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz",
"integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==",
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
"integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
"dev": true
},
"read": {
@@ -3834,9 +3779,9 @@
}
},
"sshpk": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
"integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
"dev": true,
"requires": {
"asn1": "~0.2.3",
@@ -3959,9 +3904,9 @@
"dev": true
},
"typescript": {
"version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw=="
},
"umbraco-cypress-testhelpers": {
"version": "1.0.0-beta-73",
@@ -3985,15 +3930,6 @@
"integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
"dev": true
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}
},
"url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",

View File

@@ -7,16 +7,20 @@
"test": "npx cypress run",
"ui": "npx cypress open"
},
"engines": {
"node": ">=14.0.0 <17",
"npm": ">=8.0.0 < 9"
},
"devDependencies": {
"cross-env": "^7.0.2",
"cypress": "8.4.1",
"cy-verify-downloads": "0.0.5",
"cross-env": "^7.0.3",
"cypress": "8.7.0",
"cy-verify-downloads": "0.1.5",
"del": "^6.0.0",
"ncp": "^2.0.0",
"prompt": "^1.2.0",
"umbraco-cypress-testhelpers": "^1.0.0-beta-73"
},
"dependencies": {
"typescript": "^3.9.2"
"typescript": "^4.6.3"
}
}

View File

@@ -12,7 +12,6 @@
"esModuleInterop": true,
"importHelpers": true,
"target": "es5",
"types": [
"cypress",
"cy-verify-downloads"
@@ -32,6 +31,6 @@
]
},
"include": [
"src/**/*.ts"
"cypress/**/*.ts"
]
}