From 223d5795c3cb428630343005c64e6c1cc74a9ab6 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 20 Jul 2018 00:55:28 +1000 Subject: [PATCH 001/337] wip - newer tinymce, with the inlite/inline theme, updated config file, plenty of fixes, now need more fixes --- src/Umbraco.Web.UI.Client/bower.json | 182 +-- .../components/grid/grid.rte.directive.js | 8 +- .../common/mocks/editors/prevalues.mocks.js | 158 +- .../src/common/services/tinymce.service.js | 1272 +++++++++-------- .../common/overlays/embed/embed.controller.js | 195 ++- .../views/common/overlays/embed/embed.html | 45 +- .../propertyeditors/rte/rte.controller.js | 122 +- .../src/views/propertyeditors/rte/rte.html | 51 +- .../rte/rte.prevalues.controller.js | 8 +- .../propertyeditors/rte/rte.prevalues.html | 4 +- .../config/tinyMceConfig.Release.config | 311 +--- .../config/tinyMceConfig.config | 309 +--- .../ContentEditing/RichTextEditorCommand.cs | 24 +- .../ContentEditing/RichTextEditorPlugin.cs | 3 - .../PropertyEditors/RichTextConfiguration.cs | 7 +- .../RichTextPreValueController.cs | 48 +- 16 files changed, 1148 insertions(+), 1599 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/bower.json b/src/Umbraco.Web.UI.Client/bower.json index 71b393ae9c..73a76145ec 100644 --- a/src/Umbraco.Web.UI.Client/bower.json +++ b/src/Umbraco.Web.UI.Client/bower.json @@ -1,94 +1,96 @@ { - "name": "umbraco", - "version": "7", - "homepage": "https://github.com/umbraco/Umbraco-CMS", - "authors": [ - "Shannon " - ], - "description": "Umbraco CMS", - "license": "MIT", - "private": true, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "dependencies": { - "angular": "~1.7.2", - "angular-cookies": "~1.7.2", - "angular-sanitize": "~1.7.2", - "angular-touch": "~1.7.2", - "angular-route": "~1.7.2", - "angular-animate": "~1.7.2", - "angular-i18n": "~1.7.2", - "signalr": "^2.2.1", - "typeahead.js": "~0.10.5", - "underscore": "~1.7.0", - "rgrove-lazyload": "*", - "bootstrap-social": "~4.8.0", - "jquery": "2.2.4", - "jquery-ui": "~1.12.0", - "jquery-migrate": "1.4.0", - "angular-dynamic-locale": "~0.1.36", - "ng-file-upload": "~12.2.13", - "tinymce": "~4.7.1", - "codemirror": "~5.3.0", - "angular-local-storage": "~0.7.1", - "moment": "~2.10.3", - "ace-builds": "~1.3.0", - "clipboard": "~2.0.0", - "font-awesome": "~4.2", - "animejs": "^2.2.0", - "angular-ui-sortable": "0.14.3", - "angular-messages": "^1.7.2" - }, - "install": { - "path": "lib-bower", - "ignore": [ - "font-awesome", - "bootstrap", - "codemirror", - "ace-builds" + "name": "umbraco", + "version": "7", + "homepage": "https://github.com/umbraco/Umbraco-CMS", + "authors": [ + "Shannon " ], - "sources": { - "moment": [ - "bower_components/moment/min/moment.min.js", - "bower_components/moment/min/moment-with-locales.js", - "bower_components/moment/min/moment-with-locales.min.js", - "bower_components/moment/locale/*.js" - ], - "underscore": [ - "bower_components/underscore/underscore-min.js", - "bower_components/underscore/underscore-min.map" - ], - "jquery": [ - "bower_components/jquery/dist/jquery.min.js", - "bower_components/jquery/dist/jquery.min.map" - ], - "angular-dynamic-locale": [ - "bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js", - "bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js.map" - ], - "angular-local-storage": [ - "bower_components/angular-local-storage/dist/angular-local-storage.min.js", - "bower_components/angular-local-storage/dist/angular-local-storage.min.js.map" - ], - "tinymce": [ - "bower_components/tinymce/tinymce.min.js" - ], - "angular-i18n": "bower_components/angular-i18n/angular-locale_*.js", - "typeahead.js": "bower_components/typeahead.js/dist/typeahead.bundle.min.js", - "rgrove-lazyload": "bower_components/rgrove-lazyload/lazyload.js", - "ng-file-upload": "bower_components/ng-file-upload/ng-file-upload.min.js", - "jquery-ui": "bower_components/jquery-ui/jquery-ui.min.js", - "jquery-migrate": "bower_components/jquery-migrate/jquery-migrate.min.js", - "clipboard": "bower_components/clipboard/dist/clipboard.min.js", - "animejs": "bower_components/animejs/anime.min.js" + "description": "Umbraco CMS", + "license": "MIT", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "angular": "~1.7.2", + "angular-cookies": "~1.7.2", + "angular-sanitize": "~1.7.2", + "angular-touch": "~1.7.2", + "angular-route": "~1.7.2", + "angular-animate": "~1.7.2", + "angular-i18n": "~1.7.2", + "signalr": "^2.2.1", + "typeahead.js": "~0.10.5", + "underscore": "~1.7.0", + "rgrove-lazyload": "*", + "bootstrap-social": "~4.8.0", + "jquery": "2.2.4", + "jquery-ui": "~1.12.0", + "jquery-migrate": "1.4.0", + "angular-dynamic-locale": "~0.1.36", + "ng-file-upload": "~12.2.13", + "tinymce": "~4.8.0", + "codemirror": "~5.3.0", + "angular-local-storage": "~0.7.1", + "moment": "~2.10.3", + "ace-builds": "~1.3.0", + "clipboard": "~2.0.0", + "font-awesome": "~4.2", + "animejs": "^2.2.0", + "angular-ui-sortable": "0.14.3", + "angular-messages": "^1.7.2" + }, + "install": { + "path": "lib-bower", + "ignore": [ + "font-awesome", + "bootstrap", + "codemirror", + "ace-builds" + ], + "sources": { + "moment": [ + "bower_components/moment/min/moment.min.js", + "bower_components/moment/min/moment-with-locales.js", + "bower_components/moment/min/moment-with-locales.min.js", + "bower_components/moment/locale/*.js" + ], + "underscore": [ + "bower_components/underscore/underscore-min.js", + "bower_components/underscore/underscore-min.map" + ], + "jquery": [ + "bower_components/jquery/dist/jquery.min.js", + "bower_components/jquery/dist/jquery.min.map" + ], + "angular-dynamic-locale": [ + "bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js", + "bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js.map" + ], + "angular-local-storage": [ + "bower_components/angular-local-storage/dist/angular-local-storage.min.js", + "bower_components/angular-local-storage/dist/angular-local-storage.min.js.map" + ], + "tinymce": [ + "bower_components/tinymce/tinymce.min.js", + "bower_components/tinymce/skins/*", + "bower_components/tinymce/themes/*" + ], + "angular-i18n": "bower_components/angular-i18n/angular-locale_*.js", + "typeahead.js": "bower_components/typeahead.js/dist/typeahead.bundle.min.js", + "rgrove-lazyload": "bower_components/rgrove-lazyload/lazyload.js", + "ng-file-upload": "bower_components/ng-file-upload/ng-file-upload.min.js", + "jquery-ui": "bower_components/jquery-ui/jquery-ui.min.js", + "jquery-migrate": "bower_components/jquery-migrate/jquery-migrate.min.js", + "clipboard": "bower_components/clipboard/dist/clipboard.min.js", + "animejs": "bower_components/animejs/anime.min.js" + } + }, + "devDependencies": { + "angular-mocks": "~1.7.2" } - }, - "devDependencies": { - "angular-mocks": "~1.7.2" - } } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index e18137085b..cb5b2a8a27 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -34,10 +34,10 @@ angular.module("umbraco.directives") var invalidElements = tinyMceConfig.inValidElements; var plugins = _.map(tinyMceConfig.plugins, function (plugin) { - if (plugin.useOnFrontend) { - return plugin.name; - } - }).join(" ") + " autoresize"; + return plugin.name; + }); + + plugins.push("autoresize"); //config value on the data type var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"].join(" | "); diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/editors/prevalues.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/editors/prevalues.mocks.js index 1b8560fa10..a77cea15fa 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/editors/prevalues.mocks.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/editors/prevalues.mocks.js @@ -1,81 +1,81 @@ angular.module('umbraco.mocks'). - factory('prevaluesMocks', ['$httpBackend', 'mocksUtils', function ($httpBackend, mocksUtils) { - 'use strict'; - - function getRichTextConfiguration(status, data, headers) { - if (!mocksUtils.checkAuth()) { - return [401, null, null]; - } - else { - return [200, { "plugins": [{ "name": "code", "useOnFrontend": true }, { "name": "paste", "useOnFrontend": true }, { "name": "umbracolink", "useOnFrontend": true }], "commands": [{ "icon": "images/editor/code.gif", "command": "code", "alias": "code", "userInterface": "false", "frontEndCommand": "code", "value": "", "priority": 1, "isStylePicker": false }, { "icon": "images/editor/removeformat.gif", "command": "removeformat", "alias": "removeformat", "userInterface": "false", "frontEndCommand": "removeformat", "value": "", "priority": 2, "isStylePicker": false }, { "icon": "images/editor/undo.gif", "command": "undo", "alias": "undo", "userInterface": "false", "frontEndCommand": "undo", "value": "", "priority": 11, "isStylePicker": false }, { "icon": "images/editor/redo.gif", "command": "redo", "alias": "redo", "userInterface": "false", "frontEndCommand": "redo", "value": "", "priority": 12, "isStylePicker": false }, { "icon": "images/editor/cut.gif", "command": "cut", "alias": "cut", "userInterface": "false", "frontEndCommand": "cut", "value": "", "priority": 13, "isStylePicker": false }, { "icon": "images/editor/copy.gif", "command": "copy", "alias": "copy", "userInterface": "false", "frontEndCommand": "copy", "value": "", "priority": 14, "isStylePicker": false }, { "icon": "images/editor/showStyles.png", "command": "styleselect", "alias": "styleselect", "userInterface": "false", "frontEndCommand": "styleselect", "value": "", "priority": 20, "isStylePicker": false }, { "icon": "images/editor/bold.gif", "command": "bold", "alias": "bold", "userInterface": "false", "frontEndCommand": "bold", "value": "", "priority": 21, "isStylePicker": false }, { "icon": "images/editor/italic.gif", "command": "italic", "alias": "italic", "userInterface": "false", "frontEndCommand": "italic", "value": "", "priority": 22, "isStylePicker": false }, { "icon": "images/editor/underline.gif", "command": "underline", "alias": "underline", "userInterface": "false", "frontEndCommand": "underline", "value": "", "priority": 23, "isStylePicker": false }, { "icon": "images/editor/strikethrough.gif", "command": "strikethrough", "alias": "strikethrough", "userInterface": "false", "frontEndCommand": "strikethrough", "value": "", "priority": 24, "isStylePicker": false }, { "icon": "images/editor/justifyleft.gif", "command": "justifyleft", "alias": "justifyleft", "userInterface": "false", "frontEndCommand": "alignleft", "value": "", "priority": 31, "isStylePicker": false }, { "icon": "images/editor/justifycenter.gif", "command": "justifycenter", "alias": "justifycenter", "userInterface": "false", "frontEndCommand": "aligncenter", "value": "", "priority": 32, "isStylePicker": false }, { "icon": "images/editor/justifyright.gif", "command": "justifyright", "alias": "justifyright", "userInterface": "false", "frontEndCommand": "alignright", "value": "", "priority": 33, "isStylePicker": false }, { "icon": "images/editor/justifyfull.gif", "command": "justifyfull", "alias": "justifyfull", "userInterface": "false", "frontEndCommand": "alignfull", "value": "", "priority": 34, "isStylePicker": false }, { "icon": "images/editor/bullist.gif", "command": "bullist", "alias": "bullist", "userInterface": "false", "frontEndCommand": "bullist", "value": "", "priority": 41, "isStylePicker": false }, { "icon": "images/editor/numlist.gif", "command": "numlist", "alias": "numlist", "userInterface": "false", "frontEndCommand": "numlist", "value": "", "priority": 42, "isStylePicker": false }, { "icon": "images/editor/outdent.gif", "command": "outdent", "alias": "outdent", "userInterface": "false", "frontEndCommand": "outdent", "value": "", "priority": 43, "isStylePicker": false }, { "icon": "images/editor/indent.gif", "command": "indent", "alias": "indent", "userInterface": "false", "frontEndCommand": "indent", "value": "", "priority": 44, "isStylePicker": false }, { "icon": "images/editor/link.gif", "command": "link", "alias": "mcelink", "userInterface": "true", "frontEndCommand": "link", "value": "", "priority": 51, "isStylePicker": false }, { "icon": "images/editor/unLink.gif", "command": "unlink", "alias": "unlink", "userInterface": "false", "frontEndCommand": "unlink", "value": "", "priority": 52, "isStylePicker": false }, { "icon": "images/editor/anchor.gif", "command": "anchor", "alias": "mceinsertanchor", "userInterface": "false", "frontEndCommand": "anchor", "value": "", "priority": 53, "isStylePicker": false }, { "icon": "images/editor/image.gif", "command": "image", "alias": "mceimage", "userInterface": "true", "frontEndCommand": "umbmediapicker", "value": "", "priority": 61, "isStylePicker": false }, { "icon": "images/editor/insMacro.gif", "command": "umbracomacro", "alias": "umbracomacro", "userInterface": "true", "frontEndCommand": "umbmacro", "value": "", "priority": 62, "isStylePicker": false }, { "icon": "images/editor/table.gif", "command": "table", "alias": "mceinserttable", "userInterface": "true", "frontEndCommand": "table", "value": "", "priority": 63, "isStylePicker": false }, { "icon": "images/editor/media.gif", "command": "umbracoembed", "alias": "umbracoembed", "userInterface": "true", "frontEndCommand": "umbembeddialog", "value": "", "priority": 66, "isStylePicker": false }, { "icon": "images/editor/hr.gif", "command": "hr", "alias": "inserthorizontalrule", "userInterface": "false", "frontEndCommand": "hr", "value": "", "priority": 71, "isStylePicker": false }, { "icon": "images/editor/sub.gif", "command": "sub", "alias": "subscript", "userInterface": "false", "frontEndCommand": "sub", "value": "", "priority": 72, "isStylePicker": false }, { "icon": "images/editor/sup.gif", "command": "sup", "alias": "superscript", "userInterface": "false", "frontEndCommand": "sup", "value": "", "priority": 73, "isStylePicker": false }, { "icon": "images/editor/charmap.gif", "command": "charmap", "alias": "mcecharmap", "userInterface": "false", "frontEndCommand": "charmap", "value": "", "priority": 74, "isStylePicker": false }], "validElements": "+a[id|style|rel|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],-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],-h2[id|dir|class|align],-h3[id|dir|class|align],-h4[id|dir|class|align],-h5[id|dir|class|align],-h6[id|style|dir|class|align],hr[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[*]", "inValidElements": "font", "customConfig": { "entity_encoding": "raw" } }, null]; - } - } + factory('prevaluesMocks', ['$httpBackend', 'mocksUtils', function ($httpBackend, mocksUtils) { + 'use strict'; - function getCanvasEditorConfiguration(status, data, headers){ - if (!mocksUtils.checkAuth()) { - return [401, null, null]; - } - else { - return [200, - [ - { - "name": "Rich text editor", - "alias": "rte", - "view": "rte", - "icon": "icon-article" - }, - { - "name": "Image", - "alias": "media", - "view": "media", - "icon": "icon-picture" - }, - { - "name": "Macro", - "alias": "macro", - "view": "macro", - "icon": "icon-settings-alt" - }, - { - "name": "Embed", - "alias": "embed", - "view": "embed", - "icon": "icon-movie-alt" - }, - { - "name": "Headline", - "alias": "headline", - "view": "textstring", - "icon": "icon-coin", - "config": { - "style": "font-size: 36px; line-height: 45px; font-weight: bold", - "markup": "

#value#

" - } - }, - { - "name": "Quote", - "alias": "quote", - "view": "textstring", - "icon": "icon-quote", - "config": { - "style": "border-left: 3px solid #ccc; padding: 10px; color: #ccc; font-family: serif; font-style: italic; font-size: 18px", - "markup": "
#value#
" - } - } - ], null]; - } - - } - - - return { - register: function() { - $httpBackend - .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/RichTextPreValue/GetConfiguration')) - .respond(getRichTextConfiguration); - $httpBackend - .whenGET(mocksUtils.urlRegex('../config/canvas.editors.config.js')) - .respond(getCanvasEditorConfiguration); - } - }; - }]); \ No newline at end of file + function getRichTextConfiguration(status, data, headers) { + if (!mocksUtils.checkAuth()) { + return [401, null, null]; + } + else { + return [200, { "plugins": [{ "name": "code", "useOnFrontend": true }, { "name": "paste", "useOnFrontend": true }, { "name": "umbracolink", "useOnFrontend": true }], "commands": [{ "icon": "images/editor/code.gif", "command": "code", "alias": "code", "frontEndCommand": "code", "value": "", "priority": 1, "isStylePicker": false }, { "icon": "images/editor/removeformat.gif", "command": "removeformat", "alias": "removeformat", "frontEndCommand": "removeformat", "value": "", "priority": 2, "isStylePicker": false }, { "icon": "images/editor/undo.gif", "command": "undo", "alias": "undo", "frontEndCommand": "undo", "value": "", "priority": 11, "isStylePicker": false }, { "icon": "images/editor/redo.gif", "command": "redo", "alias": "redo", "frontEndCommand": "redo", "value": "", "priority": 12, "isStylePicker": false }, { "icon": "images/editor/cut.gif", "command": "cut", "alias": "cut", "frontEndCommand": "cut", "value": "", "priority": 13, "isStylePicker": false }, { "icon": "images/editor/copy.gif", "command": "copy", "alias": "copy", "frontEndCommand": "copy", "value": "", "priority": 14, "isStylePicker": false }, { "icon": "images/editor/showStyles.png", "command": "styleselect", "alias": "styleselect", "frontEndCommand": "styleselect", "value": "", "priority": 20, "isStylePicker": false }, { "icon": "images/editor/bold.gif", "command": "bold", "alias": "bold", "frontEndCommand": "bold", "value": "", "priority": 21, "isStylePicker": false }, { "icon": "images/editor/italic.gif", "command": "italic", "alias": "italic", "frontEndCommand": "italic", "value": "", "priority": 22, "isStylePicker": false }, { "icon": "images/editor/underline.gif", "command": "underline", "alias": "underline", "frontEndCommand": "underline", "value": "", "priority": 23, "isStylePicker": false }, { "icon": "images/editor/strikethrough.gif", "command": "strikethrough", "alias": "strikethrough", "frontEndCommand": "strikethrough", "value": "", "priority": 24, "isStylePicker": false }, { "icon": "images/editor/justifyleft.gif", "command": "justifyleft", "alias": "justifyleft", "frontEndCommand": "alignleft", "value": "", "priority": 31, "isStylePicker": false }, { "icon": "images/editor/justifycenter.gif", "command": "justifycenter", "alias": "justifycenter", "frontEndCommand": "aligncenter", "value": "", "priority": 32, "isStylePicker": false }, { "icon": "images/editor/justifyright.gif", "command": "justifyright", "alias": "justifyright", "frontEndCommand": "alignright", "value": "", "priority": 33, "isStylePicker": false }, { "icon": "images/editor/justifyfull.gif", "command": "justifyfull", "alias": "justifyfull", "frontEndCommand": "alignfull", "value": "", "priority": 34, "isStylePicker": false }, { "icon": "images/editor/bullist.gif", "command": "bullist", "alias": "bullist", "frontEndCommand": "bullist", "value": "", "priority": 41, "isStylePicker": false }, { "icon": "images/editor/numlist.gif", "command": "numlist", "alias": "numlist", "frontEndCommand": "numlist", "value": "", "priority": 42, "isStylePicker": false }, { "icon": "images/editor/outdent.gif", "command": "outdent", "alias": "outdent", "frontEndCommand": "outdent", "value": "", "priority": 43, "isStylePicker": false }, { "icon": "images/editor/indent.gif", "command": "indent", "alias": "indent", "frontEndCommand": "indent", "value": "", "priority": 44, "isStylePicker": false }, { "icon": "images/editor/link.gif", "command": "link", "alias": "mcelink", "frontEndCommand": "link", "value": "", "priority": 51, "isStylePicker": false }, { "icon": "images/editor/unLink.gif", "command": "unlink", "alias": "unlink", "frontEndCommand": "unlink", "value": "", "priority": 52, "isStylePicker": false }, { "icon": "images/editor/anchor.gif", "command": "anchor", "alias": "mceinsertanchor", "frontEndCommand": "anchor", "value": "", "priority": 53, "isStylePicker": false }, { "icon": "images/editor/image.gif", "command": "image", "alias": "mceimage", "frontEndCommand": "umbmediapicker", "value": "", "priority": 61, "isStylePicker": false }, { "icon": "images/editor/insMacro.gif", "command": "umbracomacro", "alias": "umbracomacro", "frontEndCommand": "umbmacro", "value": "", "priority": 62, "isStylePicker": false }, { "icon": "images/editor/table.gif", "command": "table", "alias": "mceinserttable", "frontEndCommand": "table", "value": "", "priority": 63, "isStylePicker": false }, { "icon": "images/editor/media.gif", "command": "umbracoembed", "alias": "umbracoembed", "frontEndCommand": "umbembeddialog", "value": "", "priority": 66, "isStylePicker": false }, { "icon": "images/editor/hr.gif", "command": "hr", "alias": "inserthorizontalrule", "frontEndCommand": "hr", "value": "", "priority": 71, "isStylePicker": false }, { "icon": "images/editor/sub.gif", "command": "sub", "alias": "subscript", "frontEndCommand": "sub", "value": "", "priority": 72, "isStylePicker": false }, { "icon": "images/editor/sup.gif", "command": "sup", "alias": "superscript", "frontEndCommand": "sup", "value": "", "priority": 73, "isStylePicker": false }, { "icon": "images/editor/charmap.gif", "command": "charmap", "alias": "mcecharmap", "frontEndCommand": "charmap", "value": "", "priority": 74, "isStylePicker": false }], "validElements": "+a[id|style|rel|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],-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],-h2[id|dir|class|align],-h3[id|dir|class|align],-h4[id|dir|class|align],-h5[id|dir|class|align],-h6[id|style|dir|class|align],hr[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[*]", "inValidElements": "font", "customConfig": { "entity_encoding": "raw" } }, null]; + } + } + + function getCanvasEditorConfiguration(status, data, headers) { + if (!mocksUtils.checkAuth()) { + return [401, null, null]; + } + else { + return [200, + [ + { + "name": "Rich text editor", + "alias": "rte", + "view": "rte", + "icon": "icon-article" + }, + { + "name": "Image", + "alias": "media", + "view": "media", + "icon": "icon-picture" + }, + { + "name": "Macro", + "alias": "macro", + "view": "macro", + "icon": "icon-settings-alt" + }, + { + "name": "Embed", + "alias": "embed", + "view": "embed", + "icon": "icon-movie-alt" + }, + { + "name": "Headline", + "alias": "headline", + "view": "textstring", + "icon": "icon-coin", + "config": { + "style": "font-size: 36px; line-height: 45px; font-weight: bold", + "markup": "

#value#

" + } + }, + { + "name": "Quote", + "alias": "quote", + "view": "textstring", + "icon": "icon-quote", + "config": { + "style": "border-left: 3px solid #ccc; padding: 10px; color: #ccc; font-family: serif; font-style: italic; font-size: 18px", + "markup": "
#value#
" + } + } + ], null]; + } + + } + + + return { + register: function () { + $httpBackend + .whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/RichTextPreValue/GetConfiguration')) + .respond(getRichTextConfiguration); + $httpBackend + .whenGET(mocksUtils.urlRegex('../config/canvas.editors.config.js')) + .respond(getCanvasEditorConfiguration); + } + }; + }]); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index aa53626a78..2a6823528e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -7,7 +7,7 @@ * A service containing all logic for all of the Umbraco TinyMCE plugins */ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macroService, $routeParams, umbRequestHelper, angularHelper, userService) { - return { + return { /** * @ngdoc method @@ -18,16 +18,16 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * Returns a collection of plugins available to the tinyMCE editor * */ - configuration: function () { - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "rteApiBaseUrl", - "GetConfiguration"), { - cache: true - }), - 'Failed to retrieve tinymce configuration'); - }, + configuration: function () { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "rteApiBaseUrl", + "GetConfiguration"), { + cache: true + }), + 'Failed to retrieve tinymce configuration'); + }, /** * @ngdoc method @@ -38,16 +38,16 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * Returns a default configration to fallback on in case none is provided * */ - defaultPrevalues: function () { - var cfg = {}; - cfg.toolbar = ["code", "bold", "italic", "styleselect", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link", "image", "umbmediapicker", "umbembeddialog", "umbmacro"]; - cfg.stylesheets = []; - cfg.dimensions = { - height: 500 - }; - cfg.maxImageSize = 500; - return cfg; - }, + defaultPrevalues: function () { + var cfg = {}; + cfg.toolbar = ["code", "bold", "italic", "styleselect", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link", "image", "umbmediapicker", "umbembeddialog", "umbmacro"]; + cfg.stylesheets = []; + cfg.dimensions = { + height: 500 + }; + cfg.maxImageSize = 500; + return cfg; + }, /** * @ngdoc method @@ -60,21 +60,23 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * @param {Object} editor the TinyMCE editor instance * @param {Object} $scope the current controller scope */ - createInsertEmbeddedMedia: function (editor, scope, callback) { - editor.addButton('umbembeddialog', { - icon: 'custom icon-tv', - tooltip: 'Embed', - onclick: function () { - if (callback) { - callback(); - } - } - }); - }, + createInsertEmbeddedMedia: function (editor, $scope, callback) { + editor.addButton('umbembeddialog', { + icon: 'custom icon-tv', + tooltip: 'Embed', + onclick: function () { + if (callback) { + angularHelper.safeApply($scope, function() { + callback(); + }); + } + } + }); + }, - insertEmbeddedMediaInEditor: function (editor, preview) { - editor.insertContent(preview); - }, + insertEmbeddedMediaInEditor: function (editor, preview) { + editor.insertContent(preview); + }, /** * @ngdoc method @@ -87,85 +89,86 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * @param {Object} editor the TinyMCE editor instance * @param {Object} $scope the current controller scope */ - createMediaPicker: function (editor, scope, callback) { - editor.addButton('umbmediapicker', { - icon: 'custom icon-picture', - tooltip: 'Media Picker', - stateSelector: 'img', - onclick: function () { - - var selectedElm = editor.selection.getNode(), - currentTarget; + createMediaPicker: function (editor, $scope, callback) { + editor.addButton('umbmediapicker', { + icon: 'custom icon-picture', + tooltip: 'Media Picker', + stateSelector: 'img', + onclick: function () { - if (selectedElm.nodeName === 'IMG') { - var img = $(selectedElm); + var selectedElm = editor.selection.getNode(), + currentTarget; - var hasUdi = img.attr("data-udi") ? true : false; + if (selectedElm.nodeName === 'IMG') { + var img = $(selectedElm); - currentTarget = { - altText: img.attr("alt"), - url: img.attr("src") - }; + var hasUdi = img.attr("data-udi") ? true : false; - if (hasUdi) { - currentTarget["udi"] = img.attr("data-udi"); - } else { - currentTarget["id"] = img.attr("rel"); - } - } + currentTarget = { + altText: img.attr("alt"), + url: img.attr("src") + }; - userService.getCurrentUser().then(function (userData) { - if (callback) { - callback(currentTarget, userData); - } - }); + if (hasUdi) { + currentTarget["udi"] = img.attr("data-udi"); + } else { + currentTarget["id"] = img.attr("rel"); + } + } - } - }); - }, + userService.getCurrentUser().then(function (userData) { + if (callback) { + angularHelper.safeApply($scope, function() { + callback(currentTarget, userData); + }); + } + }); + } + }); + }, - insertMediaInEditor: function (editor, img) { - if (img) { + insertMediaInEditor: function (editor, img) { + if (img) { - var hasUdi = img.udi ? true : false; + var hasUdi = img.udi ? true : false; - var data = { - alt: img.altText || "", - src: (img.url) ? img.url : "nothing.jpg", - id: '__mcenew' - }; + var data = { + alt: img.altText || "", + src: (img.url) ? img.url : "nothing.jpg", + id: '__mcenew' + }; - if (hasUdi) { - data["data-udi"] = img.udi; - } else { - //Considering these fixed because UDI will now be used and thus - // we have no need for rel http://issues.umbraco.org/issue/U4-6228, http://issues.umbraco.org/issue/U4-6595 - data["rel"] = img.id; - data["data-id"] = img.id; - } + if (hasUdi) { + data["data-udi"] = img.udi; + } else { + //Considering these fixed because UDI will now be used and thus + // we have no need for rel http://issues.umbraco.org/issue/U4-6228, http://issues.umbraco.org/issue/U4-6595 + data["rel"] = img.id; + data["data-id"] = img.id; + } - editor.insertContent(editor.dom.createHTML('img', data)); + editor.insertContent(editor.dom.createHTML('img', data)); - $timeout(function () { - var imgElm = editor.dom.get('__mcenew'); - var size = editor.dom.getSize(imgElm); + $timeout(function () { + var imgElm = editor.dom.get('__mcenew'); + var size = editor.dom.getSize(imgElm); - if (editor.settings.maxImageSize && editor.settings.maxImageSize !== 0) { - var newSize = imageHelper.scaleToMaxSize(editor.settings.maxImageSize, size.w, size.h); + if (editor.settings.maxImageSize && editor.settings.maxImageSize !== 0) { + var newSize = imageHelper.scaleToMaxSize(editor.settings.maxImageSize, size.w, size.h); - var s = "width: " + newSize.width + "px; height:" + newSize.height + "px;"; - editor.dom.setAttrib(imgElm, 'style', s); - editor.dom.setAttrib(imgElm, 'id', null); + var s = "width: " + newSize.width + "px; height:" + newSize.height + "px;"; + editor.dom.setAttrib(imgElm, 'style', s); + editor.dom.setAttrib(imgElm, 'id', null); - if (img.url) { - var src = img.url + "?width=" + newSize.width + "&height=" + newSize.height; - editor.dom.setAttrib(imgElm, 'data-mce-src', src); - } - } - }, 500); - } - }, + if (img.url) { + var src = img.url + "?width=" + newSize.width + "&height=" + newSize.height; + editor.dom.setAttrib(imgElm, 'data-mce-src', src); + } + } + }, 500); + } + }, /** * @ngdoc method @@ -178,104 +181,104 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * @param {Object} editor the TinyMCE editor instance * @param {Object} $scope the current controller scope */ - createInsertMacro: function (editor, $scope, callback) { + createInsertMacro: function (editor, $scope, callback) { - var createInsertMacroScope = this; + var createInsertMacroScope = this; - /** Adds custom rules for the macro plugin and custom serialization */ - editor.on('preInit', function (args) { - //this is requires so that we tell the serializer that a 'div' is actually allowed in the root, otherwise the cleanup will strip it out - editor.serializer.addRules('div'); + /** Adds custom rules for the macro plugin and custom serialization */ + editor.on('preInit', function (args) { + //this is requires so that we tell the serializer that a 'div' is actually allowed in the root, otherwise the cleanup will strip it out + editor.serializer.addRules('div'); - /** This checks if the div is a macro container, if so, checks if its wrapped in a p tag and then unwraps it (removes p tag) */ - editor.serializer.addNodeFilter('div', function (nodes, name) { - for (var i = 0; i < nodes.length; i++) { - if (nodes[i].attr("class") === "umb-macro-holder" && nodes[i].parent && nodes[i].parent.name.toUpperCase() === "P") { - nodes[i].parent.unwrap(); - } - } - }); + /** This checks if the div is a macro container, if so, checks if its wrapped in a p tag and then unwraps it (removes p tag) */ + editor.serializer.addNodeFilter('div', function (nodes, name) { + for (var i = 0; i < nodes.length; i++) { + if (nodes[i].attr("class") === "umb-macro-holder" && nodes[i].parent && nodes[i].parent.name.toUpperCase() === "P") { + nodes[i].parent.unwrap(); + } + } + }); - }); + }); /** * Because the macro gets wrapped in a P tag because of the way 'enter' works, this * method will return the macro element if not wrapped in a p, or the p if the macro * element is the only one inside of it even if we are deep inside an element inside the macro */ - function getRealMacroElem(element) { - var e = $(element).closest(".umb-macro-holder"); - if (e.length > 0) { - if (e.get(0).parentNode.nodeName === "P") { - //now check if we're the only element - if (element.parentNode.childNodes.length === 1) { - return e.get(0).parentNode; - } - } - return e.get(0); - } - return null; - } + function getRealMacroElem(element) { + var e = $(element).closest(".umb-macro-holder"); + if (e.length > 0) { + if (e.get(0).parentNode.nodeName === "P") { + //now check if we're the only element + if (element.parentNode.childNodes.length === 1) { + return e.get(0).parentNode; + } + } + return e.get(0); + } + return null; + } - /** Adds the button instance */ - editor.addButton('umbmacro', { - icon: 'custom icon-settings-alt', - tooltip: 'Insert macro', - onPostRender: function () { + /** Adds the button instance */ + editor.addButton('umbmacro', { + icon: 'custom icon-settings-alt', + tooltip: 'Insert macro', + onPostRender: function () { - var ctrl = this; - var isOnMacroElement = false; + var ctrl = this; + var isOnMacroElement = false; /** if the selection comes from a different element that is not the macro's we need to check if the selection includes part of the macro, if so we'll force the selection to clear to the next element since if people can select part of the macro markup they can then modify it. */ - function handleSelectionChange() { + function handleSelectionChange() { - if (!editor.selection.isCollapsed()) { - var endSelection = tinymce.activeEditor.selection.getEnd(); - var startSelection = tinymce.activeEditor.selection.getStart(); - //don't proceed if it's an entire element selected - if (endSelection !== startSelection) { + if (!editor.selection.isCollapsed()) { + var endSelection = tinymce.activeEditor.selection.getEnd(); + var startSelection = tinymce.activeEditor.selection.getStart(); + //don't proceed if it's an entire element selected + if (endSelection !== startSelection) { - //if the end selection is a macro then move the cursor - //NOTE: we don't have to handle when the selection comes from a previous parent because - // that is automatically taken care of with the normal onNodeChanged logic since the - // evt.element will be the macro once it becomes part of the selection. - var $testForMacro = $(endSelection).closest(".umb-macro-holder"); - if ($testForMacro.length > 0) { + //if the end selection is a macro then move the cursor + //NOTE: we don't have to handle when the selection comes from a previous parent because + // that is automatically taken care of with the normal onNodeChanged logic since the + // evt.element will be the macro once it becomes part of the selection. + var $testForMacro = $(endSelection).closest(".umb-macro-holder"); + if ($testForMacro.length > 0) { - //it came from before so move after, if there is no after then select ourselves - var next = $testForMacro.next(); - if (next.length > 0) { - editor.selection.setCursorLocation($testForMacro.next().get(0)); - } else { - selectMacroElement($testForMacro.get(0)); - } + //it came from before so move after, if there is no after then select ourselves + var next = $testForMacro.next(); + if (next.length > 0) { + editor.selection.setCursorLocation($testForMacro.next().get(0)); + } else { + selectMacroElement($testForMacro.get(0)); + } - } - } - } - } + } + } + } + } - /** helper method to select the macro element */ - function selectMacroElement(macroElement) { + /** helper method to select the macro element */ + function selectMacroElement(macroElement) { - // move selection to top element to ensure we can't edit this - editor.selection.select(macroElement); + // move selection to top element to ensure we can't edit this + editor.selection.select(macroElement); - // check if the current selection *is* the element (ie bug) - var currentSelection = editor.selection.getStart(); - if (tinymce.isIE) { - if (!editor.dom.hasClass(currentSelection, 'umb-macro-holder')) { - while (!editor.dom.hasClass(currentSelection, 'umb-macro-holder') && currentSelection.parentNode) { - currentSelection = currentSelection.parentNode; - } - editor.selection.select(currentSelection); - } - } - } + // check if the current selection *is* the element (ie bug) + var currentSelection = editor.selection.getStart(); + if (tinymce.isIE) { + if (!editor.dom.hasClass(currentSelection, 'umb-macro-holder')) { + while (!editor.dom.hasClass(currentSelection, 'umb-macro-holder') && currentSelection.parentNode) { + currentSelection = currentSelection.parentNode; + } + editor.selection.select(currentSelection); + } + } + } /** * Add a node change handler, test if we're editing a macro and select the whole thing, then set our isOnMacroElement flag. @@ -283,471 +286,474 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * from the event listener before changing selection, however, it seems that putting a break point in this method * will always cause an 'infinite' loop as the caret keeps changing. */ - function onNodeChanged(evt) { + function onNodeChanged(evt) { - //set our macro button active when on a node of class umb-macro-holder - var $macroElement = $(evt.element).closest(".umb-macro-holder"); + //set our macro button active when on a node of class umb-macro-holder + var $macroElement = $(evt.element).closest(".umb-macro-holder"); - handleSelectionChange(); + handleSelectionChange(); - //set the button active - ctrl.active($macroElement.length !== 0); + //set the button active + ctrl.active($macroElement.length !== 0); - if ($macroElement.length > 0) { - var macroElement = $macroElement.get(0); + if ($macroElement.length > 0) { + var macroElement = $macroElement.get(0); - //remove the event listener before re-selecting - editor.off('NodeChange', onNodeChanged); + //remove the event listener before re-selecting + editor.off('NodeChange', onNodeChanged); - selectMacroElement(macroElement); + selectMacroElement(macroElement); - //set the flag - isOnMacroElement = true; + //set the flag + isOnMacroElement = true; - //re-add the event listener - editor.on('NodeChange', onNodeChanged); - } else { - isOnMacroElement = false; - } + //re-add the event listener + editor.on('NodeChange', onNodeChanged); + } else { + isOnMacroElement = false; + } - } + } - /** when the contents load we need to find any macros declared and load in their content */ - editor.on("LoadContent", function (o) { + /** when the contents load we need to find any macros declared and load in their content */ + editor.on("LoadContent", function (o) { - //get all macro divs and load their content - $(editor.dom.select(".umb-macro-holder.mceNonEditable")).each(function () { - createInsertMacroScope.loadMacroContent($(this), null, $scope); - }); + //get all macro divs and load their content + $(editor.dom.select(".umb-macro-holder.mceNonEditable")).each(function () { + createInsertMacroScope.loadMacroContent($(this), null, $scope); + }); - }); + }); - /** This prevents any other commands from executing when the current element is the macro so the content cannot be edited */ - editor.on('BeforeExecCommand', function (o) { - if (isOnMacroElement) { - if (o.preventDefault) { - o.preventDefault(); - } - if (o.stopImmediatePropagation) { - o.stopImmediatePropagation(); - } - return; - } - }); + /** This prevents any other commands from executing when the current element is the macro so the content cannot be edited */ + editor.on('BeforeExecCommand', function (o) { + if (isOnMacroElement) { + if (o.preventDefault) { + o.preventDefault(); + } + if (o.stopImmediatePropagation) { + o.stopImmediatePropagation(); + } + return; + } + }); - /** This double checks and ensures you can't paste content into the rendered macro */ - editor.on("Paste", function (o) { - if (isOnMacroElement) { - if (o.preventDefault) { - o.preventDefault(); - } - if (o.stopImmediatePropagation) { - o.stopImmediatePropagation(); - } - return; - } - }); + /** This double checks and ensures you can't paste content into the rendered macro */ + editor.on("Paste", function (o) { + if (isOnMacroElement) { + if (o.preventDefault) { + o.preventDefault(); + } + if (o.stopImmediatePropagation) { + o.stopImmediatePropagation(); + } + return; + } + }); - //set onNodeChanged event listener - editor.on('NodeChange', onNodeChanged); + //set onNodeChanged event listener + editor.on('NodeChange', onNodeChanged); /** * Listen for the keydown in the editor, we'll check if we are currently on a macro element, if so * we'll check if the key down is a supported key which requires an action, otherwise we ignore the request * so the macro cannot be edited. */ - editor.on('KeyDown', function (e) { - if (isOnMacroElement) { - var macroElement = editor.selection.getNode(); + editor.on('KeyDown', function (e) { + if (isOnMacroElement) { + var macroElement = editor.selection.getNode(); - //get the 'real' element (either p or the real one) - macroElement = getRealMacroElem(macroElement); + //get the 'real' element (either p or the real one) + macroElement = getRealMacroElem(macroElement); - //prevent editing - e.preventDefault(); - e.stopPropagation(); + //prevent editing + e.preventDefault(); + e.stopPropagation(); - var moveSibling = function (element, isNext) { - var $e = $(element); - var $sibling = isNext ? $e.next() : $e.prev(); - if ($sibling.length > 0) { - editor.selection.select($sibling.get(0)); - editor.selection.collapse(true); - } else { - //if we're moving previous and there is no sibling, then lets recurse and just select the next one - if (!isNext) { - moveSibling(element, true); - return; - } + var moveSibling = function (element, isNext) { + var $e = $(element); + var $sibling = isNext ? $e.next() : $e.prev(); + if ($sibling.length > 0) { + editor.selection.select($sibling.get(0)); + editor.selection.collapse(true); + } else { + //if we're moving previous and there is no sibling, then lets recurse and just select the next one + if (!isNext) { + moveSibling(element, true); + return; + } - //if there is no sibling we'll generate a new p at the end and select it - editor.setContent(editor.getContent() + "

 

"); - editor.selection.select($(editor.dom.getRoot()).children().last().get(0)); - editor.selection.collapse(true); + //if there is no sibling we'll generate a new p at the end and select it + editor.setContent(editor.getContent() + "

 

"); + editor.selection.select($(editor.dom.getRoot()).children().last().get(0)); + editor.selection.collapse(true); - } - }; + } + }; - //supported keys to move to the next or prev element (13-enter, 27-esc, 38-up, 40-down, 39-right, 37-left) - //supported keys to remove the macro (8-backspace, 46-delete) - //TODO: Should we make the enter key insert a line break before or leave it as moving to the next element? - if ($.inArray(e.keyCode, [13, 40, 39]) !== -1) { - //move to next element - moveSibling(macroElement, true); - } else if ($.inArray(e.keyCode, [27, 38, 37]) !== -1) { - //move to prev element - moveSibling(macroElement, false); - } else if ($.inArray(e.keyCode, [8, 46]) !== -1) { - //delete macro element + //supported keys to move to the next or prev element (13-enter, 27-esc, 38-up, 40-down, 39-right, 37-left) + //supported keys to remove the macro (8-backspace, 46-delete) + //TODO: Should we make the enter key insert a line break before or leave it as moving to the next element? + if ($.inArray(e.keyCode, [13, 40, 39]) !== -1) { + //move to next element + moveSibling(macroElement, true); + } else if ($.inArray(e.keyCode, [27, 38, 37]) !== -1) { + //move to prev element + moveSibling(macroElement, false); + } else if ($.inArray(e.keyCode, [8, 46]) !== -1) { + //delete macro element - //move first, then delete - moveSibling(macroElement, false); - editor.dom.remove(macroElement); - } - return; - } - }); + //move first, then delete + moveSibling(macroElement, false); + editor.dom.remove(macroElement); + } + return; + } + }); - }, + }, - /** The insert macro button click event handler */ - onclick: function () { + /** The insert macro button click event handler */ + onclick: function () { - var dialogData = { - //flag for use in rte so we only show macros flagged for the editor - richTextEditor: true - }; + var dialogData = { + //flag for use in rte so we only show macros flagged for the editor + richTextEditor: true + }; - //when we click we could have a macro already selected and in that case we'll want to edit the current parameters - //so we'll need to extract them and submit them to the dialog. - var macroElement = editor.selection.getNode(); - macroElement = getRealMacroElem(macroElement); - if (macroElement) { - //we have a macro selected so we'll need to parse it's alias and parameters - var contents = $(macroElement).contents(); - var comment = _.find(contents, function (item) { - return item.nodeType === 8; - }); - if (!comment) { - throw "Cannot parse the current macro, the syntax in the editor is invalid"; - } - var syntax = comment.textContent.trim(); - var parsed = macroService.parseMacroSyntax(syntax); - dialogData = { - macroData: parsed - }; - } + //when we click we could have a macro already selected and in that case we'll want to edit the current parameters + //so we'll need to extract them and submit them to the dialog. + var macroElement = editor.selection.getNode(); + macroElement = getRealMacroElem(macroElement); + if (macroElement) { + //we have a macro selected so we'll need to parse it's alias and parameters + var contents = $(macroElement).contents(); + var comment = _.find(contents, function (item) { + return item.nodeType === 8; + }); + if (!comment) { + throw "Cannot parse the current macro, the syntax in the editor is invalid"; + } + var syntax = comment.textContent.trim(); + var parsed = macroService.parseMacroSyntax(syntax); + dialogData = { + macroData: parsed + }; + } - if (callback) { - callback(dialogData); - } + if (callback) { + angularHelper.safeApply($scope, function () { + callback(dialogData); + }); + } + } + }); + }, - } - }); - }, + insertMacroInEditor: function (editor, macroObject, $scope) { - insertMacroInEditor: function (editor, macroObject, $scope) { + //put the macro syntax in comments, we will parse this out on the server side to be used + //for persisting. + var macroSyntaxComment = ""; + //create an id class for this element so we can re-select it after inserting + var uniqueId = "umb-macro-" + editor.dom.uniqueId(); + var macroDiv = editor.dom.create('div', { + 'class': 'umb-macro-holder ' + macroObject.macroAlias + ' mceNonEditable ' + uniqueId + }, + macroSyntaxComment + 'Macro alias: ' + macroObject.macroAlias + ''); - //put the macro syntax in comments, we will parse this out on the server side to be used - //for persisting. - var macroSyntaxComment = ""; - //create an id class for this element so we can re-select it after inserting - var uniqueId = "umb-macro-" + editor.dom.uniqueId(); - var macroDiv = editor.dom.create('div', { - 'class': 'umb-macro-holder ' + macroObject.macroAlias + ' mceNonEditable ' + uniqueId - }, - macroSyntaxComment + 'Macro alias: ' + macroObject.macroAlias + ''); + editor.selection.setNode(macroDiv); - editor.selection.setNode(macroDiv); + var $macroDiv = $(editor.dom.select("div.umb-macro-holder." + uniqueId)); - var $macroDiv = $(editor.dom.select("div.umb-macro-holder." + uniqueId)); + //async load the macro content + this.loadMacroContent($macroDiv, macroObject, $scope); - //async load the macro content - this.loadMacroContent($macroDiv, macroObject, $scope); + }, - }, + /** loads in the macro content async from the server */ + loadMacroContent: function ($macroDiv, macroData, $scope) { - /** loads in the macro content async from the server */ - loadMacroContent: function ($macroDiv, macroData, $scope) { + //if we don't have the macroData, then we'll need to parse it from the macro div + if (!macroData) { + var contents = $macroDiv.contents(); + var comment = _.find(contents, function (item) { + return item.nodeType === 8; + }); + if (!comment) { + throw "Cannot parse the current macro, the syntax in the editor is invalid"; + } + var syntax = comment.textContent.trim(); + var parsed = macroService.parseMacroSyntax(syntax); + macroData = parsed; + } - //if we don't have the macroData, then we'll need to parse it from the macro div - if (!macroData) { - var contents = $macroDiv.contents(); - var comment = _.find(contents, function (item) { - return item.nodeType === 8; - }); - if (!comment) { - throw "Cannot parse the current macro, the syntax in the editor is invalid"; - } - var syntax = comment.textContent.trim(); - var parsed = macroService.parseMacroSyntax(syntax); - macroData = parsed; - } + var $ins = $macroDiv.find("ins"); - var $ins = $macroDiv.find("ins"); + //show the throbber + $macroDiv.addClass("loading"); - //show the throbber - $macroDiv.addClass("loading"); + var contentId = $routeParams.id; - var contentId = $routeParams.id; + //need to wrap in safe apply since this might be occuring outside of angular + angularHelper.safeApply($scope, function () { + macroResource.getMacroResultAsHtmlForEditor(macroData.macroAlias, contentId, macroData.macroParamsDictionary) + .then(function (htmlResult) { - //need to wrap in safe apply since this might be occuring outside of angular - angularHelper.safeApply($scope, function () { - macroResource.getMacroResultAsHtmlForEditor(macroData.macroAlias, contentId, macroData.macroParamsDictionary) - .then(function (htmlResult) { + $macroDiv.removeClass("loading"); + htmlResult = htmlResult.trim(); + if (htmlResult !== "") { + $ins.html(htmlResult); + } + }); + }); - $macroDiv.removeClass("loading"); - htmlResult = htmlResult.trim(); - if (htmlResult !== "") { - $ins.html(htmlResult); - } - }); - }); + }, - }, + createLinkPicker: function (editor, $scope, onClick) { - createLinkPicker: function (editor, $scope, onClick) { + function createLinkList(callback) { + return function () { + var linkList = editor.settings.link_list; - function createLinkList(callback) { - return function () { - var linkList = editor.settings.link_list; + if (typeof (linkList) === "string") { + tinymce.util.XHR.send({ + url: linkList, + success: function (text) { + callback(tinymce.util.JSON.parse(text)); + } + }); + } else { + callback(linkList); + } + }; + } - if (typeof (linkList) === "string") { - tinymce.util.XHR.send({ - url: linkList, - success: function (text) { - callback(tinymce.util.JSON.parse(text)); - } - }); - } else { - callback(linkList); - } - }; - } + function showDialog(linkList) { + var data = {}, + selection = editor.selection, + dom = editor.dom, + selectedElm, anchorElm, initialText; + var win, linkListCtrl, relListCtrl, targetListCtrl; - function showDialog(linkList) { - var data = {}, - selection = editor.selection, - dom = editor.dom, - selectedElm, anchorElm, initialText; - var win, linkListCtrl, relListCtrl, targetListCtrl; + function linkListChangeHandler(e) { + var textCtrl = win.find('#text'); - function linkListChangeHandler(e) { - var textCtrl = win.find('#text'); + if (!textCtrl.value() || (e.lastControl && textCtrl.value() === e.lastControl.text())) { + textCtrl.value(e.control.text()); + } - if (!textCtrl.value() || (e.lastControl && textCtrl.value() === e.lastControl.text())) { - textCtrl.value(e.control.text()); - } + win.find('#href').value(e.control.value()); + } - win.find('#href').value(e.control.value()); - } - - function buildLinkList() { - var linkListItems = [{ - text: 'None', - value: '' + function buildLinkList() { + var linkListItems = [{ + text: 'None', + value: '' }]; - tinymce.each(linkList, function (link) { - linkListItems.push({ - text: link.text || link.title, - value: link.value || link.url, - menu: link.menu - }); - }); + tinymce.each(linkList, function (link) { + linkListItems.push({ + text: link.text || link.title, + value: link.value || link.url, + menu: link.menu + }); + }); - return linkListItems; - } + return linkListItems; + } - function buildRelList(relValue) { - var relListItems = [{ - text: 'None', - value: '' + function buildRelList(relValue) { + var relListItems = [{ + text: 'None', + value: '' }]; - tinymce.each(editor.settings.rel_list, function (rel) { - relListItems.push({ - text: rel.text || rel.title, - value: rel.value, - selected: relValue === rel.value - }); - }); + tinymce.each(editor.settings.rel_list, function (rel) { + relListItems.push({ + text: rel.text || rel.title, + value: rel.value, + selected: relValue === rel.value + }); + }); - return relListItems; - } + return relListItems; + } - function buildTargetList(targetValue) { - var targetListItems = [{ - text: 'None', - value: '' + function buildTargetList(targetValue) { + var targetListItems = [{ + text: 'None', + value: '' }]; - if (!editor.settings.target_list) { - targetListItems.push({ - text: 'New window', - value: '_blank' - }); - } + if (!editor.settings.target_list) { + targetListItems.push({ + text: 'New window', + value: '_blank' + }); + } - tinymce.each(editor.settings.target_list, function (target) { - targetListItems.push({ - text: target.text || target.title, - value: target.value, - selected: targetValue === target.value - }); - }); + tinymce.each(editor.settings.target_list, function (target) { + targetListItems.push({ + text: target.text || target.title, + value: target.value, + selected: targetValue === target.value + }); + }); - return targetListItems; - } + return targetListItems; + } - function buildAnchorListControl(url) { - var anchorList = []; + function buildAnchorListControl(url) { + var anchorList = []; - tinymce.each(editor.dom.select('a:not([href])'), function (anchor) { - var id = anchor.name || anchor.id; + 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 (id) { + anchorList.push({ + text: id, + value: '#' + id, + selected: url.indexOf('#' + id) !== -1 + }); + } + }); - if (anchorList.length) { - anchorList.unshift({ - text: 'None', - value: '' - }); + if (anchorList.length) { + anchorList.unshift({ + text: 'None', + value: '' + }); - return { - name: 'anchor', - type: 'listbox', - label: 'Anchors', - values: anchorList, - onselect: linkListChangeHandler - }; - } - } + 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()); - } - } + 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]'); + selectedElm = selection.getNode(); + anchorElm = dom.getParent(selectedElm, 'a[href]'); - data.text = initialText = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({ - format: 'text' - }); - data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : ''; - data.target = anchorElm ? dom.getAttrib(anchorElm, 'target') : ''; - data.rel = anchorElm ? dom.getAttrib(anchorElm, 'rel') : ''; + data.text = initialText = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({ + format: 'text' + }); + data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : ''; + data.target = anchorElm ? dom.getAttrib(anchorElm, 'target') : ''; + data.rel = anchorElm ? dom.getAttrib(anchorElm, 'rel') : ''; - if (selectedElm.nodeName === "IMG") { - data.text = initialText = " "; - } + if (selectedElm.nodeName === "IMG") { + data.text = initialText = " "; + } - if (linkList) { - linkListCtrl = { - type: 'listbox', - label: 'Link list', - values: buildLinkList(), - onselect: linkListChangeHandler - }; - } + if (linkList) { + linkListCtrl = { + type: 'listbox', + label: 'Link list', + values: buildLinkList(), + onselect: linkListChangeHandler + }; + } - if (editor.settings.target_list !== false) { - targetListCtrl = { - name: 'target', - type: 'listbox', - label: 'Target', - values: buildTargetList(data.target) - }; - } + if (editor.settings.target_list !== false) { + targetListCtrl = { + name: 'target', + type: 'listbox', + label: 'Target', + values: buildTargetList(data.target) + }; + } - if (editor.settings.rel_list) { - relListCtrl = { - name: 'rel', - type: 'listbox', - label: 'Rel', - values: buildRelList(data.rel) - }; - } + if (editor.settings.rel_list) { + relListCtrl = { + name: 'rel', + type: 'listbox', + label: 'Rel', + values: buildRelList(data.rel) + }; + } - var currentTarget = null; + var currentTarget = null; - //if we already have a link selected, we want to pass that data over to the dialog - if (anchorElm) { - var anchor = $(anchorElm); - currentTarget = { - name: anchor.attr("title"), - url: anchor.attr("href"), - target: anchor.attr("target") - }; + //if we already have a link selected, we want to pass that data over to the dialog + if (anchorElm) { + var anchor = $(anchorElm); + currentTarget = { + name: anchor.attr("title"), + url: anchor.attr("href"), + target: anchor.attr("target") + }; - // drop the lead char from the anchor text, if it has a value - var anchorVal = anchor[0].dataset.anchor; - if (anchorVal) { - currentTarget.anchor = anchorVal.substring(1); - } + // drop the lead char from the anchor text, if it has a value + var anchorVal = anchor[0].dataset.anchor; + if (anchorVal) { + currentTarget.anchor = anchorVal.substring(1); + } - //locallink detection, we do this here, to avoid poluting the dialogservice - //so the dialog service can just expect to get a node-like structure - if (currentTarget.url.indexOf("localLink:") > 0) { - // if the current link has an anchor, it needs to be considered when getting the udi/id - // if an anchor exists, reduce the substring max by its length plus two to offset the removed prefix and trailing curly brace - var linkId = currentTarget.url.substring(currentTarget.url.indexOf(":") + 1, currentTarget.url.lastIndexOf("}")); + //locallink detection, we do this here, to avoid poluting the dialogservice + //so the dialog service can just expect to get a node-like structure + if (currentTarget.url.indexOf("localLink:") > 0) { + // if the current link has an anchor, it needs to be considered when getting the udi/id + // if an anchor exists, reduce the substring max by its length plus two to offset the removed prefix and trailing curly brace + var linkId = currentTarget.url.substring(currentTarget.url.indexOf(":") + 1, currentTarget.url.lastIndexOf("}")); - //we need to check if this is an INT or a UDI - var parsedIntId = parseInt(linkId, 10); - if (isNaN(parsedIntId)) { - //it's a UDI - currentTarget.udi = linkId; - } else { - currentTarget.id = linkId; - } - } - } + //we need to check if this is an INT or a UDI + var parsedIntId = parseInt(linkId, 10); + if (isNaN(parsedIntId)) { + //it's a UDI + currentTarget.udi = linkId; + } else { + currentTarget.id = linkId; + } + } + } - if (onClick) { - onClick(currentTarget, anchorElm); - } + angularHelper.safeApply($scope, + function () { + if (onClick) { + onClick(currentTarget, anchorElm); + } + }); + } - } + editor.addButton('link', { + icon: 'link', + tooltip: 'Insert/edit link', + shortcut: 'Ctrl+K', + onclick: createLinkList(showDialog), + stateSelector: 'a[href]' + }); - editor.addButton('link', { - icon: 'link', - tooltip: 'Insert/edit link', - shortcut: 'Ctrl+K', - onclick: createLinkList(showDialog), - stateSelector: 'a[href]' - }); + editor.addButton('unlink', { + icon: 'unlink', + tooltip: 'Remove link', + cmd: 'unlink', + stateSelector: 'a[href]' + }); - editor.addButton('unlink', { - icon: 'unlink', - tooltip: 'Remove link', - cmd: 'unlink', - stateSelector: 'a[href]' - }); + editor.addShortcut('Ctrl+K', '', createLinkList(showDialog)); + this.showDialog = showDialog; - editor.addShortcut('Ctrl+K', '', createLinkList(showDialog)); - this.showDialog = showDialog; + editor.addMenuItem('link', { + icon: 'link', + text: 'Insert link', + shortcut: 'Ctrl+K', + onclick: createLinkList(showDialog), + stateSelector: 'a[href]', + context: 'insert', + prependToContext: true + }); - editor.addMenuItem('link', { - icon: 'link', - text: 'Insert link', - shortcut: 'Ctrl+K', - onclick: createLinkList(showDialog), - stateSelector: 'a[href]', - context: 'insert', - prependToContext: true - }); - - }, + }, /** * @ngdoc method @@ -760,116 +766,116 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * * @param {string} input the string to parse */ - getAnchorNames: function (input) { + getAnchorNames: function (input) { var anchors = []; if (!input) { return anchors; } - - var anchorPattern = //gi; - var matches = input.match(anchorPattern); - - if (matches) { - anchors = matches.map(function (v) { - return v.substring(v.indexOf('"') + 1, v.lastIndexOf('\\')); - }); - } + var anchorPattern = //gi; + var matches = input.match(anchorPattern); - return anchors; - }, - insertLinkInEditor: function (editor, target, anchorElm) { + if (matches) { + anchors = matches.map(function (v) { + return v.substring(v.indexOf('"') + 1, v.lastIndexOf('\\')); + }); + } - var href = target.url; - // We want to use the Udi. If it is set, we use it, else fallback to id, and finally to null - var hasUdi = target.udi ? true : false; - var id = hasUdi ? target.udi : (target.id ? target.id : null); + return anchors; + }, - // if an anchor exists, check that it is appropriately prefixed - if (target.anchor && target.anchor[0] !== '?' && target.anchor[0] !== '#') { - target.anchor = (target.anchor.indexOf('=') === -1 ? '#' : '?') + target.anchor; - } - - // the href might be an external url, so check the value for an anchor/qs - // href has the anchor re-appended later, hence the reset here to avoid duplicating the anchor - if (!target.anchor) { - var urlParts = href.split(/(#|\?)/); - if (urlParts.length === 3) { - href = urlParts[0]; - target.anchor = urlParts[1] + urlParts[2]; - } - } - - //Create a json obj used to create the attributes for the tag - function createElemAttributes() { - var a = { - href: href, - title: target.name, - target: target.target ? target.target : null, - rel: target.rel ? target.rel : null - }; + insertLinkInEditor: function (editor, target, anchorElm) { - if (hasUdi) { - a["data-udi"] = target.udi; - } else if (target.id) { - a["data-id"] = target.id; - } + var href = target.url; + // We want to use the Udi. If it is set, we use it, else fallback to id, and finally to null + var hasUdi = target.udi ? true : false; + var id = hasUdi ? target.udi : (target.id ? target.id : null); - if (target.anchor) { - a["data-anchor"] = target.anchor; - a.href = a.href + target.anchor; - } else { - a["data-anchor"] = null; - } + // if an anchor exists, check that it is appropriately prefixed + if (target.anchor && target.anchor[0] !== '?' && target.anchor[0] !== '#') { + target.anchor = (target.anchor.indexOf('=') === -1 ? '#' : '?') + target.anchor; + } - return a; - } + // the href might be an external url, so check the value for an anchor/qs + // href has the anchor re-appended later, hence the reset here to avoid duplicating the anchor + if (!target.anchor) { + var urlParts = href.split(/(#|\?)/); + if (urlParts.length === 3) { + href = urlParts[0]; + target.anchor = urlParts[1] + urlParts[2]; + } + } - function insertLink() { - if (anchorElm) { - editor.dom.setAttribs(anchorElm, createElemAttributes()); + //Create a json obj used to create the attributes for the tag + function createElemAttributes() { + var a = { + href: href, + title: target.name, + target: target.target ? target.target : null, + rel: target.rel ? target.rel : null + }; - editor.selection.select(anchorElm); - editor.execCommand('mceEndTyping'); - } else { - editor.execCommand('mceInsertLink', false, createElemAttributes()); - } - } + if (hasUdi) { + a["data-udi"] = target.udi; + } else if (target.id) { + a["data-id"] = target.id; + } - if (!href) { - editor.execCommand('unlink'); - return; - } + if (target.anchor) { + a["data-anchor"] = target.anchor; + a.href = a.href + target.anchor; + } else { + a["data-anchor"] = null; + } - //if we have an id, it must be a locallink:id, aslong as the isMedia flag is not set - if (id && (angular.isUndefined(target.isMedia) || !target.isMedia)) { + return a; + } - href = "/{localLink:" + id + "}"; + function insertLink() { + if (anchorElm) { + editor.dom.setAttribs(anchorElm, createElemAttributes()); - insertLink(); - return; - } + editor.selection.select(anchorElm); + editor.execCommand('mceEndTyping'); + } else { + editor.execCommand('mceInsertLink', false, createElemAttributes()); + } + } - // Is email and not //user@domain.com - if (href.indexOf('@') > 0 && href.indexOf('//') === -1 && href.indexOf('mailto:') === -1) { - href = 'mailto:' + href; - insertLink(); - return; - } + if (!href) { + editor.execCommand('unlink'); + return; + } - // Is www. prefixed - if (/^\s*www\./i.test(href)) { - href = 'http://' + href; - insertLink(); - return; - } + //if we have an id, it must be a locallink:id, aslong as the isMedia flag is not set + if (id && (angular.isUndefined(target.isMedia) || !target.isMedia)) { - insertLink(); + href = "/{localLink:" + id + "}"; - } + insertLink(); + return; + } - }; + // Is email and not //user@domain.com + if (href.indexOf('@') > 0 && href.indexOf('//') === -1 && href.indexOf('mailto:') === -1) { + href = 'mailto:' + href; + insertLink(); + return; + } + + // Is www. prefixed + if (/^\s*www\./i.test(href)) { + href = 'http://' + href; + insertLink(); + return; + } + + insertLink(); + + } + + }; } angular.module('umbraco.services').factory('tinyMceService', tinyMceService); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.controller.js index c64430d9fe..6bcf517126 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.controller.js @@ -1,108 +1,107 @@ -(function() { - "use strict"; +(function () { + "use strict"; - function EmbedOverlay($scope, $http, umbRequestHelper, localizationService) { + function EmbedOverlay($scope, $http, $sce, umbRequestHelper, localizationService) { - var vm = this; - var origWidth = 500; - var origHeight = 300; + var origWidth = 500; + var origHeight = 300; - $scope.model.embed = { - url: "", - width: 360, - height: 240, - constrain: true, - preview: "", - success: false, - info: "", - supportsDimensions: "" - }; + $scope.model.embed = { + url: "", + width: 360, + height: 240, + constrain: true, + preview: "", + success: false, + info: "", + supportsDimensions: "" + }; - vm.showPreview = showPreview; - vm.changeSize = changeSize; + $scope.showPreview = showPreview; + $scope.changeSize = changeSize; - function onInit() { - if(!$scope.model.title) { - localizationService.localize("general_embed").then(function(value){ - $scope.model.title = value; - }); + function onInit() { + if (!$scope.model.title) { + localizationService.localize("general_embed").then(function (value) { + $scope.model.title = value; + }); + } } + + function showPreview() { + + if ($scope.model.embed.url) { + $scope.model.embed.show = true; + $scope.model.embed.preview = "
"; + $scope.model.embed.trustedPreview = $scope.model.embed.preview; + $scope.model.embed.info = ""; + $scope.model.embed.success = false; + + $http({ + method: 'GET', + url: umbRequestHelper.getApiUrl("embedApiBaseUrl", "GetEmbed"), + params: { + url: $scope.model.embed.url, + width: $scope.model.embed.width, + height: $scope.model.embed.height + } + }).then(function (data) { + $scope.model.embed.preview = ""; + + switch (data.data.Status) { + case 0: + //not supported + $scope.model.embed.info = "Not supported"; + break; + case 1: + //error + $scope.model.embed.info = "Could not embed media - please ensure the URL is valid"; + break; + case 2: + $scope.model.embed.preview = data.data.Markup + $scope.model.embed.trustedPreview = $sce.trustAsHtml($scope.model.embed.preview); + $scope.model.embed.supportsDimensions = data.data.SupportsDimensions; + $scope.model.embed.success = true; + break; + } + }, + function () { + $scope.model.embed.supportsDimensions = false; + $scope.model.embed.preview = ""; + $scope.model.embed.info = "Could not embed media - please ensure the URL is valid"; + }); + } else { + $scope.model.embed.supportsDimensions = false; + $scope.model.embed.preview = ""; + $scope.model.embed.info = "Please enter a URL"; + } + } + + function changeSize(type) { + + var width, height; + + if ($scope.model.embed.constrain) { + width = parseInt($scope.model.embed.width, 10); + height = parseInt($scope.model.embed.height, 10); + if (type == 'width') { + origHeight = Math.round((width / origWidth) * height); + $scope.model.embed.height = origHeight; + } else { + origWidth = Math.round((height / origHeight) * width); + $scope.model.embed.width = origWidth; + } + } + if ($scope.model.embed.url !== "") { + showPreview(); + } + + } + + onInit(); + } - function showPreview() { - - if ($scope.model.embed.url) { - $scope.model.embed.show = true; - $scope.model.embed.preview = "
"; - $scope.model.embed.info = ""; - $scope.model.embed.success = false; - - $http({ - method: 'GET', - url: umbRequestHelper.getApiUrl("embedApiBaseUrl", "GetEmbed"), - params: { - url: $scope.model.embed.url, - width: $scope.model.embed.width, - height: $scope.model.embed.height - } - }) - .success(function(data) { - - $scope.model.embed.preview = ""; - - switch (data.Status) { - case 0: - //not supported - $scope.model.embed.info = "Not supported"; - break; - case 1: - //error - $scope.model.embed.info = "Could not embed media - please ensure the URL is valid"; - break; - case 2: - $scope.model.embed.preview = data.Markup; - $scope.model.embed.supportsDimensions = data.SupportsDimensions; - $scope.model.embed.success = true; - break; - } - }) - .error(function() { - $scope.model.embed.supportsDimensions = false; - $scope.model.embed.preview = ""; - $scope.model.embed.info = "Could not embed media - please ensure the URL is valid"; - }); - } else { - $scope.model.embed.supportsDimensions = false; - $scope.model.embed.preview = ""; - $scope.model.embed.info = "Please enter a URL"; - } - } - - function changeSize(type) { - - var width, height; - - if ($scope.model.embed.constrain) { - width = parseInt($scope.model.embed.width, 10); - height = parseInt($scope.model.embed.height, 10); - if (type == 'width') { - origHeight = Math.round((width / origWidth) * height); - $scope.model.embed.height = origHeight; - } else { - origWidth = Math.round((height / origHeight) * width); - $scope.model.embed.width = origWidth; - } - } - if ($scope.model.embed.url !== "") { - showPreview(); - } - - } - - onInit(); - - } - - angular.module("umbraco").controller("Umbraco.Overlays.EmbedOverlay", EmbedOverlay); + angular.module("umbraco").controller("Umbraco.Overlays.EmbedOverlay", EmbedOverlay); })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.html index 401acca2c5..e63e7e42e4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/embed/embed.html @@ -1,27 +1,30 @@ -
+
+ - - - - + + + + - -

-
-
+ +

+
+
-
- - - +
+ + + - - - + + + - - - -
+ + + +
- + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index a9d1cd1234..90fc036dca 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -13,18 +13,9 @@ angular.module("umbraco") var alreadyDirty = false; function syncContent(editor){ - editor.save(); angularHelper.safeApply($scope, function () { $scope.model.value = editor.getContent(); }); - - if (!alreadyDirty) { - //make the form dirty manually so that the track changes works, setting our model doesn't trigger - // the angular bits because tinymce replaces the textarea. - var currForm = angularHelper.getCurrentForm($scope); - currForm.$setDirty(); - alreadyDirty = true; - } } tinyMceService.configuration().then(function (tinyMceConfig) { @@ -37,11 +28,10 @@ angular.module("umbraco") var extendedValidElements = "@[id|class|style],-div[id|dir|class|align|style],ins[datetime|cite],-ul[class|style],-li[class|style],span[id|class|style]"; var invalidElements = tinyMceConfig.inValidElements; - var plugins = _.map(tinyMceConfig.plugins, function (plugin) { - if (plugin.useOnFrontend) { + var plugins = _.map(tinyMceConfig.plugins, + function(plugin) { return plugin.name; - } - }).join(" "); + }); var editorConfig = $scope.model.config.editor; if (!editorConfig || angular.isString(editorConfig)) { @@ -49,7 +39,14 @@ angular.module("umbraco") } //config value on the data type - var toolbar = editorConfig.toolbar.join(" | "); + var allowedSelectionToolbar = ["bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link"]; + var allowedInsertToolbar = ["link", "image", "umbmediapicker", "umbembeddialog", "umbmacro", "bullist", "numlist"]; + var insertToolbar = _.filter(editorConfig.toolbar, function (t) { + return allowedInsertToolbar.indexOf(t) !== -1; + }).join(" | "); + var selectionToolbar = _.filter(editorConfig.toolbar, function(t) { + return allowedSelectionToolbar.indexOf(t) !== -1; + }).join(" | "); var stylesheets = []; var styleFormats = []; var await = []; @@ -142,8 +139,9 @@ angular.module("umbraco") //create a baseline Config to exten upon var baseLineConfigObj = { - mode: "exact", - skin: "umbraco", + //skin: "umbraco", + theme: "inlite", + inline: true, plugins: plugins, valid_elements: validElements, invalid_elements: invalidElements, @@ -154,7 +152,9 @@ angular.module("umbraco") height: editorConfig.dimensions.height, width: editorConfig.dimensions.width, maxImageSize: editorConfig.maxImageSize, - toolbar: toolbar, + //toolbar: toolbar, + insert_toolbar: insertToolbar, + selection_toolbar: selectionToolbar, content_css: stylesheets, style_formats: styleFormats, language: language, @@ -198,81 +198,43 @@ angular.module("umbraco") } //set all the things that user configs should not be able to override - baseLineConfigObj.elements = $scope.textAreaHtmlId; //this is the exact textarea id to replace! + //baseLineConfigObj.elements = $scope.textAreaHtmlId; //this is the exact textarea id to replace! + baseLineConfigObj.selector = "#" + $scope.textAreaHtmlId; baseLineConfigObj.setup = function (editor) { //set the reference tinyMceEditor = editor; - //enable browser based spell checking + //set the value and enable browser based spell checking editor.on('init', function (e) { + editor.setContent($scope.model.value); editor.getBody().setAttribute('spellcheck', true); }); - - //We need to listen on multiple things here because of the nature of tinymce, it doesn't - //fire events when you think! - //The change event doesn't fire when content changes, only when cursor points are changed and undo points - //are created. the blur event doesn't fire if you insert content into the editor with a button and then - //press save. - //We have a couple of options, one is to do a set timeout and check for isDirty on the editor, or we can - //listen to both change and blur and also on our own 'saving' event. I think this will be best because a - //timer might end up using unwanted cpu and we'd still have to listen to our saving event in case they clicked - //save before the timeout elapsed. - - //TODO: We need to re-enable something like this to ensure the track changes is working with tinymce - // so we can detect if the form is dirty or not, Per has some better events to use as this one triggers - // even if you just enter/exit with mouse cursuor which doesn't really mean it's changed. - // see: http://issues.umbraco.org/issue/U4-4485 - //var alreadyDirty = false; - //editor.on('change', function (e) { - // angularHelper.safeApply($scope, function () { - // $scope.model.value = editor.getContent(); - - // if (!alreadyDirty) { - // //make the form dirty manually so that the track changes works, setting our model doesn't trigger - // // the angular bits because tinymce replaces the textarea. - // var currForm = angularHelper.getCurrentForm($scope); - // currForm.$setDirty(); - // alreadyDirty = true; - // } - - // }); - //}); - - //when we leave the editor (maybe) - editor.on('blur', function (e) { - editor.save(); - angularHelper.safeApply($scope, function () { - $scope.model.value = editor.getContent(); - }); - }); - - //when buttons modify content - editor.on('ExecCommand', function (e) { - syncContent(editor); - }); - - // Update model on keypress - editor.on('KeyUp', function (e) { - syncContent(editor); - }); - - // Update model on change, i.e. copy/pasted text, plugins altering content - editor.on('SetContent', function (e) { - if (!e.initial) { - syncContent(editor); + + editor.on('Dirty', function (e) { + console.log("DIRTY..."); + if (!alreadyDirty) { + //make the form dirty manually so that the track changes works, setting our model doesn't trigger + // the angular bits because tinymce replaces the textarea. + var currForm = angularHelper.getCurrentForm($scope); + currForm.$setDirty(); + alreadyDirty = true; } }); - - editor.on('ObjectResized', function (e) { - var qs = "?width=" + e.width + "&height=" + e.height + "&mode=max"; - var srcAttr = $(e.target).attr("src"); - var path = srcAttr.split("?")[0]; - $(e.target).attr("data-mce-src", path + qs); - + editor.on('Change', function (e) { + console.log("Change..."); syncContent(editor); }); + + //editor.on('ObjectResized', function (e) { + // var qs = "?width=" + e.width + "&height=" + e.height + "&mode=max"; + // var srcAttr = $(e.target).attr("src"); + // var path = srcAttr.split("?")[0]; + // $(e.target).attr("data-mce-src", path + qs); + + // syncContent(editor); + //}); tinyMceService.createLinkPicker(editor, $scope, function(currentTarget, anchorElement) { $scope.linkPickerOverlay = { @@ -354,7 +316,7 @@ angular.module("umbraco") $scope.isLoading = false; - }, 200, false); + }, 200); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html index 5842384006..4d6da6a915 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html @@ -1,35 +1,32 @@
-
Loading...
- - +
Loading...
+ +
+ + - - + + - - + + - - + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js index e1c9ce9ba2..245843ac84 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js @@ -25,7 +25,7 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", // extend commands with properties for font-icon and if it is a custom command $scope.tinyMceConfig.commands = _.map($scope.tinyMceConfig.commands, function (obj) { - var icon = getFontIcon(obj.frontEndCommand); + var icon = getFontIcon(obj.alias); return angular.extend(obj, { fontIcon: icon.name, isCustom: icon.isCustom @@ -46,10 +46,10 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", }; $scope.selectCommand = function(command){ - var index = $scope.model.value.toolbar.indexOf(command.frontEndCommand); + var index = $scope.model.value.toolbar.indexOf(command.alias); if(command.selected && index === -1){ - $scope.model.value.toolbar.push(command.frontEndCommand); + $scope.model.value.toolbar.push(command.alias); }else if(index >= 0){ $scope.model.value.toolbar.splice(index, 1); } @@ -107,7 +107,7 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var commands = _.where($scope.tinyMceConfig.commands, {selected: true}); - $scope.model.value.toolbar = _.pluck(commands, "frontEndCommand"); + $scope.model.value.toolbar = _.pluck(commands, "alias"); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html index 155ad34e27..4e4b37ba67 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html @@ -4,7 +4,7 @@
- \ No newline at end of file + diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config index f338305aa3..eeb90f9ea6 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config @@ -1,245 +1,51 @@ - - - + - - - code - Code - images/editor/code.gif - code - 1 - - - codemirror - Code mirror - images/editor/code.gif - codemirror - 1 - - - removeformat - Remove format - images/editor/removeformat.gif - removeformat - 2 - - - undo - Undo - images/editor/undo.gif - undo - 11 - - - redo - Redo - images/editor/redo.gif - redo - 12 - - - cut - Cut - images/editor/cut.gif - cut - 13 - - - copy - Copy - images/editor/copy.gif - copy - 14 - - - paste - Paste - images/editor/paste.gif - paste - 15 - - - styleselect - Style select - images/editor/showStyles.png - styleselect - 20 - - - bold - Bold - images/editor/bold.gif - bold - 21 - - - italic - Italic - images/editor/italic.gif - italic - 22 - - - underline - Underline - images/editor/underline.gif - underline - 23 - - - strikethrough - Strikethrough - images/editor/strikethrough.gif - strikethrough - 24 - - - justifyleft - Justify left - images/editor/justifyleft.gif - justifyleft - 31 - - - justifycenter - Justify center - images/editor/justifycenter.gif - justifycenter - 32 - - - justifyright - Justify right - images/editor/justifyright.gif - justifyright - 33 - - - justifyfull - Justify full - images/editor/justifyfull.gif - alignjustify - 34 - - - bullist - Bullet list - images/editor/bullist.gif - bullist - 41 - - - numlist - Numbered list - images/editor/numlist.gif - numlist - 42 - - - outdent - Decrease indent - images/editor/outdent.gif - outdent - 43 - - - indent - Increase indent - images/editor/indent.gif - indent - 44 - - - mceLink - Insert/edit link - images/editor/link.gif - link - 51 - - - unlink - Remove link - images/editor/unLink.gif - unlink - 52 - - - mceInsertAnchor - Anchor - images/editor/anchor.gif - anchor - 53 - - - mceImage - Image - images/editor/image.gif - image - 61 - - - umbracomacro - Macro - images/editor/insMacro.gif - umbracomacro - 62 - - - mceInsertTable - Table - images/editor/table.gif - table - 63 - - - umbracoembed - Embed - images/editor/media.gif - umbracoembed - 66 - - - inserthorizontalrule - Horizontal rule - images/editor/hr.gif - hr - 71 - - - subscript - Subscript - images/editor/sub.gif - subscript - 72 - - - superscript - Superscript - images/editor/sup.gif - superscript - 73 - - - mceCharMap - Character map - images/editor/charmap.gif - charmap - 74 - - - - code - codemirror - paste - anchor - charmap - table - lists - hr - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + code + codemirror + paste + anchor + charmap + table + lists + hr + + + - - font + + font - - - - raw - - { + + + + raw + + + - - \ No newline at end of file + + diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.config b/src/Umbraco.Web.UI/config/tinyMceConfig.config index 84e841d924..eeb90f9ea6 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.config @@ -1,245 +1,51 @@ - - - + - - - code - Code - images/editor/code.gif - code - 1 - - - codemirror - Code mirror - images/editor/code.gif - codemirror - 1 - - - removeformat - Remove format - images/editor/removeformat.gif - removeformat - 2 - - - undo - Undo - images/editor/undo.gif - undo - 11 - - - redo - Redo - images/editor/redo.gif - redo - 12 - - - cut - Cut - images/editor/cut.gif - cut - 13 - - - copy - Copy - images/editor/copy.gif - copy - 14 - - - paste - Paste - images/editor/paste.gif - paste - 15 - - - styleselect - Style select - images/editor/showStyles.png - styleselect - 20 - - - bold - Bold - images/editor/bold.gif - bold - 21 - - - italic - Italic - images/editor/italic.gif - italic - 22 - - - underline - Underline - images/editor/underline.gif - underline - 23 - - - strikethrough - Strikethrough - images/editor/strikethrough.gif - strikethrough - 24 - - - justifyleft - Justify left - images/editor/justifyleft.gif - justifyleft - 31 - - - justifycenter - Justify center - images/editor/justifycenter.gif - justifycenter - 32 - - - justifyright - Justify right - images/editor/justifyright.gif - justifyright - 33 - - - justifyfull - Justify full - images/editor/justifyfull.gif - alignjustify - 34 - - - bullist - Bullet list - images/editor/bullist.gif - bullist - 41 - - - numlist - Numbered list - images/editor/numlist.gif - numlist - 42 - - - outdent - Decrease indent - images/editor/outdent.gif - outdent - 43 - - - indent - Increase indent - images/editor/indent.gif - indent - 44 - - - mceLink - Insert/edit link - images/editor/link.gif - link - 51 - - - unlink - Remove link - images/editor/unLink.gif - unlink - 52 - - - mceInsertAnchor - Anchor - images/editor/anchor.gif - anchor - 53 - - - mceImage - Image - images/editor/image.gif - image - 61 - - - umbracomacro - Macro - images/editor/insMacro.gif - umbracomacro - 62 - - - mceInsertTable - Table - images/editor/table.gif - table - 63 - - - umbracoembed - Embed - images/editor/media.gif - umbracoembed - 66 - - - inserthorizontalrule - Horizontal rule - images/editor/hr.gif - hr - 71 - - - subscript - Subscript - images/editor/sub.gif - subscript - 72 - - - superscript - Superscript - images/editor/sup.gif - superscript - 73 - - - mceCharMap - Character map - images/editor/charmap.gif - charmap - 74 - - - - code - codemirror - paste - anchor - charmap - table - lists - hr - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + code + codemirror + paste + anchor + charmap + table + lists + hr + + + - - font + + font - - - - raw - - { + + + + raw + + + - + diff --git a/src/Umbraco.Web/Models/ContentEditing/RichTextEditorCommand.cs b/src/Umbraco.Web/Models/ContentEditing/RichTextEditorCommand.cs index 49065024a5..85be2a7b80 100644 --- a/src/Umbraco.Web/Models/ContentEditing/RichTextEditorCommand.cs +++ b/src/Umbraco.Web/Models/ContentEditing/RichTextEditorCommand.cs @@ -12,29 +12,9 @@ namespace Umbraco.Web.Models.ContentEditing { [DataMember(Name = "name")] public string Name { get; set; } - - [DataMember(Name = "icon")] - public string Icon { get; set; } - - [DataMember(Name = "command")] - public string Command { get; set; } - + [DataMember(Name = "alias")] public string Alias { get; set; } - - [DataMember(Name = "userInterface")] - public string UserInterface { get; set; } - - [DataMember(Name = "frontEndCommand")] - public string FrontEndCommand { get; set; } - - [DataMember(Name = "value")] - public string Value { get; set; } - - [DataMember(Name = "priority")] - public int Priority { get; set; } - - [DataMember(Name = "isStylePicker")] - public bool IsStylePicker { get; set; } + } } diff --git a/src/Umbraco.Web/Models/ContentEditing/RichTextEditorPlugin.cs b/src/Umbraco.Web/Models/ContentEditing/RichTextEditorPlugin.cs index aec92a1eff..a3ce9e508c 100644 --- a/src/Umbraco.Web/Models/ContentEditing/RichTextEditorPlugin.cs +++ b/src/Umbraco.Web/Models/ContentEditing/RichTextEditorPlugin.cs @@ -12,8 +12,5 @@ namespace Umbraco.Web.Models.ContentEditing { [DataMember(Name = "name")] public string Name { get; set; } - - [DataMember(Name = "useOnFrontend")] - public bool UseOnFrontend { get; set; } } } diff --git a/src/Umbraco.Web/PropertyEditors/RichTextConfiguration.cs b/src/Umbraco.Web/PropertyEditors/RichTextConfiguration.cs index 420abe61cc..afbc57e445 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextConfiguration.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextConfiguration.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.PropertyEditors; +using Newtonsoft.Json.Linq; +using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { @@ -8,9 +9,9 @@ namespace Umbraco.Web.PropertyEditors public class RichTextConfiguration { [ConfigurationField("editor", "Editor", "views/propertyeditors/rte/rte.prevalues.html", HideLabel = true)] - public string Editor { get; set; } + public JObject Editor { get; set; } [ConfigurationField("hideLabel", "Hide Label", "boolean")] public bool HideLabel { get; set; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPreValueController.cs b/src/Umbraco.Web/PropertyEditors/RichTextPreValueController.cs index e769a43e6d..1590d36896 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPreValueController.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPreValueController.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Xml; +using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Web.Editors; using Umbraco.Web.Models.ContentEditing; @@ -15,7 +16,7 @@ namespace Umbraco.Web.PropertyEditors { private static volatile bool _init; private static readonly object Locker = new object(); - private static readonly Dictionary Commands = new Dictionary(); + private static readonly Dictionary Commands = new Dictionary(); private static readonly Dictionary Plugins = new Dictionary(); private static readonly Dictionary ConfigOptions = new Dictionary(); @@ -26,12 +27,14 @@ namespace Umbraco.Web.PropertyEditors { EnsureInit(); - RichTextEditorConfiguration config = new RichTextEditorConfiguration(); - config.Plugins = Plugins.Values; - config.Commands = Commands.Values; - config.ValidElements = _validElements; - config.InvalidElements = _invalidElements; - config.CustomConfig = ConfigOptions; + var config = new RichTextEditorConfiguration + { + Plugins = Plugins.Values, + Commands = Commands.Values, + ValidElements = _validElements, + InvalidElements = _invalidElements, + CustomConfig = ConfigOptions + }; return config; } @@ -51,28 +54,17 @@ namespace Umbraco.Web.PropertyEditors foreach (XmlNode n in xd.DocumentElement.SelectNodes("//command")) { - var alias = n.SelectSingleNode("./umbracoAlias").FirstChild.Value.ToLower(); - - bool isStyle = false; - if (n.Attributes.GetNamedItem("isStyle") != null) - isStyle = bool.Parse(n.Attributes.GetNamedItem("isStyle").Value); + var alias = n.AttributeValue("alias").ToLower(); if (!Commands.ContainsKey(alias)) Commands.Add( - alias, - new RichTextEditorCommand() - { - IsStylePicker = isStyle, - Name = n.SelectSingleNode("./name") != null ? n.SelectSingleNode("./name").FirstChild.Value : alias, - Icon = n.SelectSingleNode("./icon").FirstChild.Value, - Command = n.SelectSingleNode("./tinyMceCommand").FirstChild.Value, - Alias = alias, - UserInterface = n.SelectSingleNode("./tinyMceCommand").Attributes.GetNamedItem("userInterface").Value, - FrontEndCommand = n.SelectSingleNode("./tinyMceCommand").Attributes.GetNamedItem("frontendCommand").Value, - Value = n.SelectSingleNode("./tinyMceCommand").Attributes.GetNamedItem("value").Value, - Priority = int.Parse(n.SelectSingleNode("./priority").FirstChild.Value) - } - ); + alias, + new RichTextEditorCommand() + { + Name = n.AttributeValue("name") ?? alias, + Alias = alias, + } + ); } @@ -80,16 +72,12 @@ namespace Umbraco.Web.PropertyEditors { if (!Plugins.ContainsKey(n.FirstChild.Value)) { - bool useOnFrontend = false; - if (n.Attributes.GetNamedItem("loadOnFrontend") != null) - useOnFrontend = bool.Parse(n.Attributes.GetNamedItem("loadOnFrontend").Value); Plugins.Add( n.FirstChild.Value.ToLower(), new RichTextEditorPlugin() { Name = n.FirstChild.Value, - UseOnFrontend = useOnFrontend }); } } From ab78242dd69a0a48d8eb9641936eaae1307499ce Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 20 Jul 2018 01:30:40 +1000 Subject: [PATCH 002/337] Grid pre-value fixing and updates tinymce with inline theme for the grid too --- .../components/grid/grid.rte.directive.js | 152 +++++----- .../overlays/mediaPicker/mediapicker.html | 279 +++++++++--------- .../propertyeditors/rte/rte.controller.js | 36 ++- .../PropertyEditors/GridConfiguration.cs | 9 +- 4 files changed, 236 insertions(+), 240 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index cb5b2a8a27..dfdb1d126a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -13,7 +13,7 @@ angular.module("umbraco.directives") onMacroPickerClick: "=", onLinkPickerClick: "=" }, - template: "", + template: "
", replace: true, link: function (scope, element, attrs) { @@ -40,7 +40,6 @@ angular.module("umbraco.directives") plugins.push("autoresize"); //config value on the data type - var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"].join(" | "); var stylesheets = []; var styleFormats = []; @@ -48,14 +47,22 @@ angular.module("umbraco.directives") //queue file loading if (typeof (tinymce) === "undefined") { - await.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope)); + await.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope)); } - - if(scope.configuration && scope.configuration.toolbar){ - toolbar = scope.configuration.toolbar.join(' | '); + var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"]; + if(scope.configuration && scope.configuration.toolbar) { + toolbar = scope.configuration.toolbar; } - + //TODO: get this from the config + var allowedSelectionToolbar = ["bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link"]; + var allowedInsertToolbar = ["link", "image", "umbmediapicker", "umbembeddialog", "umbmacro", "bullist", "numlist"]; + var insertToolbar = _.filter(toolbar, function (t) { + return allowedInsertToolbar.indexOf(t) !== -1; + }).join(" | "); + var selectionToolbar = _.filter(toolbar, function (t) { + return allowedSelectionToolbar.indexOf(t) !== -1; + }).join(" | "); if(scope.configuration && scope.configuration.stylesheets){ angular.forEach(scope.configuration.stylesheets, function(stylesheet, key){ @@ -103,8 +110,8 @@ angular.module("umbraco.directives") //create a baseline Config to exten upon var baseLineConfigObj = { - mode: "exact", - skin: "umbraco", + theme: "inlite", + inline: true, plugins: plugins, valid_elements: validElements, invalid_elements: invalidElements, @@ -112,7 +119,8 @@ angular.module("umbraco.directives") menubar: false, statusbar: false, relative_urls: false, - toolbar: toolbar, + insert_toolbar: insertToolbar, + selection_toolbar: selectionToolbar, content_css: stylesheets, style_formats: styleFormats, autoresize_bottom_margin: 0, @@ -157,7 +165,8 @@ angular.module("umbraco.directives") } //set all the things that user configs should not be able to override - baseLineConfigObj.elements = uniqueId; + //baseLineConfigObj.elements = uniqueId; + baseLineConfigObj.selector = "#" + scope.uniqueId; baseLineConfigObj.setup = function (editor) { //set the reference @@ -167,6 +176,11 @@ angular.module("umbraco.directives") //enable browser based spell checking editor.on('init', function (e) { + if (!scope.value) { + scope.value = ""; + } + editor.setContent(scope.value); + editor.getBody().setAttribute('spellcheck', true); //force overflow to hidden to prevent no needed scroll @@ -180,58 +194,57 @@ angular.module("umbraco.directives") }); - // pin toolbar to top of screen if we have focus and it scrolls off the screen - var pinToolbar = function () { + //// pin toolbar to top of screen if we have focus and it scrolls off the screen + //var pinToolbar = function () { - var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - var toolbarHeight = _toolbar.height(); + // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); + // var toolbarHeight = _toolbar.height(); - var _tinyMce = $(editor.editorContainer); - var tinyMceRect = _tinyMce[0].getBoundingClientRect(); - var tinyMceTop = tinyMceRect.top; - var tinyMceBottom = tinyMceRect.bottom; - var tinyMceWidth = tinyMceRect.width; + // var _tinyMce = $(editor.editorContainer); + // var tinyMceRect = _tinyMce[0].getBoundingClientRect(); + // var tinyMceTop = tinyMceRect.top; + // var tinyMceBottom = tinyMceRect.bottom; + // var tinyMceWidth = tinyMceRect.width; - var _tinyMceEditArea = _tinyMce.find(".mce-edit-area"); + // 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); + // // set padding in top of mce so the content does not "jump" up + // _tinyMceEditArea.css("padding-top", toolbarHeight); - if (tinyMceTop < 160 && ((160 + toolbarHeight) < tinyMceBottom)) { - _toolbar - .css("visibility", "visible") - .css("position", "fixed") - .css("top", "160px") - .css("margin-top", "0") - .css("width", tinyMceWidth); - } else { - _toolbar - .css("visibility", "visible") - .css("position", "absolute") - .css("top", "auto") - .css("margin-top", "0") - .css("width", tinyMceWidth); - } + // if (tinyMceTop < 160 && ((160 + toolbarHeight) < tinyMceBottom)) { + // _toolbar + // .css("visibility", "visible") + // .css("position", "fixed") + // .css("top", "160px") + // .css("margin-top", "0") + // .css("width", tinyMceWidth); + // } else { + // _toolbar + // .css("visibility", "visible") + // .css("position", "absolute") + // .css("top", "auto") + // .css("margin-top", "0") + // .css("width", tinyMceWidth); + // } - }; + //}; - // unpin toolbar to top of screen - var unpinToolbar = function() { + //// unpin toolbar to top of screen + //var unpinToolbar = function() { - var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - var _tinyMce = $(editor.editorContainer); - var _tinyMceEditArea = _tinyMce.find(".mce-edit-area"); + // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); + // var _tinyMce = $(editor.editorContainer); + // 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"); + // // reset padding in top of mce so the content does not "jump" up + // _tinyMceEditArea.css("padding-top", "0"); - _toolbar.css("position", "static"); + // _toolbar.css("position", "static"); - }; + //}; //when we leave the editor (maybe) - editor.on('blur', function (e) { - editor.save(); + editor.on('blur', function (e) { angularHelper.safeApply(scope, function () { scope.value = editor.getContent(); @@ -242,8 +255,8 @@ angular.module("umbraco.directives") scope.onBlur(); } - unpinToolbar(); - $('.umb-panel-body').off('scroll', pinToolbar); + //unpinToolbar(); + //$('.umb-panel-body').off('scroll', pinToolbar); }); }); @@ -256,8 +269,8 @@ angular.module("umbraco.directives") scope.onFocus(); } - pinToolbar(); - $('.umb-panel-body').on('scroll', pinToolbar); + //pinToolbar(); + //$('.umb-panel-body').on('scroll', pinToolbar); }); }); @@ -270,36 +283,17 @@ angular.module("umbraco.directives") scope.onClick(); } - pinToolbar(); - $('.umb-panel-body').on('scroll', pinToolbar); + //pinToolbar(); + //$('.umb-panel-body').on('scroll', pinToolbar); }); }); - //when buttons modify content - editor.on('ExecCommand', function (e) { - editor.save(); - angularHelper.safeApply(scope, function () { - scope.value = editor.getContent(); - }); - }); - - // Update model on keypress - editor.on('KeyUp', function (e) { - editor.save(); - angularHelper.safeApply(scope, function () { - scope.value = editor.getContent(); - }); - }); - // Update model on change, i.e. copy/pasted text, plugins altering content - editor.on('SetContent', function (e) { - if (!e.initial) { - editor.save(); - angularHelper.safeApply(scope, function () { - scope.value = editor.getContent(); - }); - } + editor.on('Change', function (e) { + angularHelper.safeApply(scope, function () { + scope.value = editor.getContent(); + }); }); editor.on('ObjectResized', function (e) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html index 482485c4b2..d95a194da3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.html @@ -1,150 +1,153 @@ -
+
+ -
+
- + + + +
+ +
+ + +
+ +
+ +
+ Preview +
+ + + + +
+ +
+ +
+ + + placeholder="@general_url" + class="umb-property-editor umb-textstring" + ng-model="target.url" + ng-disabled="target.id" />
-
- - +
+ +
-
-
- -
-
- - - - - - - -
- - -
- - - - - -
- - - -
- -
- - -
- -
- -
- Preview -
- - - - -
- -
- -
- - -
- -
- - -
- - -
- - +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 90fc036dca..1be54073a2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -10,8 +10,7 @@ angular.module("umbraco") var d = new Date(); var n = d.getTime(); $scope.textAreaHtmlId = $scope.model.alias + "_" + n + "_rte"; - - var alreadyDirty = false; + function syncContent(editor){ angularHelper.safeApply($scope, function () { $scope.model.value = editor.getContent(); @@ -39,6 +38,8 @@ angular.module("umbraco") } //config value on the data type + var toolbar = editorConfig.toolbar; + //TODO: get this from the config var allowedSelectionToolbar = ["bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link"]; var allowedInsertToolbar = ["link", "image", "umbmediapicker", "umbembeddialog", "umbmacro", "bullist", "numlist"]; var insertToolbar = _.filter(editorConfig.toolbar, function (t) { @@ -47,6 +48,7 @@ angular.module("umbraco") var selectionToolbar = _.filter(editorConfig.toolbar, function(t) { return allowedSelectionToolbar.indexOf(t) !== -1; }).join(" | "); + var stylesheets = []; var styleFormats = []; var await = []; @@ -139,7 +141,6 @@ angular.module("umbraco") //create a baseline Config to exten upon var baseLineConfigObj = { - //skin: "umbraco", theme: "inlite", inline: true, plugins: plugins, @@ -152,7 +153,6 @@ angular.module("umbraco") height: editorConfig.dimensions.height, width: editorConfig.dimensions.width, maxImageSize: editorConfig.maxImageSize, - //toolbar: toolbar, insert_toolbar: insertToolbar, selection_toolbar: selectionToolbar, content_css: stylesheets, @@ -212,14 +212,10 @@ angular.module("umbraco") }); editor.on('Dirty', function (e) { - console.log("DIRTY..."); - if (!alreadyDirty) { - //make the form dirty manually so that the track changes works, setting our model doesn't trigger - // the angular bits because tinymce replaces the textarea. - var currForm = angularHelper.getCurrentForm($scope); - currForm.$setDirty(); - alreadyDirty = true; - } + //make the form dirty manually so that the track changes works, setting our model doesn't trigger + // the angular bits because tinymce replaces the textarea. + var currForm = angularHelper.getCurrentForm($scope); + currForm.$setDirty(); }); editor.on('Change', function (e) { @@ -227,14 +223,16 @@ angular.module("umbraco") syncContent(editor); }); - //editor.on('ObjectResized', function (e) { - // var qs = "?width=" + e.width + "&height=" + e.height + "&mode=max"; - // var srcAttr = $(e.target).attr("src"); - // var path = srcAttr.split("?")[0]; - // $(e.target).attr("data-mce-src", path + qs); + editor.on('ObjectResized', function (e) { + console.log("ObjectResized..."); - // syncContent(editor); - //}); + var qs = "?width=" + e.width + "&height=" + e.height + "&mode=max"; + var srcAttr = $(e.target).attr("src"); + var path = srcAttr.split("?")[0]; + $(e.target).attr("data-mce-src", path + qs); + + syncContent(editor); + }); tinyMceService.createLinkPicker(editor, $scope, function(currentTarget, anchorElement) { $scope.linkPickerOverlay = { diff --git a/src/Umbraco.Web/PropertyEditors/GridConfiguration.cs b/src/Umbraco.Web/PropertyEditors/GridConfiguration.cs index 23cc722e6f..750fae21bc 100644 --- a/src/Umbraco.Web/PropertyEditors/GridConfiguration.cs +++ b/src/Umbraco.Web/PropertyEditors/GridConfiguration.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.PropertyEditors; +using Newtonsoft.Json.Linq; +using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { @@ -8,9 +9,9 @@ namespace Umbraco.Web.PropertyEditors public class GridConfiguration { [ConfigurationField("items", "Grid", "views/propertyeditors/grid/grid.prevalues.html", Description = "Grid configuration")] - public string Items { get; set; } + public JObject Items { get; set; } [ConfigurationField("rte", "Rich text editor", "views/propertyeditors/rte/rte.prevalues.html", Description = "Rich text editor configuration")] - public string Rte { get; set; } + public JObject Rte { get; set; } } -} \ No newline at end of file +} From 829edf5307edd5d50f8871ae310d6c7ace542864 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 20 Jul 2018 16:32:10 +1000 Subject: [PATCH 003/337] removes unecessary skin/theme for tinymce --- .../{skins => DELETE_skins}/umbraco/content.min.css | 0 .../{skins => DELETE_skins}/umbraco/fonts/readme.md | 0 .../umbraco/fonts/tinymce-small.eot | Bin .../umbraco/fonts/tinymce-small.svg | 0 .../umbraco/fonts/tinymce-small.ttf | Bin .../umbraco/fonts/tinymce-small.woff | Bin .../umbraco/fonts/tinymce.eot | Bin .../umbraco/fonts/tinymce.svg | 0 .../umbraco/fonts/tinymce.ttf | Bin .../umbraco/fonts/tinymce.woff | Bin .../{skins => DELETE_skins}/umbraco/img/anchor.gif | Bin .../{skins => DELETE_skins}/umbraco/img/loader.gif | Bin .../{skins => DELETE_skins}/umbraco/img/object.gif | Bin .../{skins => DELETE_skins}/umbraco/img/trans.gif | Bin .../{skins => DELETE_skins}/umbraco/img/wline.gif | Bin .../umbraco/skin.classic.min.css | 0 .../umbraco/skin.ie7.min.css | 0 .../{skins => DELETE_skins}/umbraco/skin.min.css | 0 .../lib/tinymce/themes/umbraco/theme.min.js | 1 - 19 files changed, 1 deletion(-) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/content.min.css (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/readme.md (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce-small.eot (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce-small.svg (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce-small.ttf (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce-small.woff (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce.eot (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce.svg (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce.ttf (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/fonts/tinymce.woff (100%) rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/img/anchor.gif (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/img/loader.gif (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/img/object.gif (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/img/trans.gif (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/img/wline.gif (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/skin.classic.min.css (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/skin.ie7.min.css (100%) mode change 100755 => 100644 rename src/Umbraco.Web.UI.Client/lib/tinymce/{skins => DELETE_skins}/umbraco/skin.min.css (100%) mode change 100755 => 100644 delete mode 100755 src/Umbraco.Web.UI.Client/lib/tinymce/themes/umbraco/theme.min.js diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/content.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/content.min.css old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/content.min.css rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/content.min.css diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/readme.md b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/readme.md old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/readme.md rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/readme.md diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.eot b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.eot similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.eot rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.eot diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.svg b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.svg rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.svg diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.ttf b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.ttf similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.ttf rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.ttf diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.woff b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.woff similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce-small.woff rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.woff diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.eot b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.eot similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.eot rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.eot diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.svg b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.svg rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.svg diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.ttf b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.ttf similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.ttf rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.ttf diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.woff b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.woff similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/fonts/tinymce.woff rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.woff diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/anchor.gif b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/anchor.gif old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/anchor.gif rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/anchor.gif diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/loader.gif b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/loader.gif old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/loader.gif rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/loader.gif diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/object.gif b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/object.gif old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/object.gif rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/object.gif diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/trans.gif b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/trans.gif old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/trans.gif rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/trans.gif diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/wline.gif b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/wline.gif old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/img/wline.gif rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/wline.gif diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.classic.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.classic.min.css old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.classic.min.css rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.classic.min.css diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.ie7.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.ie7.min.css old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.ie7.min.css rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.ie7.min.css diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.min.css old mode 100755 new mode 100644 similarity index 100% rename from src/Umbraco.Web.UI.Client/lib/tinymce/skins/umbraco/skin.min.css rename to src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.min.css diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/themes/umbraco/theme.min.js b/src/Umbraco.Web.UI.Client/lib/tinymce/themes/umbraco/theme.min.js deleted file mode 100755 index 1fbd8159ec..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/themes/umbraco/theme.min.js +++ /dev/null @@ -1 +0,0 @@ -tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var r,i=[];if(t)return c(t.split(/[ ,]/),function(t){function n(){var n=e.selection;"bullist"==o&&n.selectorChanged("ul > li",function(e,n){for(var r,i=n.parents.length;i--&&(r=n.parents[i].nodeName,"OL"!=r&&"UL"!=r););t.active("UL"==r)}),"numlist"==o&&n.selectorChanged("ol > li",function(e,n){for(var r,i=n.parents.length;i--&&(r=n.parents[i].nodeName,"OL"!=r&&"UL"!=r););t.active("OL"==r)}),t.settings.stateSelector&&n.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&n.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var o;"|"==t?r=null:l.has(t)?(t={type:t},s.toolbar_items_size&&(t.size=s.toolbar_items_size),i.push(t),r=null):(r||(r={type:"buttongroup",items:[]},i.push(r)),e.buttons[t]&&(o=t,t=e.buttons[o],t.type=t.type||"button",s.toolbar_items_size&&(t.size=s.toolbar_items_size),t=l.create(t),r.items.push(t),e.initialized?n():e.on("init",n)))}),n.push({type:"toolbar",layout:"flow",items:i}),!0}for(var n=[],r=1;10>r&&t(s["toolbar"+r]);r++);return n.length||t(s.toolbar||f),n}function n(){function t(t){var n;return"|"==t?{text:"|"}:n=e.menuItems[t]}function n(n){var r,i,o,a;if(s.menu?(i=s.menu[n],a=!0):i=d[n],i){r={text:i.title},o=[],c((i.items||"").split(/[ ,]/),function(e){var n=t(e);n&&o.push(t(e))}),a||c(e.menuItems,function(e){e.context==n&&("before"==e.separator&&o.push({text:"|"}),e.prependToContext?o.unshift(e):o.push(e),"after"==e.separator&&o.push({text:"|"}))});for(var l=0;o.length>l;l++)"|"==o[l].text&&(0===l||l==o.length-1)&&o.splice(l,1);if(r.menu=o,!r.menu.length)return null}return r}var r=[],i=s.menubar?tinymce.makeMap(s.menubar,/[ ,]/):!1;for(var o in d)(!i||i[o])&&(o=n(o),o&&r.push(o));return r}function r(t){function n(e){var n=t.find(e)[0];n&&n.focus()}e.shortcuts.add("Alt+F9","",function(){n("menubar")}),e.shortcuts.add("Alt+F10","",function(){n("toolbar")}),e.shortcuts.add("Alt+F11","",function(){n("elementpath")}),t.on("cancel",function(){e.focus()})}function i(){function i(){if(f&&f.visible()){var t=u.getPos(e.getBody());f.moveTo(t.x,t.y-f.layoutRect().h)}}function o(){f&&(f.show(),i(),u.addClass(e.getBody(),"mce-edit-focus"))}function c(){f&&(f.hide(),u.removeClass(e.getBody(),"mce-edit-focus"),document.activeElement&&-1==document.activeElement.className.indexOf("mce-content-body")&&u.setStyle(document.body,"padding-top",0))}function d(){return f?(f.visible()||o(),void 0):(f=a.panel=l.create({type:"floatpanel",classes:"tinymce tinymce-inline",layout:"flex",direction:"column",autohide:!1,autofix:!0,border:1,items:[s.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:n()},{type:"panel",name:"toolbar",layout:"stack",items:t()}]}),f.renderTo(document.body).reflow(),r(f),o(),e.on("nodeChange",i),e.on("activate",o),e.on("deactivate",c),void 0)}var f;return s.content_editable=!0,e.on("focus",d),e.on("blur",c),e.on("remove",function(){f.remove(),f=null}),{}}function o(i){var o;return o=a.panel=l.create({type:"panel",classes:"tinymce",style:"visibility: hidden",layout:"stack",border:1,items:[s.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:n()},{type:"panel",layout:"stack",items:t()},{type:"panel",name:"iframe",layout:"stack",classes:"edit-area",html:"",border:"1 0 0 0"}]}),s.statusbar!==!1&&o.add({type:"panel",name:"statusbar",classes:"statusbar",layout:"flow",border:"1 0 0 0",items:[{type:"elementpath"},s.resize!==!1?{type:"resizehandle",editor:e}:null]}),o.renderBefore(i.targetNode).reflow(),s.width&&tinymce.DOM.setStyle(o.getEl(),"width",s.width),e.on("remove",function(){o.remove(),o=null}),r(o),{iframeContainer:o.find("#iframe")[0].getEl(),editorContainer:o.getEl()}}var a=this,s=e.settings,l=tinymce.ui.Factory,c=tinymce.each,u=tinymce.DOM,d={file:{title:"File",items:"newdocument"},edit:{title:"Edit",items:"undo redo | cut copy paste | selectall"},insert:{title:"Insert",items:"|"},view:{title:"View",items:"visualaid |"},format:{title:"Format",items:"bold italic underline strikethrough superscript subscript | formats | removeformat"},table:{title:"Table"},tools:{title:"Tools"}},f="undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image";a.renderUI=function(t){var n=s.skin!==!1?s.skin||"lightgray":!1;return n&&(tinymce.Env.ie&&7>=tinymce.Env.ie?tinymce.DOM.loadCSS(tinymce.baseURL+"/skins/"+n+"/skin.ie7.min.css"):tinymce.DOM.loadCSS(tinymce.baseURL+"/skins/"+n+"/skin.min.css"),e.contentCSS.push(tinymce.baseURL+"/skins/"+n+"/content.min.css")),e.on("ProgressState",function(e){a.throbber=a.throbber||new tinymce.ui.Throbber(a.panel.getEl("body")),e.state?a.throbber.show(e.time):a.throbber.hide()}),s.inline?i(t):o(t)}}); \ No newline at end of file From 88a7d56a088bdc6f194c64834d6ad48f942a9de2 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 20 Jul 2018 16:40:31 +1000 Subject: [PATCH 004/337] gets inline/selection commands in place, things are looking better. --- .../components/grid/grid.rte.directive.js | 542 +++++++----------- .../src/common/services/tinymce.service.js | 265 ++++++++- src/Umbraco.Web.UI.Client/src/less/belle.less | 1 + src/Umbraco.Web.UI.Client/src/less/rte.less | 53 ++ .../src/views/components/grid/grid-rte.html | 3 + .../grid/config/grid.default.rtestyles.css | 15 - .../propertyeditors/rte/rte.controller.js | 253 ++------ .../config/tinyMceConfig.Release.config | 71 +-- .../config/tinyMceConfig.config | 71 +-- .../ContentEditing/RichTextEditorCommand.cs | 14 +- .../RichTextPreValueController.cs | 1 + 11 files changed, 667 insertions(+), 622 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/less/rte.less create mode 100644 src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html delete mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.rtestyles.css diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index dfdb1d126a..5d2d763ca3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -7,379 +7,249 @@ angular.module("umbraco.directives") onClick: '&', onFocus: '&', onBlur: '&', - configuration:"=", + configuration: "=", onMediaPickerClick: "=", onEmbedClick: "=", onMacroPickerClick: "=", onLinkPickerClick: "=" }, - template: "
", + templateUrl: 'views/components/grid/grid-rte.html', replace: true, link: function (scope, element, attrs) { - var initTiny = function () { + //TODO: A lot of the code below should be shared between the grid rte and the normal rte - //we always fetch the default one, and then override parts with our own - tinyMceService.configuration().then(function (tinyMceConfig) { + var promises = []; + //queue file loading + if (typeof (tinymce) === "undefined") { + promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope)); + } + var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"]; + if (scope.configuration && scope.configuration.toolbar) { + toolbar = scope.configuration.toolbar; + } + + //stores a reference to the editor + var tinyMceEditor = null; - //config value from general tinymce.config file - var validElements = tinyMceConfig.validElements; - 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"}]; + promises.push(tinyMceService.getTinyMceEditorConfig({ + htmlId: scope.uniqueId, + stylesheets: scope.configuration ? scope.configuration.stylesheets : null, + toolbar: toolbar + })); - //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]"; + $q.all(promises).then(function (result) { + + var tinyMceEditorConfig = result[promises.length - 1]; + + tinyMceEditorConfig.setup = function (editor) { + + //set the reference + tinyMceEditor = editor; + + //enable browser based spell checking + editor.on('init', function (e) { + + if (!scope.value) { + scope.value = ""; + } + editor.setContent(scope.value); + + editor.getBody().setAttribute('spellcheck', true); + + //force overflow to hidden to prevent no needed scroll + editor.getBody().style.overflow = "hidden"; + + $timeout(function () { + if (scope.value === null) { + editor.focus(); + } + }, 400); - var invalidElements = tinyMceConfig.inValidElements; - var plugins = _.map(tinyMceConfig.plugins, function (plugin) { - return plugin.name; }); - plugins.push("autoresize"); + //// pin toolbar to top of screen if we have focus and it scrolls off the screen + //var pinToolbar = function () { - //config value on the data type - var stylesheets = []; + // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); + // var toolbarHeight = _toolbar.height(); - var styleFormats = []; - var await = []; + // var _tinyMce = $(editor.editorContainer); + // var tinyMceRect = _tinyMce[0].getBoundingClientRect(); + // var tinyMceTop = tinyMceRect.top; + // var tinyMceBottom = tinyMceRect.bottom; + // var tinyMceWidth = tinyMceRect.width; - //queue file loading - if (typeof (tinymce) === "undefined") { - await.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope)); - } + // var _tinyMceEditArea = _tinyMce.find(".mce-edit-area"); - var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"]; - if(scope.configuration && scope.configuration.toolbar) { - toolbar = scope.configuration.toolbar; - } - //TODO: get this from the config - var allowedSelectionToolbar = ["bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link"]; - var allowedInsertToolbar = ["link", "image", "umbmediapicker", "umbembeddialog", "umbmacro", "bullist", "numlist"]; - var insertToolbar = _.filter(toolbar, function (t) { - return allowedInsertToolbar.indexOf(t) !== -1; - }).join(" | "); - var selectionToolbar = _.filter(toolbar, function (t) { - return allowedSelectionToolbar.indexOf(t) !== -1; - }).join(" | "); + // // set padding in top of mce so the content does not "jump" up + // _tinyMceEditArea.css("padding-top", toolbarHeight); - if(scope.configuration && scope.configuration.stylesheets){ - angular.forEach(scope.configuration.stylesheets, function(stylesheet, key){ + // if (tinyMceTop < 160 && ((160 + toolbarHeight) < tinyMceBottom)) { + // _toolbar + // .css("visibility", "visible") + // .css("position", "fixed") + // .css("top", "160px") + // .css("margin-top", "0") + // .css("width", tinyMceWidth); + // } else { + // _toolbar + // .css("visibility", "visible") + // .css("position", "absolute") + // .css("top", "auto") + // .css("margin-top", "0") + // .css("width", tinyMceWidth); + // } - stylesheets.push(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/" + stylesheet + ".css"); - await.push(stylesheetResource.getRulesByName(stylesheet).then(function (rules) { - angular.forEach(rules, function (rule) { - var r = {}; - var split = ""; - r.title = rule.name; - if (rule.selector[0] === ".") { - r.inline = "span"; - r.classes = rule.selector.substring(1); - }else if (rule.selector[0] === "#") { - //Even though this will render in the style drop down, it will not actually be applied - // to the elements, don't think TinyMCE even supports this and it doesn't really make much sense - // since only one element can have one id. - r.inline = "span"; - r.attributes = { id: rule.selector.substring(1) }; - }else if (rule.selector[0] !== "." && rule.selector.indexOf(".") > -1) { - split = rule.selector.split("."); - r.block = split[0]; - r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(".", " "); - }else if (rule.selector[0] !== "#" && rule.selector.indexOf("#") > -1) { - split = rule.selector.split("#"); - r.block = split[0]; - r.classes = rule.selector.substring(rule.selector.indexOf("#") + 1); - }else { - r.block = rule.selector; - } - styleFormats.push(r); - }); - })); - }); - }else{ - stylesheets.push("views/propertyeditors/grid/config/grid.default.rtestyles.css"); - styleFormats = fallbackStyles; - } + //}; - //stores a reference to the editor - var tinyMceEditor = null; - $q.all(await).then(function () { + //// unpin toolbar to top of screen + //var unpinToolbar = function() { - var uniqueId = scope.uniqueId; + // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); + // var _tinyMce = $(editor.editorContainer); + // var _tinyMceEditArea = _tinyMce.find(".mce-edit-area"); - //create a baseline Config to exten upon - var baseLineConfigObj = { - theme: "inlite", - inline: true, - plugins: plugins, - valid_elements: validElements, - invalid_elements: invalidElements, - extended_valid_elements: extendedValidElements, - menubar: false, - statusbar: false, - relative_urls: false, - insert_toolbar: insertToolbar, - selection_toolbar: selectionToolbar, - content_css: stylesheets, - style_formats: styleFormats, - autoresize_bottom_margin: 0, - //see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix - cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster - }; + // // reset padding in top of mce so the content does not "jump" up + // _tinyMceEditArea.css("padding-top", "0"); + // _toolbar.css("position", "static"); - if (tinyMceConfig.customConfig) { + //}; - //if there is some custom config, we need to see if the string value of each item might actually be json and if so, we need to - // convert it to json instead of having it as a string since this is what tinymce requires - for (var i in tinyMceConfig.customConfig) { - var val = tinyMceConfig.customConfig[i]; - if (val) { - val = val.toString().trim(); - if (val.detectIsJson()) { - try { - tinyMceConfig.customConfig[i] = JSON.parse(val); - //now we need to check if this custom config key is defined in our baseline, if it is we don't want to - //overwrite the baseline config item if it is an array, we want to concat the items in the array, otherwise - //if it's an object it will overwrite the baseline - if (angular.isArray(baseLineConfigObj[i]) && angular.isArray(tinyMceConfig.customConfig[i])) { - //concat it and below this concat'd array will overwrite the baseline in angular.extend - tinyMceConfig.customConfig[i] = baseLineConfigObj[i].concat(tinyMceConfig.customConfig[i]); - } - } - catch (e) { - //cannot parse, we'll just leave it - } - } - } - if (val === "true") { - tinyMceConfig.customConfig[i] = true; - } - if (val === "false") { - tinyMceConfig.customConfig[i] = false; - } + //when we leave the editor (maybe) + editor.on('blur', function (e) { + angularHelper.safeApply(scope, function () { + scope.value = editor.getContent(); + + var _toolbar = $(editor.editorContainer) + .find(".mce-toolbar"); + + if (scope.onBlur) { + scope.onBlur(); } - angular.extend(baseLineConfigObj, tinyMceConfig.customConfig); - } + //unpinToolbar(); + //$('.umb-panel-body').off('scroll', pinToolbar); - //set all the things that user configs should not be able to override - //baseLineConfigObj.elements = uniqueId; - baseLineConfigObj.selector = "#" + scope.uniqueId; - baseLineConfigObj.setup = function (editor) { - - //set the reference - tinyMceEditor = editor; - - - //enable browser based spell checking - editor.on('init', function (e) { - - if (!scope.value) { - scope.value = ""; - } - editor.setContent(scope.value); - - editor.getBody().setAttribute('spellcheck', true); - - //force overflow to hidden to prevent no needed scroll - editor.getBody().style.overflow = "hidden"; - - $timeout(function(){ - if(scope.value === null){ - editor.focus(); - } - }, 400); - - }); - - //// pin toolbar to top of screen if we have focus and it scrolls off the screen - //var pinToolbar = function () { - - // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - // var toolbarHeight = _toolbar.height(); - - // var _tinyMce = $(editor.editorContainer); - // var tinyMceRect = _tinyMce[0].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 < 160 && ((160 + toolbarHeight) < tinyMceBottom)) { - // _toolbar - // .css("visibility", "visible") - // .css("position", "fixed") - // .css("top", "160px") - // .css("margin-top", "0") - // .css("width", tinyMceWidth); - // } else { - // _toolbar - // .css("visibility", "visible") - // .css("position", "absolute") - // .css("top", "auto") - // .css("margin-top", "0") - // .css("width", tinyMceWidth); - // } - - //}; - - //// unpin toolbar to top of screen - //var unpinToolbar = function() { - - // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - // var _tinyMce = $(editor.editorContainer); - // 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"); - - //}; - - //when we leave the editor (maybe) - editor.on('blur', function (e) { - angularHelper.safeApply(scope, function () { - scope.value = editor.getContent(); - - var _toolbar = $(editor.editorContainer) - .find(".mce-toolbar"); - - if(scope.onBlur){ - scope.onBlur(); - } - - //unpinToolbar(); - //$('.umb-panel-body').off('scroll', pinToolbar); - - }); - }); - - // Focus on editor - editor.on('focus', function (e) { - angularHelper.safeApply(scope, function () { - - if(scope.onFocus){ - scope.onFocus(); - } - - //pinToolbar(); - //$('.umb-panel-body').on('scroll', pinToolbar); - - }); - }); - - // Click on editor - editor.on('click', function (e) { - angularHelper.safeApply(scope, function () { - - if(scope.onClick){ - scope.onClick(); - } - - //pinToolbar(); - //$('.umb-panel-body').on('scroll', pinToolbar); - - }); - }); - - // Update model on change, i.e. copy/pasted text, plugins altering content - editor.on('Change', function (e) { - angularHelper.safeApply(scope, function () { - scope.value = editor.getContent(); - }); - }); - - editor.on('ObjectResized', function (e) { - var qs = "?width=" + e.width + "&height=" + e.height; - var srcAttr = $(e.target).attr("src"); - var path = srcAttr.split("?")[0]; - $(e.target).attr("data-mce-src", path + qs); - }); - - //Create the insert link plugin - tinyMceService.createLinkPicker(editor, scope, function(currentTarget, anchorElement){ - if(scope.onLinkPickerClick) { - scope.onLinkPickerClick(editor, currentTarget, anchorElement); - } - }); - - //Create the insert media plugin - tinyMceService.createMediaPicker(editor, scope, function(currentTarget, userData){ - if(scope.onMediaPickerClick) { - scope.onMediaPickerClick(editor, currentTarget, userData); - } - }); - - //Create the embedded plugin - tinyMceService.createInsertEmbeddedMedia(editor, scope, function(){ - if(scope.onEmbedClick) { - scope.onEmbedClick(editor); - } - }); - - //Create the insert macro plugin - tinyMceService.createInsertMacro(editor, scope, function(dialogData){ - if(scope.onMacroPickerClick) { - scope.onMacroPickerClick(editor, dialogData); - } - }); - - }; - - /** Loads in the editor */ - function loadTinyMce() { - - //we need to add a timeout here, to force a redraw so TinyMCE can find - //the elements needed - $timeout(function () { - tinymce.DOM.events.domLoaded = true; - tinymce.init(baseLineConfigObj); - }, 150, false); - } - - loadTinyMce(); - - //here we declare a special method which will be called whenever the value has changed from the server - //this is instead of doing a watch on the model.value = faster - //scope.model.onValueChanged = function (newVal, oldVal) { - // //update the display val again if it has changed from the server; - // tinyMceEditor.setContent(newVal, { format: 'raw' }); - // //we need to manually fire this event since it is only ever fired based on loading from the DOM, this - // // is required for our plugins listening to this event to execute - // tinyMceEditor.fire('LoadContent', null); - //}; - - //listen for formSubmitting event (the result is callback used to remove the event subscription) - var unsubscribe = scope.$on("formSubmitting", function () { - //TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer - // we do parse it out on the server side but would be nice to do that on the client side before as well. - scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null; }); - - //when the element is disposed we need to unsubscribe! - // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom - // element might still be there even after the modal has been hidden. - scope.$on('$destroy', function () { - unsubscribe(); - if (tinyMceEditor !== undefined && tinyMceEditor != null) { - tinyMceEditor.destroy() - } - }); - }); + // Focus on editor + editor.on('focus', function (e) { + angularHelper.safeApply(scope, function () { + + if (scope.onFocus) { + scope.onFocus(); + } + + //pinToolbar(); + //$('.umb-panel-body').on('scroll', pinToolbar); + + }); + }); + + // Click on editor + editor.on('click', function (e) { + angularHelper.safeApply(scope, function () { + + if (scope.onClick) { + scope.onClick(); + } + + //pinToolbar(); + //$('.umb-panel-body').on('scroll', pinToolbar); + + }); + }); + + // Update model on change, i.e. copy/pasted text, plugins altering content + editor.on('Change', function (e) { + angularHelper.safeApply(scope, function () { + scope.value = editor.getContent(); + }); + }); + + editor.on('ObjectResized', function (e) { + var qs = "?width=" + e.width + "&height=" + e.height; + var srcAttr = $(e.target).attr("src"); + var path = srcAttr.split("?")[0]; + $(e.target).attr("data-mce-src", path + qs); + }); + + //Create the insert link plugin + tinyMceService.createLinkPicker(editor, scope, function (currentTarget, anchorElement) { + if (scope.onLinkPickerClick) { + scope.onLinkPickerClick(editor, currentTarget, anchorElement); + } + }); + + //Create the insert media plugin + tinyMceService.createMediaPicker(editor, scope, function (currentTarget, userData) { + if (scope.onMediaPickerClick) { + scope.onMediaPickerClick(editor, currentTarget, userData); + } + }); + + //Create the embedded plugin + tinyMceService.createInsertEmbeddedMedia(editor, scope, function () { + if (scope.onEmbedClick) { + scope.onEmbedClick(editor); + } + }); + + //Create the insert macro plugin + tinyMceService.createInsertMacro(editor, scope, function (dialogData) { + if (scope.onMacroPickerClick) { + scope.onMacroPickerClick(editor, dialogData); + } + }); + + }; + + /** Loads in the editor */ + function loadTinyMce() { + + //we need to add a timeout here, to force a redraw so TinyMCE can find + //the elements needed + $timeout(function () { + tinymce.DOM.events.domLoaded = true; + tinymce.init(tinyMceEditorConfig); + }, 150, false); + } + + loadTinyMce(); + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + //scope.model.onValueChanged = function (newVal, oldVal) { + // //update the display val again if it has changed from the server; + // tinyMceEditor.setContent(newVal, { format: 'raw' }); + // //we need to manually fire this event since it is only ever fired based on loading from the DOM, this + // // is required for our plugins listening to this event to execute + // tinyMceEditor.fire('LoadContent', null); + //}; + + //listen for formSubmitting event (the result is callback used to remove the event subscription) + var unsubscribe = scope.$on("formSubmitting", function () { + //TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer + // we do parse it out on the server side but would be nice to do that on the client side before as well. + scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null; }); - }; + //when the element is disposed we need to unsubscribe! + // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom + // element might still be there even after the modal has been hidden. + scope.$on('$destroy', function () { + unsubscribe(); + if (tinyMceEditor !== undefined && tinyMceEditor != null) { + tinyMceEditor.destroy() + } + }); - initTiny(); + }); } }; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 2a6823528e..c845a5ae72 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -6,9 +6,249 @@ * @description * A service containing all logic for all of the Umbraco TinyMCE plugins */ -function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macroService, $routeParams, umbRequestHelper, angularHelper, userService) { +function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesheetResource, macroResource, macroService, $routeParams, umbRequestHelper, angularHelper, userService) { + + //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]"; + 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" }]; + // these languages are available for localization + var availableLanguages = [ + 'da', + 'de', + 'en', + 'en_us', + 'fi', + 'fr', + 'he', + 'it', + 'ja', + 'nl', + 'no', + 'pl', + 'pt', + 'ru', + 'sv', + 'zh' + ]; + //define fallback language + var defaultLanguage = 'en_us'; + + /** + * Returns a promise of an object containing the stylesheets and styleFormats collections + * @param {any} configuredStylesheets + */ + function getStyles(configuredStylesheets) { + + var stylesheets = []; + var styleFormats = []; + var promises = [$q.when(true)]; //a collection of promises, the first one is an empty promise + + //get the umbraco stylesheet loaded and use that href to inject into tinymce. + //strip off the query string since tiny will append our cache buster itself. + stylesheets.push(_.find(document.styleSheets, function (s) { + return s.href && s.href.indexOf("assets/css/umbraco.css") !== -1 + }).href.split("?")[0]); + + //queue rules loading + if (configuredStylesheets) { + angular.forEach(configuredStylesheets, function (val, key) { + + stylesheets.push(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/" + val + ".css"); + + promises.push(stylesheetResource.getRulesByName(val).then(function (rules) { + angular.forEach(rules, function (rule) { + var r = {}; + r.title = rule.name; + if (rule.selector[0] == ".") { + r.inline = "span"; + r.classes = rule.selector.substring(1); + } + else if (rule.selector[0] === "#") { + r.inline = "span"; + r.attributes = { id: rule.selector.substring(1) }; + } + else if (rule.selector[0] !== "." && rule.selector.indexOf(".") > -1) { + var split = rule.selector.split("."); + r.block = split[0]; + r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(".", " "); + } + else if (rule.selector[0] != "#" && rule.selector.indexOf("#") > -1) { + var split = rule.selector.split("#"); + r.block = split[0]; + r.classes = rule.selector.substring(rule.selector.indexOf("#") + 1); + } + else { + r.block = rule.selector; + } + + styleFormats.push(r); + }); + })); + }); + } + else { + styleFormats = fallbackStyles; + } + + return $q.all(promises).then(function() { + return $q.when({ stylesheets: stylesheets, styleFormats: styleFormats}); + }); + } + + /** Returns the language to use for TinyMCE */ + function getLanguage() { + var language = defaultLanguage; + //get locale from angular and match tinymce format. Angular localization is always in the format of ru-ru, de-de, en-gb, etc. + //wheras tinymce is in the format of ru, de, en, en_us, etc. + var localeId = $locale.id.replace('-', '_'); + //try matching the language using full locale format + var languageMatch = _.find(availableLanguages, function (o) { return o === localeId; }); + //if no matches, try matching using only the language + if (languageMatch === undefined) { + var localeParts = localeId.split('_'); + languageMatch = _.find(availableLanguages, function (o) { return o === localeParts[0]; }); + } + //if a match was found - set the language + if (languageMatch !== undefined) { + language = languageMatch; + } + return language; + } + + 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 + } + } + return { + /** + * Returns a promise of the configuration object to initialize the TinyMCE editor + * @param {} args + * @returns {} + */ + getTinyMceEditorConfig: function (args) { + + var promises = [ + this.configuration(), + getStyles(args.stylesheets) + ]; + + return $q.all(promises).then(function(result) { + + 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"); + + //create a baseline Config to exten upon + var config = { + selector: "#" + args.htmlId, + theme: "inlite", + inline: true, + plugins: plugins, + valid_elements: tinyMceConfig.validElements, + invalid_elements: tinyMceConfig.inValidElements, + extended_valid_elements: extendedValidElements, + menubar: false, + statusbar: false, + relative_urls: false, + autoresize_bottom_margin: 0, + content_css: styles.stylesheets, + style_formats: styles.styleFormats, + language: getLanguage(), + + //this would be for a theme other than inlite + toolbar: args.toolbar, + //these are for the inlite theme to work + insert_toolbar: toolbars.insertToolbar, + selection_toolbar: toolbars.selectionToolbar, + + body_class: 'umb-rte', + //see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix + cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster + }; + + if (tinyMceConfig.customConfig) { + + //if there is some custom config, we need to see if the string value of each item might actually be json and if so, we need to + // convert it to json instead of having it as a string since this is what tinymce requires + for (var i in tinyMceConfig.customConfig) { + var val = tinyMceConfig.customConfig[i]; + if (val) { + val = val.toString().trim(); + if (val.detectIsJson()) { + try { + tinyMceConfig.customConfig[i] = JSON.parse(val); + //now we need to check if this custom config key is defined in our baseline, if it is we don't want to + //overwrite the baseline config item if it is an array, we want to concat the items in the array, otherwise + //if it's an object it will overwrite the baseline + if (angular.isArray(config[i]) && angular.isArray(tinyMceConfig.customConfig[i])) { + //concat it and below this concat'd array will overwrite the baseline in angular.extend + tinyMceConfig.customConfig[i] = config[i].concat(tinyMceConfig.customConfig[i]); + } + } + catch (e) { + //cannot parse, we'll just leave it + } + } + if (val === "true") { + tinyMceConfig.customConfig[i] = true; + } + if (val === "false") { + tinyMceConfig.customConfig[i] = false; + } + } + } + + angular.extend(config, tinyMceConfig.customConfig); + } + + + return $q.when(config); + + }); + + }, + /** * @ngdoc method * @name umbraco.services.tinyMceService#configuration @@ -285,6 +525,8 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * If we change the selection inside this method, then we end up in an infinite loop, so we have to remove ourselves * from the event listener before changing selection, however, it seems that putting a break point in this method * will always cause an 'infinite' loop as the caret keeps changing. + * + * TODO: I don't think we need this anymore with recent tinymce fixes: https://www.tiny.cloud/docs/plugins/noneditable/ */ function onNodeChanged(evt) { @@ -325,7 +567,11 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro }); - /** This prevents any other commands from executing when the current element is the macro so the content cannot be edited */ + /** + * This prevents any other commands from executing when the current element is the macro so the content cannot be edited + * + * TODO: I don't think we need this anymore with recent tinymce fixes: https://www.tiny.cloud/docs/plugins/noneditable/ + */ editor.on('BeforeExecCommand', function (o) { if (isOnMacroElement) { if (o.preventDefault) { @@ -338,7 +584,11 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro } }); - /** This double checks and ensures you can't paste content into the rendered macro */ + /** + * This double checks and ensures you can't paste content into the rendered macro + * + * TODO: I don't think we need this anymore with recent tinymce fixes: https://www.tiny.cloud/docs/plugins/noneditable/ + */ editor.on("Paste", function (o) { if (isOnMacroElement) { if (o.preventDefault) { @@ -358,6 +608,8 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro * Listen for the keydown in the editor, we'll check if we are currently on a macro element, if so * we'll check if the key down is a supported key which requires an action, otherwise we ignore the request * so the macro cannot be edited. + * + * TODO: I don't think we need this anymore with recent tinymce fixes: https://www.tiny.cloud/docs/plugins/noneditable/ */ editor.on('KeyDown', function (e) { if (isOnMacroElement) { @@ -457,9 +709,10 @@ function tinyMceService($log, imageHelper, $http, $timeout, macroResource, macro var macroSyntaxComment = ""; //create an id class for this element so we can re-select it after inserting var uniqueId = "umb-macro-" + editor.dom.uniqueId(); - var macroDiv = editor.dom.create('div', { - 'class': 'umb-macro-holder ' + macroObject.macroAlias + ' mceNonEditable ' + uniqueId - }, + var macroDiv = editor.dom.create('div', + { + 'class': 'umb-macro-holder ' + macroObject.macroAlias + ' mceNonEditable ' + uniqueId + }, macroSyntaxComment + 'Macro alias: ' + macroObject.macroAlias + ''); editor.selection.setNode(macroDiv); diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index b18f2c942f..809852d76e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -57,6 +57,7 @@ // Application wide styles (refactor is WIP) @import "application/grid.less"; +@import "rte.less"; @import "application/shadows.less"; @import "application/animations.less"; diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less new file mode 100644 index 0000000000..341e8839af --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -0,0 +1,53 @@ +// Styles for the RTE, the whole stylesheet is used in Tiny and these are specific to it's content +// ------------------------- + +.umb-rte { + overflow: hidden; +} +.umb-rte .mce-content-body { + padding:10px; + background-color: #fff; + font-size: 14px; + line-height: 1.5em; + scrollbar-3dlight-color: #f0f0ee; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #f0f0ee; + scrollbar-darkshadow-color: #ddd; + scrollbar-face-color: #e0e0dd; + scrollbar-highlight-color: #f0f0ee; + scrollbar-shadow-color: #f0f0ee; + scrollbar-track-color: #f5f5f5; +} + +/* loader for macro loading in tinymce*/ +.umb-rte .mce-content-body .umb-macro-holder.loading { + background: url(img/loader.gif) right no-repeat; + -moz-background-size: 18px; + -o-background-size: 18px; + -webkit-background-size: 18px; + background-size: 18px; + background-position-x: 99%; +} + +/* This used to be in place but I'm not sure its needed ... */ + +/* TINYMCE IMAGE RESIZING LIMITS */ +/*#mceResizeHandlen, #mceResizeHandles, #mceResizeHandlee, #mceResizeHandlew { + display: none !important; + visibility: hidden !important; +}*/ + +/*body.mce-content-body { + background: transparent !important; + overflow-x: hidden !important; + padding-bottom: 10px !important; +} + +p { + margin: 0 0 10px; +} + +.button { + display: inline-block; + border-radius: 4px; +}*/ diff --git a/src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html b/src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html new file mode 100644 index 0000000000..f3b854a062 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/grid/grid-rte.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.rtestyles.css b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.rtestyles.css deleted file mode 100644 index 3837788d2d..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/config/grid.default.rtestyles.css +++ /dev/null @@ -1,15 +0,0 @@ -body.mce-content-body { - background: transparent !important; - overflow-x:hidden !important; - padding-bottom: 10px !important; - /*margin:0px;*/ -} - -p { - margin: 0 0 10px; -} - -.button { - display: inline-block; - border-radius:4px; -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 1be54073a2..d190076f4b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -1,205 +1,62 @@ angular.module("umbraco") .controller("Umbraco.PropertyEditors.RTEController", - function ($rootScope, $scope, $q, $locale, dialogService, $log, imageHelper, assetsService, $timeout, tinyMceService, angularHelper, stylesheetResource, macroService, editorState) { + function ($rootScope, $scope, $q, $locale, dialogService, $log, imageHelper, assetsService, $timeout, tinyMceService, angularHelper, stylesheetResource, macroService, editorState) { - $scope.isLoading = true; + //TODO: A lot of the code below should be shared between the grid rte and the normal rte - //To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias - // because now we have to support having 2x (maybe more at some stage) content editors being displayed at once. This is because - // we have this mini content editor panel that can be launched with MNTP. - var d = new Date(); - var n = d.getTime(); - $scope.textAreaHtmlId = $scope.model.alias + "_" + n + "_rte"; - - function syncContent(editor){ - angularHelper.safeApply($scope, function () { - $scope.model.value = editor.getContent(); - }); - } + $scope.isLoading = true; - tinyMceService.configuration().then(function (tinyMceConfig) { + //To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias + // because now we have to support having 2x (maybe more at some stage) content editors being displayed at once. This is because + // we have this mini content editor panel that can be launched with MNTP. + var d = new Date(); + var n = d.getTime(); + $scope.textAreaHtmlId = $scope.model.alias + "_" + n + "_rte"; - //config value from general tinymce.config file - var validElements = tinyMceConfig.validElements; - - //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],span[id|class|style]"; - - var invalidElements = tinyMceConfig.inValidElements; - var plugins = _.map(tinyMceConfig.plugins, - function(plugin) { - return plugin.name; + function syncContent(editor) { + angularHelper.safeApply($scope, function () { + $scope.model.value = editor.getContent(); }); + } var editorConfig = $scope.model.config.editor; if (!editorConfig || angular.isString(editorConfig)) { editorConfig = tinyMceService.defaultPrevalues(); } - - //config value on the data type - var toolbar = editorConfig.toolbar; - //TODO: get this from the config - var allowedSelectionToolbar = ["bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link"]; - var allowedInsertToolbar = ["link", "image", "umbmediapicker", "umbembeddialog", "umbmacro", "bullist", "numlist"]; - var insertToolbar = _.filter(editorConfig.toolbar, function (t) { - return allowedInsertToolbar.indexOf(t) !== -1; - }).join(" | "); - var selectionToolbar = _.filter(editorConfig.toolbar, function(t) { - return allowedSelectionToolbar.indexOf(t) !== -1; - }).join(" | "); - - var stylesheets = []; - var styleFormats = []; - var await = []; + + var promises = []; if (!editorConfig.maxImageSize && editorConfig.maxImageSize != 0) { editorConfig.maxImageSize = tinyMceService.defaultPrevalues().maxImageSize; } //queue file loading if (typeof tinymce === "undefined") { // Don't reload tinymce if already loaded - await.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope)); + promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope)); } - //queue rules loading - angular.forEach(editorConfig.stylesheets, function (val, key) { - stylesheets.push(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/" + val + ".css?" + new Date().getTime()); - await.push(stylesheetResource.getRulesByName(val).then(function (rules) { - angular.forEach(rules, function (rule) { - var r = {}; - r.title = rule.name; - if (rule.selector[0] == ".") { - r.inline = "span"; - r.classes = rule.selector.substring(1); - } - else if (rule.selector[0] == "#") { - r.inline = "span"; - r.attributes = { id: rule.selector.substring(1) }; - } - else if (rule.selector[0] != "." && rule.selector.indexOf(".") > -1) { - var split = rule.selector.split("."); - r.block = split[0]; - r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(".", " "); - } - else if (rule.selector[0] != "#" && rule.selector.indexOf("#") > -1) { - var split = rule.selector.split("#"); - r.block = split[0]; - r.classes = rule.selector.substring(rule.selector.indexOf("#") + 1); - } - else { - r.block = rule.selector; - } - - styleFormats.push(r); - }); - })); - }); - - //stores a reference to the editor var tinyMceEditor = null; - // these languages are available for localization - var availableLanguages = [ - 'da', - 'de', - 'en', - 'en_us', - 'fi', - 'fr', - 'he', - 'it', - 'ja', - 'nl', - 'no', - 'pl', - 'pt', - 'ru', - 'sv', - 'zh' - ]; - - //define fallback language - var language = 'en_us'; - //get locale from angular and match tinymce format. Angular localization is always in the format of ru-ru, de-de, en-gb, etc. - //wheras tinymce is in the format of ru, de, en, en_us, etc. - var localeId = $locale.id.replace('-', '_'); - //try matching the language using full locale format - var languageMatch = _.find(availableLanguages, function(o) { return o === localeId; }); - //if no matches, try matching using only the language - if (languageMatch === undefined) { - var localeParts = localeId.split('_'); - languageMatch = _.find(availableLanguages, function(o) { return o === localeParts[0]; }); - } - //if a match was found - set the language - if (languageMatch !== undefined) { - language = languageMatch; - } + promises.push(tinyMceService.getTinyMceEditorConfig({ + htmlId: $scope.textAreaHtmlId, + stylesheets: editorConfig.stylesheets, + toolbar: editorConfig.toolbar + })); //wait for queue to end - $q.all(await).then(function () { - + $q.all(promises).then(function (result) { + + var standardConfig = result[promises.length - 1]; + //create a baseline Config to exten upon var baseLineConfigObj = { - theme: "inlite", - inline: true, - plugins: plugins, - valid_elements: validElements, - invalid_elements: invalidElements, - extended_valid_elements: extendedValidElements, - menubar: false, - statusbar: false, - relative_urls: false, height: editorConfig.dimensions.height, width: editorConfig.dimensions.width, - maxImageSize: editorConfig.maxImageSize, - insert_toolbar: insertToolbar, - selection_toolbar: selectionToolbar, - content_css: stylesheets, - style_formats: styleFormats, - language: language, - //see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix - cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster + maxImageSize: editorConfig.maxImageSize }; - if (tinyMceConfig.customConfig) { + angular.extend(baseLineConfigObj, standardConfig); - //if there is some custom config, we need to see if the string value of each item might actually be json and if so, we need to - // convert it to json instead of having it as a string since this is what tinymce requires - for (var i in tinyMceConfig.customConfig) { - var val = tinyMceConfig.customConfig[i]; - if (val) { - val = val.toString().trim(); - if (val.detectIsJson()) { - try { - tinyMceConfig.customConfig[i] = JSON.parse(val); - //now we need to check if this custom config key is defined in our baseline, if it is we don't want to - //overwrite the baseline config item if it is an array, we want to concat the items in the array, otherwise - //if it's an object it will overwrite the baseline - if (angular.isArray(baseLineConfigObj[i]) && angular.isArray(tinyMceConfig.customConfig[i])) { - //concat it and below this concat'd array will overwrite the baseline in angular.extend - tinyMceConfig.customConfig[i] = baseLineConfigObj[i].concat(tinyMceConfig.customConfig[i]); - } - } - catch (e) { - //cannot parse, we'll just leave it - } - } - if (val === "true") { - tinyMceConfig.customConfig[i] = true; - } - if (val === "false") { - tinyMceConfig.customConfig[i] = false; - } - } - } - - angular.extend(baseLineConfigObj, tinyMceConfig.customConfig); - } - - //set all the things that user configs should not be able to override - //baseLineConfigObj.elements = $scope.textAreaHtmlId; //this is the exact textarea id to replace! - baseLineConfigObj.selector = "#" + $scope.textAreaHtmlId; baseLineConfigObj.setup = function (editor) { //set the reference @@ -210,7 +67,7 @@ angular.module("umbraco") editor.setContent($scope.model.value); editor.getBody().setAttribute('spellcheck', true); }); - + editor.on('Dirty', function (e) { //make the form dirty manually so that the track changes works, setting our model doesn't trigger // the angular bits because tinymce replaces the textarea. @@ -219,13 +76,10 @@ angular.module("umbraco") }); editor.on('Change', function (e) { - console.log("Change..."); syncContent(editor); }); editor.on('ObjectResized', function (e) { - console.log("ObjectResized..."); - var qs = "?width=" + e.width + "&height=" + e.height + "&mode=max"; var srcAttr = $(e.target).attr("src"); var path = srcAttr.split("?")[0]; @@ -233,14 +87,14 @@ angular.module("umbraco") syncContent(editor); }); - - tinyMceService.createLinkPicker(editor, $scope, function(currentTarget, anchorElement) { + + tinyMceService.createLinkPicker(editor, $scope, function (currentTarget, anchorElement) { $scope.linkPickerOverlay = { view: "linkpicker", currentTarget: currentTarget, - anchors: tinyMceService.getAnchorNames(JSON.stringify(editorState.current.properties)), + anchors: tinyMceService.getAnchorNames(JSON.stringify(editorState.current.properties)), show: true, - submit: function(model) { + submit: function (model) { tinyMceService.insertLinkInEditor(editor, model.target, anchorElement); $scope.linkPickerOverlay.show = false; $scope.linkPickerOverlay = null; @@ -249,7 +103,7 @@ angular.module("umbraco") }); //Create the insert media plugin - tinyMceService.createMediaPicker(editor, $scope, function(currentTarget, userData){ + tinyMceService.createMediaPicker(editor, $scope, function (currentTarget, userData) { $scope.mediaPickerOverlay = { currentTarget: currentTarget, @@ -260,7 +114,7 @@ angular.module("umbraco") startNodeIsVirtual: userData.startMediaIds.length !== 1, view: "mediapicker", show: true, - submit: function(model) { + submit: function (model) { tinyMceService.insertMediaInEditor(editor, model.selectedImages[0]); $scope.mediaPickerOverlay.show = false; $scope.mediaPickerOverlay = null; @@ -268,31 +122,31 @@ angular.module("umbraco") }; }); - - //Create the embedded plugin - tinyMceService.createInsertEmbeddedMedia(editor, $scope, function() { - $scope.embedOverlay = { - view: "embed", - show: true, - submit: function(model) { - tinyMceService.insertEmbeddedMediaInEditor(editor, model.embed.preview); - $scope.embedOverlay.show = false; - $scope.embedOverlay = null; - } - }; + //Create the embedded plugin + tinyMceService.createInsertEmbeddedMedia(editor, $scope, function () { + + $scope.embedOverlay = { + view: "embed", + show: true, + submit: function (model) { + tinyMceService.insertEmbeddedMediaInEditor(editor, model.embed.preview); + $scope.embedOverlay.show = false; + $scope.embedOverlay = null; + } + }; }); //Create the insert macro plugin - tinyMceService.createInsertMacro(editor, $scope, function(dialogData) { + tinyMceService.createInsertMacro(editor, $scope, function (dialogData) { $scope.macroPickerOverlay = { view: "macropicker", dialogData: dialogData, show: true, - submit: function(model) { + submit: function (model) { var macroObject = macroService.collectValueData(model.selectedMacro, model.macroParams, dialogData.renderingEngine); tinyMceService.insertMacroInEditor(editor, macroObject, $scope); $scope.macroPickerOverlay.show = false; @@ -302,7 +156,7 @@ angular.module("umbraco") }); }; - + /** Loads in the editor */ function loadTinyMce() { @@ -345,11 +199,10 @@ angular.module("umbraco") // element might still be there even after the modal has been hidden. $scope.$on('$destroy', function () { unsubscribe(); - if (tinyMceEditor !== undefined && tinyMceEditor != null) { - tinyMceEditor.destroy() - } + if (tinyMceEditor !== undefined && tinyMceEditor != null) { + tinyMceEditor.destroy() + } }); }); - }); - }); + }); diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config index eeb90f9ea6..649be9723f 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config @@ -1,38 +1,40 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + code @@ -42,7 +44,12 @@ charmap table lists + advlist hr + autolink + directionality + tabfocus + searchreplace - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + code @@ -42,7 +44,12 @@ charmap table lists + advlist hr + autolink + directionality + tabfocus + searchreplace ("name") ?? alias, Alias = alias, + Mode = Enum.Parse(n.AttributeValue("mode"), true) } ); } From 926fef43d0022da05bb6e0c4b4ef0f76975dbada Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 11 Oct 2018 14:07:04 +0200 Subject: [PATCH 005/337] Fixes merge issues --- src/Umbraco.Web.UI.Client/bower.json | 1 - src/Umbraco.Web.UI.Client/package-lock.json | 484 +++++++++--------- .../propertyeditors/grid/grid.controller.js | 4 +- .../propertyeditors/rte/rte.controller.js | 4 +- 4 files changed, 240 insertions(+), 253 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/bower.json b/src/Umbraco.Web.UI.Client/bower.json index 4076f95f89..61b54f6c1c 100644 --- a/src/Umbraco.Web.UI.Client/bower.json +++ b/src/Umbraco.Web.UI.Client/bower.json @@ -90,7 +90,6 @@ "jquery-ui": "bower_components/jquery-ui/jquery-ui.min.js", "jquery-migrate": "bower_components/jquery-migrate/jquery-migrate.min.js", "clipboard": "bower_components/clipboard/dist/clipboard.min.js", - "animejs": "bower_components/animejs/anime.min.js" "animejs": "bower_components/animejs/anime.min.js", "jquery-validate": "bower_components/jquery-validate/dist/jquery.validate.min.js", "jquery-validation-unobtrusive": "bower_components/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js", diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 2bbe8d726d..c5659ccf73 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -862,7 +862,7 @@ "acorn-jsx": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", - "integrity": "sha1-6OQeSOov4MiWdAYQq2pP/YrdIl4=", + "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", "dev": true, "requires": { "acorn": "^5.0.3" @@ -884,7 +884,7 @@ "agent-base": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha1-2J5ZmfeXh1Z0wH2H8mD8Qeg+jKk=", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -945,7 +945,7 @@ "amqplib": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha1-0tcxPH/6pNELzx5iUt5FkbbMe2M=", + "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", "dev": true, "optional": true, "requires": { @@ -958,19 +958,19 @@ }, "angular": { "version": "1.3.20", - "resolved": "http://registry.npmjs.org/angular/-/angular-1.3.20.tgz", + "resolved": "https://registry.npmjs.org/angular/-/angular-1.3.20.tgz", "integrity": "sha1-sjo9fF5/mffZW5tNSbmsNVJpuu4=", "dev": true }, "angular-animate": { "version": "1.3.20", - "resolved": "http://registry.npmjs.org/angular-animate/-/angular-animate-1.3.20.tgz", + "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.3.20.tgz", "integrity": "sha1-0XB8cn+K0N8hxKLewgzX/ElFtSo=", "dev": true }, "ansi-colors": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { @@ -989,7 +989,7 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha1-9zIHu4EgfXX9bIPxJa8m7qN4yjA=", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, "ansi-gray": { @@ -1227,7 +1227,7 @@ "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", "dev": true }, "arrify": { @@ -1267,7 +1267,7 @@ "ast-types": { "version": "0.11.5", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", - "integrity": "sha1-mJCCXWYMA8KDOfMV6foKNg4x7Cg=", + "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", "dev": true, "optional": true }, @@ -1296,7 +1296,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "dev": true }, "asynckit": { @@ -1339,7 +1339,7 @@ }, "axios": { "version": "0.15.3", - "resolved": "http://registry.npmjs.org/axios/-/axios-0.15.3.tgz", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", "dev": true, "optional": true, @@ -1349,7 +1349,7 @@ "dependencies": { "follow-redirects": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", "dev": true, "optional": true, @@ -1446,7 +1446,7 @@ }, "basic-auth": { "version": "1.0.4", - "resolved": "http://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", "integrity": "sha1-Awk1sB3nyblKgksp8/zLdQ06UpA=", "dev": true }, @@ -1670,7 +1670,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2052,7 +2052,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -2406,7 +2406,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2463,7 +2463,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -2529,7 +2529,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2564,7 +2564,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2641,7 +2641,7 @@ "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha1-+XJgj/DOrWi4QaFqky0LGDeRgU4=", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", "dev": true }, "core-util-is": { @@ -2667,7 +2667,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -2782,7 +2782,7 @@ }, "cssnano": { "version": "3.10.0", - "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", "dev": true, "requires": { @@ -2877,7 +2877,7 @@ "data-uri-to-buffer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha1-dxY+qcINhkG0cH6PGKvfmnjzSDU=", + "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", "dev": true, "optional": true }, @@ -3549,7 +3549,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -3894,7 +3894,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, @@ -4030,7 +4030,7 @@ "engine.io": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha1-Dn751pDrCzVZfx1K0Comyi26OEU=", + "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -4061,7 +4061,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -4078,7 +4078,7 @@ "engine.io-client": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha1-W96xMPi5SlCsXL63JYPnpKBj3f0=", + "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -4097,7 +4097,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -4108,7 +4108,7 @@ "engine.io-parser": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha1-TA9M/3mq7su9z96maoI8YIVAkZY=", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", "dev": true, "requires": { "after": "0.8.2", @@ -4204,7 +4204,7 @@ }, "es6-promise": { "version": "3.3.1", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", "dev": true }, @@ -4259,7 +4259,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true } @@ -4403,7 +4403,7 @@ "eslint-scope": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -4413,19 +4413,19 @@ "eslint-utils": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha1-moUbqJ7nxGA0b5fPiTnHKYgn5RI=", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "dev": true }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, "espree": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", - "integrity": "sha1-JTmY8goPgttdhmOFeZ2RKoOjZjQ=", + "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", "dev": true, "requires": { "acorn": "^5.6.0", @@ -4441,7 +4441,7 @@ "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -4450,7 +4450,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -4503,7 +4503,7 @@ "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", "dev": true }, "exec-buffer": { @@ -4767,7 +4767,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -5018,7 +5018,7 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true, "optional": true }, @@ -5070,7 +5070,7 @@ }, "finalhandler": { "version": "0.4.0", - "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", "integrity": "sha1-llpS2ejQXSuFdUhUH7ibU6JJfZs=", "dev": true, "requires": { @@ -5082,7 +5082,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -5361,23 +5361,21 @@ "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -5390,20 +5388,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5444,7 +5439,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -5459,14 +5454,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { @@ -5475,12 +5470,12 @@ "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -5495,7 +5490,7 @@ "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "^2.1.0" } }, "ignore-walk": { @@ -5504,7 +5499,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -5513,15 +5508,14 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5533,9 +5527,8 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -5548,25 +5541,22 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" } }, "minizlib": { @@ -5575,14 +5565,13 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5599,9 +5588,9 @@ "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { @@ -5610,16 +5599,16 @@ "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -5628,8 +5617,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { @@ -5644,8 +5633,8 @@ "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -5654,17 +5643,16 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5676,9 +5664,8 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -5699,8 +5686,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -5721,10 +5708,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -5741,13 +5728,13 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { @@ -5756,7 +5743,7 @@ "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-buffer": { @@ -5798,11 +5785,10 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -5811,7 +5797,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -5819,7 +5805,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -5834,13 +5820,13 @@ "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -5855,7 +5841,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2" } }, "wrappy": { @@ -5947,7 +5933,7 @@ "get-uri": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", - "integrity": "sha1-XHlecTJvbKEoby/IJXXNK6sq9Xg=", + "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", "dev": true, "optional": true, "requires": { @@ -5968,7 +5954,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -5985,7 +5971,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, "requires": { @@ -6126,7 +6112,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -6246,7 +6232,7 @@ }, "lodash": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", "dev": true }, @@ -6373,7 +6359,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -6446,7 +6432,7 @@ }, "gulp-connect": { "version": "5.0.0", - "resolved": "http://registry.npmjs.org/gulp-connect/-/gulp-connect-5.0.0.tgz", + "resolved": "https://registry.npmjs.org/gulp-connect/-/gulp-connect-5.0.0.tgz", "integrity": "sha1-8v3zBq6RFGg2jCKF8teC8T7dr04=", "dev": true, "requires": { @@ -6504,7 +6490,7 @@ "gulp-eslint": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-5.0.0.tgz", - "integrity": "sha1-KiaECV93Syz3kxAmIHjFbMehK1I=", + "integrity": "sha512-9GUqCqh85C7rP9120cpxXuZz2ayq3BZc85pCTuPJS03VQYxne0aWPIXWx6LSvsGPa3uRqtSO537vaugOh+5cXg==", "dev": true, "requires": { "eslint": "^5.0.1", @@ -6713,7 +6699,7 @@ "dependencies": { "ansi-regex": { "version": "0.2.1", - "resolved": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", "dev": true }, @@ -6725,7 +6711,7 @@ }, "chalk": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", "dev": true, "requires": { @@ -6798,7 +6784,7 @@ }, "lodash": { "version": "2.4.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", "integrity": "sha1-W3cjA03aTSYuWkb7LFjXzCL3FCA=", "dev": true }, @@ -6888,13 +6874,13 @@ }, "minimist": { "version": "0.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", "dev": true }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -6906,7 +6892,7 @@ }, "strip-ansi": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", "dev": true, "requires": { @@ -7090,7 +7076,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -7279,7 +7265,7 @@ "has-binary2": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", "dev": true, "requires": { "isarray": "2.0.1" @@ -7414,7 +7400,7 @@ }, "http-errors": { "version": "1.3.1", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", "dev": true, "requires": { @@ -7431,7 +7417,7 @@ "http-proxy": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { "eventemitter3": "^3.0.0", @@ -7442,7 +7428,7 @@ "http-proxy-agent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha1-5IIb7vWyFCogJr1zkm/lN2McVAU=", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "dev": true, "requires": { "agent-base": "4", @@ -7452,7 +7438,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -7490,7 +7476,7 @@ "https-proxy-agent": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { "agent-base": "^4.1.0", @@ -7516,7 +7502,7 @@ }, "iconv-lite": { "version": "0.4.11", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", "integrity": "sha1-LstC/SlHRJIiCaLnxATayHk9it4=", "dev": true }, @@ -7940,7 +7926,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { @@ -8084,7 +8070,7 @@ "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha1-ezUbjo7dTTmV1NBmaA5mTZRpaCQ=", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", "dev": true, "optional": true }, @@ -8143,7 +8129,7 @@ "is-path-in-cwd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha1-WsSLNF72dTOb1sekipEhELJBz1I=", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { "is-path-inside": "^1.0.0" @@ -8231,7 +8217,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-retry-allowed": { @@ -8416,7 +8402,7 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify": { @@ -8448,7 +8434,7 @@ }, "jsonfile": { "version": "2.4.0", - "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { @@ -8500,7 +8486,7 @@ "karma": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.5.tgz", - "integrity": "sha1-NxDHoucbHEOTE/KDhG2I4E5PkYw=", + "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", "dev": true, "requires": { "bluebird": "^3.3.0", @@ -8535,7 +8521,7 @@ "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -8569,7 +8555,7 @@ "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha1-NW/04rDo5D4yLRijckYLvPOszSY=", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -8636,7 +8622,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -8649,7 +8635,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -8667,7 +8653,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "range-parser": { @@ -8679,7 +8665,7 @@ "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "dev": true, "requires": { "bytes": "3.0.0", @@ -8691,7 +8677,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "utils-merge": { @@ -8856,7 +8842,7 @@ "dependencies": { "iconv-lite": { "version": "0.4.15", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", "dev": true } @@ -8892,7 +8878,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -9204,7 +9190,7 @@ "log4js": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.11.0.tgz", - "integrity": "sha1-vzkC7/ZcaSPZzpz70ttUFg40AFo=", + "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", "dev": true, "requires": { "amqplib": "^0.5.2", @@ -9366,7 +9352,7 @@ }, "readable-stream": { "version": "2.0.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "optional": true, @@ -9381,7 +9367,7 @@ }, "request": { "version": "2.75.0", - "resolved": "http://registry.npmjs.org/request/-/request-2.75.0.tgz", + "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", "dev": true, "optional": true, @@ -9475,7 +9461,7 @@ "mailgun-js": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", - "integrity": "sha1-7jmqGNe7WYpc6e3oSvtoHe/IprA=", + "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", "dev": true, "optional": true, "requires": { @@ -9503,7 +9489,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "optional": true, "requires": { @@ -9579,7 +9565,7 @@ }, "marked": { "version": "0.3.2", - "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.2.tgz", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.2.tgz", "integrity": "sha1-AV2xWIZEOPJKZL3WGgQotBhwbQk=", "dev": true }, @@ -9627,7 +9613,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -9745,7 +9731,7 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { @@ -9759,7 +9745,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, @@ -9786,7 +9772,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -9795,7 +9781,7 @@ }, "morgan": { "version": "1.6.1", - "resolved": "http://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", "integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=", "dev": true, "requires": { @@ -9808,7 +9794,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -13131,7 +13117,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "optional": true, @@ -13145,7 +13131,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "optional": true, "requires": { @@ -13162,7 +13148,7 @@ "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "dev": true, "optional": true, "requires": { @@ -13177,7 +13163,7 @@ "pac-resolver": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha1-auoweH2wqJFwTet4AKcip2FabyY=", + "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", "dev": true, "optional": true, "requires": { @@ -13388,7 +13374,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -13505,7 +13491,7 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "posix-character-classes": { @@ -13528,7 +13514,7 @@ }, "postcss-calc": { "version": "5.3.1", - "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", "dev": true, "requires": { @@ -13560,7 +13546,7 @@ }, "postcss-discard-comments": { "version": "2.0.4", - "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "dev": true, "requires": { @@ -13578,7 +13564,7 @@ }, "postcss-discard-empty": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "dev": true, "requires": { @@ -13587,7 +13573,7 @@ }, "postcss-discard-overridden": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "dev": true, "requires": { @@ -13596,7 +13582,7 @@ }, "postcss-discard-unused": { "version": "2.2.3", - "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", "dev": true, "requires": { @@ -13647,7 +13633,7 @@ }, "postcss-merge-idents": { "version": "2.1.7", - "resolved": "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", "dev": true, "requires": { @@ -13686,7 +13672,7 @@ }, "postcss-minify-font-values": { "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", "dev": true, "requires": { @@ -13697,7 +13683,7 @@ }, "postcss-minify-gradients": { "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "dev": true, "requires": { @@ -13707,7 +13693,7 @@ }, "postcss-minify-params": { "version": "1.2.2", - "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", "dev": true, "requires": { @@ -13719,7 +13705,7 @@ }, "postcss-minify-selectors": { "version": "2.1.1", - "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", "dev": true, "requires": { @@ -13731,7 +13717,7 @@ }, "postcss-normalize-charset": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "dev": true, "requires": { @@ -13740,7 +13726,7 @@ }, "postcss-normalize-url": { "version": "3.0.8", - "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", "dev": true, "requires": { @@ -13762,7 +13748,7 @@ }, "postcss-reduce-idents": { "version": "2.4.0", - "resolved": "http://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", "dev": true, "requires": { @@ -13772,7 +13758,7 @@ }, "postcss-reduce-initial": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "dev": true, "requires": { @@ -13781,7 +13767,7 @@ }, "postcss-reduce-transforms": { "version": "1.0.4", - "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", "dev": true, "requires": { @@ -13803,7 +13789,7 @@ }, "postcss-svgo": { "version": "2.1.6", - "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", "dev": true, "requires": { @@ -13815,7 +13801,7 @@ }, "postcss-unique-selectors": { "version": "2.0.2", - "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", "dev": true, "requires": { @@ -13832,7 +13818,7 @@ }, "postcss-zindex": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", "dev": true, "requires": { @@ -13939,7 +13925,7 @@ "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", "dev": true, "optional": true, "requires": { @@ -13992,7 +13978,7 @@ "qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "dev": true }, "qs": { @@ -14061,7 +14047,7 @@ }, "iconv-lite": { "version": "0.4.13", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", "dev": true } @@ -14152,7 +14138,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -14203,7 +14189,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -14233,7 +14219,7 @@ "redis": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha1-ICKI4/WMSfYHnZevehDhMDrhSwI=", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", "dev": true, "optional": true, "requires": { @@ -14245,7 +14231,7 @@ "redis-commands": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", - "integrity": "sha1-RJWIlBTx6IYmEYCxRC5ylWAtg6I=", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", "dev": true, "optional": true }, @@ -14258,7 +14244,7 @@ }, "reduce-css-calc": { "version": "1.3.0", - "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", "dev": true, "requires": { @@ -14338,7 +14324,7 @@ "regexpp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", - "integrity": "sha1-sqdTSoXKGwM7z1zp/45W1OB1U2U=", + "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", "dev": true }, "regexpu-core": { @@ -14470,7 +14456,7 @@ "requestretry": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha1-IT7BAG7rdQ6LjOVBdig9FajVXZQ=", + "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", "dev": true, "optional": true, "requires": { @@ -14690,7 +14676,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "sax": { @@ -14762,7 +14748,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -14832,7 +14818,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -14890,7 +14876,7 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, "shebang-command": { @@ -14939,7 +14925,7 @@ "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" @@ -15120,7 +15106,7 @@ "socket.io-parser": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha1-7S2l7nnxCVUDbj2kE7/X8eTYbI4=", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -15132,7 +15118,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -15159,7 +15145,7 @@ "socks-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", - "integrity": "sha1-WTa/i3B6mTB5xvN9sgkYIb/6ZHM=", + "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", "dev": true, "requires": { "agent-base": "~4.2.0", @@ -15424,7 +15410,7 @@ "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha1-odG3z4PTmvsNYwSaWsv5NJO99ks=", + "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { "date-format": "^1.2.0", @@ -15456,7 +15442,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -15472,7 +15458,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -15489,7 +15475,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -15527,7 +15513,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -15676,7 +15662,7 @@ }, "table": { "version": "4.0.3", - "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { @@ -15813,7 +15799,7 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -15961,7 +15947,7 @@ }, "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -15976,7 +15962,7 @@ }, "iconv-lite": { "version": "0.4.13", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", "dev": true }, @@ -15997,7 +15983,7 @@ "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -16207,7 +16193,7 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", "dev": true }, "unc-path-regex": { @@ -16371,13 +16357,13 @@ "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha1-NSVll+RqWB20eT0M5H+prr/J+r0=", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", "dev": true }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -16470,7 +16456,7 @@ "uws": { "version": "9.14.0", "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha1-+sg4a+/DOno3BcvVjcR7Qwyk3ZU=", + "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", "dev": true, "optional": true }, @@ -16713,7 +16699,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -16852,7 +16838,7 @@ "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { "async-limiter": "~1.0.0", @@ -16888,7 +16874,7 @@ }, "yargs": { "version": "3.10.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index b5b9910465..38e32b7451 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -888,8 +888,8 @@ angular.module("umbraco") angular.forEach($scope.availableEditors, function (value, key) { //If no translation is provided, keep using the editor name from the manifest if (localizationService.dictionary.hasOwnProperty("grid_" + value.alias)) { - localizationService.localize("grid_" + value.alias).then(function(value){ - value.name = value; + localizationService.localize("grid_" + value.alias).then(function(v){ + value.name = v; }); } }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 32a180cdc3..4232e30e07 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -98,7 +98,9 @@ angular.module("umbraco") //set the value and enable browser based spell checking editor.on('init', function (e) { - editor.setContent($scope.model.value); + if ($scope.model.value) { + editor.setContent($scope.model.value); + } editor.getBody().setAttribute('spellcheck', true); }); From f816f19d601d2011e66cc2a8e0a7723c8a923d31 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 11 Oct 2018 14:25:33 +0200 Subject: [PATCH 006/337] Fixes some issues for rte --- src/Umbraco.Web.UI.Client/bower.json | 12 +-- .../propertyeditors/rte/rte.controller.js | 82 +++++++++---------- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/bower.json b/src/Umbraco.Web.UI.Client/bower.json index 61b54f6c1c..084cb1816a 100644 --- a/src/Umbraco.Web.UI.Client/bower.json +++ b/src/Umbraco.Web.UI.Client/bower.json @@ -78,11 +78,13 @@ "bower_components/angular-local-storage/dist/angular-local-storage.min.js", "bower_components/angular-local-storage/dist/angular-local-storage.min.js.map" ], - "tinymce": [ - "bower_components/tinymce/tinymce.min.js", - "bower_components/tinymce/skins/*", - "bower_components/tinymce/themes/*" - ], + "tinymce": { + "mapping": [ + { "bower_components/tinymce/skins/**": "skins" }, + { "bower_components/tinymce/themes/**": "themes" }, + { "bower_components/tinymce/tinymce.min.js": "tinymce.min.js" } + ] + }, "angular-i18n": "bower_components/angular-i18n/angular-locale_*.js", "typeahead.js": "bower_components/typeahead.js/dist/typeahead.bundle.min.js", "rgrove-lazyload": "bower_components/rgrove-lazyload/lazyload.js", diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 4232e30e07..52aa19b659 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -1,6 +1,6 @@ angular.module("umbraco") .controller("Umbraco.PropertyEditors.RTEController", - function ($rootScope, $scope, $q, $locale, dialogService, $log, imageHelper, assetsService, $timeout, tinyMceService, angularHelper, stylesheetResource, macroService, editorState) { + function ($scope, $q, assetsService, $timeout, tinyMceService, angularHelper, editorService, macroService, editorState) { //TODO: A lot of the code below should be shared between the grid rte and the normal rte @@ -15,49 +15,49 @@ angular.module("umbraco") function syncContent(editor) { - //stop watching before we update the value - stopWatch(); + //stop watching before we update the value + stopWatch(); angularHelper.safeApply($scope, function () { $scope.model.value = editor.getContent(); }); - //re-watch the value - startWatch(editor); - } - - 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 - * @param {any} editor - */ - function startWatch(editor) { - unwatch = $scope.$watch("model.value", function (newVal, oldVal) { - if (newVal !== oldVal) { - //update the display val again if it has changed from the server; - //uses an empty string in the editor when the value is null - 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 - // is required for our plugins listening to this event to execute - editor.fire('LoadContent', null); - } - }); - } - - /** Stops the watch on model.value which is done anytime we are manually updating the model.value */ - function stopWatch() { - if (unwatch) { - unwatch(); + //re-watch the value + startWatch(editor); } - } - + 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 + * @param {any} editor + */ + function startWatch(editor) { + unwatch = $scope.$watch("model.value", function (newVal, oldVal) { + if (newVal !== oldVal) { + //update the display val again if it has changed from the server; + //uses an empty string in the editor when the value is null + 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 + // is required for our plugins listening to this event to execute + editor.fire('LoadContent', null); + } + }); + } + + /** Stops the watch on model.value which is done anytime we are manually updating the model.value */ + function stopWatch() { + if (unwatch) { + unwatch(); + } + } + + var editorConfig = $scope.model.config.editor; if (!editorConfig || angular.isString(editorConfig)) { editorConfig = tinyMceService.defaultPrevalues(); } - + var promises = []; if (!editorConfig.maxImageSize && editorConfig.maxImageSize != 0) { editorConfig.maxImageSize = tinyMceService.defaultPrevalues().maxImageSize; @@ -132,7 +132,7 @@ angular.module("umbraco") tinyMceService.insertLinkInEditor(editor, model.target, anchorElement); editorService.close(); }, - close: function() { + close: function () { editorService.close(); } }; @@ -152,7 +152,7 @@ angular.module("umbraco") tinyMceService.insertMediaInEditor(editor, model.selectedImages[0]); editorService.close(); }, - close: function() { + close: function () { editorService.close(); } }; @@ -162,11 +162,11 @@ angular.module("umbraco") //Create the embedded plugin tinyMceService.createInsertEmbeddedMedia(editor, $scope, function () { var embed = { - submit: function(model) { + submit: function (model) { tinyMceService.insertEmbeddedMediaInEditor(editor, model.embed.preview); editorService.close(); }, - close: function() { + close: function () { editorService.close(); } }; @@ -183,7 +183,7 @@ angular.module("umbraco") tinyMceService.insertMacroInEditor(editor, macroObject, $scope); editorService.close(); }, - close: function() { + close: function () { editorService.close(); } }; @@ -208,7 +208,7 @@ angular.module("umbraco") } loadTinyMce(); - + //listen for formSubmitting event (the result is callback used to remove the event subscription) var unsubscribe = $scope.$on("formSubmitting", function () { //TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer @@ -227,7 +227,7 @@ angular.module("umbraco") tinyMceEditor.destroy() } }); - + }); }); From 1902ebd989f26c8d1fa2334f3e75f899c52802f5 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 11 Oct 2018 14:56:22 +0200 Subject: [PATCH 007/337] Fixes issue with umbsetdirtyonchange.directive --- .../directives/validation/umbsetdirtyonchange.directive.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/umbsetdirtyonchange.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/umbsetdirtyonchange.directive.js index c13680a037..d4e77eda05 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/umbsetdirtyonchange.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/umbsetdirtyonchange.directive.js @@ -7,7 +7,7 @@ var formCtrl = ctrls[0]; - if (ctrls.length > 1) { + if (ctrls.length > 1 && ctrls[1]) { //if an ngModel is supplied, assign a render function which is called when the model is changed var modelCtrl = ctrls[1]; var oldRender = modelCtrl.$render; @@ -17,8 +17,9 @@ if (oldRender) { oldRender(); } - }; - } else { + } + } + else { var initValue = attr.umbSetDirtyOnChange; attr.$observe("umbSetDirtyOnChange", function (newValue) { From 1597dce99e344d6f45bb53ae6d9091fc33ae7407 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 11 Oct 2018 15:39:18 +0200 Subject: [PATCH 008/337] Adds pre-value drop down for theme selection --- .../src/common/services/tinymce.service.js | 9 +++- src/Umbraco.Web.UI.Client/src/less/rte.less | 1 + .../propertyeditors/rte/rte.controller.js | 3 +- .../rte/rte.prevalues.controller.js | 3 ++ .../propertyeditors/rte/rte.prevalues.html | 47 +++++++++++-------- 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 4879fdd72b..5f79f921e0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -116,6 +116,11 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh return language; } + /** + * Gets toolbars for the inlite theme + * @param {any} configuredToolbar + * @param {any} tinyMceConfig + */ function getToolbars(configuredToolbar, tinyMceConfig) { //the commands for selection/all @@ -182,7 +187,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //create a baseline Config to exten upon var config = { selector: "#" + args.htmlId, - theme: "inlite", + theme: args.theme ? args.theme : "inlite", inline: true, plugins: plugins, valid_elements: tinyMceConfig.validElements, @@ -197,7 +202,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh language: getLanguage(), //this would be for a theme other than inlite - toolbar: args.toolbar, + toolbar: args.toolbar.join(" "), //these are for the inlite theme to work insert_toolbar: toolbars.insertToolbar, selection_toolbar: toolbars.selectionToolbar, diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index 341e8839af..3413285859 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -29,6 +29,7 @@ background-position-x: 99%; } + /* This used to be in place but I'm not sure its needed ... */ /* TINYMCE IMAGE RESIZING LIMITS */ diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 52aa19b659..c10fd989e8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -74,7 +74,8 @@ angular.module("umbraco") promises.push(tinyMceService.getTinyMceEditorConfig({ htmlId: $scope.textAreaHtmlId, stylesheets: editorConfig.stylesheets, - toolbar: editorConfig.toolbar + toolbar: editorConfig.toolbar, + theme: editorConfig.theme })); //wait for queue to end diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js index 245843ac84..f0fae34628 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js @@ -19,6 +19,9 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", if (!$scope.model.value.maxImageSize && $scope.model.value.maxImageSize != 0) { $scope.model.value.maxImageSize = cfg.maxImageSize; } + if (!$scope.model.value.theme) { + $scope.model.value.theme = "inlite"; + } tinyMceService.configuration().then(function(config){ $scope.tinyMceConfig = config; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html index 4e4b37ba67..4d9b332fcb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html @@ -1,32 +1,32 @@
- -
+ +
-
-
+
+
- -
+ +
-
-
+
+
@@ -38,6 +38,15 @@
Pixels -
+
+
+ + +
+ +
From a275b4713921f24f89957fb517baa27191538feb Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 11 Oct 2018 15:12:05 +0100 Subject: [PATCH 009/337] npm install of tinymce --- src/Umbraco.Web.UI.Client/package-lock.json | 309 ++++++++++---------- src/Umbraco.Web.UI.Client/package.json | 2 +- 2 files changed, 158 insertions(+), 153 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index c5659ccf73..5bfa1b0bc9 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -862,7 +862,7 @@ "acorn-jsx": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", - "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", + "integrity": "sha1-6OQeSOov4MiWdAYQq2pP/YrdIl4=", "dev": true, "requires": { "acorn": "^5.0.3" @@ -884,7 +884,7 @@ "agent-base": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "integrity": "sha1-2J5ZmfeXh1Z0wH2H8mD8Qeg+jKk=", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -945,7 +945,7 @@ "amqplib": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", + "integrity": "sha1-0tcxPH/6pNELzx5iUt5FkbbMe2M=", "dev": true, "optional": true, "requires": { @@ -958,19 +958,19 @@ }, "angular": { "version": "1.3.20", - "resolved": "https://registry.npmjs.org/angular/-/angular-1.3.20.tgz", + "resolved": "http://registry.npmjs.org/angular/-/angular-1.3.20.tgz", "integrity": "sha1-sjo9fF5/mffZW5tNSbmsNVJpuu4=", "dev": true }, "angular-animate": { "version": "1.3.20", - "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.3.20.tgz", + "resolved": "http://registry.npmjs.org/angular-animate/-/angular-animate-1.3.20.tgz", "integrity": "sha1-0XB8cn+K0N8hxKLewgzX/ElFtSo=", "dev": true }, "ansi-colors": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { @@ -989,7 +989,7 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "integrity": "sha1-9zIHu4EgfXX9bIPxJa8m7qN4yjA=", "dev": true }, "ansi-gray": { @@ -1227,7 +1227,7 @@ "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", "dev": true }, "arrify": { @@ -1267,7 +1267,7 @@ "ast-types": { "version": "0.11.5", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", - "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", + "integrity": "sha1-mJCCXWYMA8KDOfMV6foKNg4x7Cg=", "dev": true, "optional": true }, @@ -1296,7 +1296,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", "dev": true }, "asynckit": { @@ -1339,7 +1339,7 @@ }, "axios": { "version": "0.15.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.15.3.tgz", "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", "dev": true, "optional": true, @@ -1349,7 +1349,7 @@ "dependencies": { "follow-redirects": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", "dev": true, "optional": true, @@ -1446,7 +1446,7 @@ }, "basic-auth": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", "integrity": "sha1-Awk1sB3nyblKgksp8/zLdQ06UpA=", "dev": true }, @@ -1670,7 +1670,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2052,7 +2052,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -2406,7 +2406,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2463,7 +2463,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -2529,7 +2529,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2564,7 +2564,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2641,7 +2641,7 @@ "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "integrity": "sha1-+XJgj/DOrWi4QaFqky0LGDeRgU4=", "dev": true }, "core-util-is": { @@ -2667,7 +2667,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -2782,7 +2782,7 @@ }, "cssnano": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", "dev": true, "requires": { @@ -2877,7 +2877,7 @@ "data-uri-to-buffer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", + "integrity": "sha1-dxY+qcINhkG0cH6PGKvfmnjzSDU=", "dev": true, "optional": true }, @@ -3549,7 +3549,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", "dev": true, "requires": { "esutils": "^2.0.2" @@ -3894,7 +3894,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, @@ -4030,7 +4030,7 @@ "engine.io": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "integrity": "sha1-Dn751pDrCzVZfx1K0Comyi26OEU=", "dev": true, "requires": { "accepts": "~1.3.4", @@ -4061,7 +4061,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -4078,7 +4078,7 @@ "engine.io-client": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "integrity": "sha1-W96xMPi5SlCsXL63JYPnpKBj3f0=", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -4097,7 +4097,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -4108,7 +4108,7 @@ "engine.io-parser": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "integrity": "sha1-TA9M/3mq7su9z96maoI8YIVAkZY=", "dev": true, "requires": { "after": "0.8.2", @@ -4204,7 +4204,7 @@ }, "es6-promise": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", "dev": true }, @@ -4259,7 +4259,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true, "optional": true } @@ -4403,7 +4403,7 @@ "eslint-scope": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -4413,19 +4413,19 @@ "eslint-utils": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "integrity": "sha1-moUbqJ7nxGA0b5fPiTnHKYgn5RI=", "dev": true }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", "dev": true }, "espree": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", - "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", + "integrity": "sha1-JTmY8goPgttdhmOFeZ2RKoOjZjQ=", "dev": true, "requires": { "acorn": "^5.6.0", @@ -4441,7 +4441,7 @@ "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -4450,7 +4450,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -4503,7 +4503,7 @@ "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", "dev": true }, "exec-buffer": { @@ -4767,7 +4767,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -5018,7 +5018,7 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", "dev": true, "optional": true }, @@ -5070,7 +5070,7 @@ }, "finalhandler": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", "integrity": "sha1-llpS2ejQXSuFdUhUH7ibU6JJfZs=", "dev": true, "requires": { @@ -5082,7 +5082,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -5933,7 +5933,7 @@ "get-uri": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", - "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", + "integrity": "sha1-XHlecTJvbKEoby/IJXXNK6sq9Xg=", "dev": true, "optional": true, "requires": { @@ -5954,7 +5954,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -5971,7 +5971,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "optional": true, "requires": { @@ -6112,7 +6112,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -6232,7 +6232,7 @@ }, "lodash": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", "dev": true }, @@ -6359,7 +6359,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -6432,7 +6432,7 @@ }, "gulp-connect": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gulp-connect/-/gulp-connect-5.0.0.tgz", + "resolved": "http://registry.npmjs.org/gulp-connect/-/gulp-connect-5.0.0.tgz", "integrity": "sha1-8v3zBq6RFGg2jCKF8teC8T7dr04=", "dev": true, "requires": { @@ -6490,7 +6490,7 @@ "gulp-eslint": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-5.0.0.tgz", - "integrity": "sha512-9GUqCqh85C7rP9120cpxXuZz2ayq3BZc85pCTuPJS03VQYxne0aWPIXWx6LSvsGPa3uRqtSO537vaugOh+5cXg==", + "integrity": "sha1-KiaECV93Syz3kxAmIHjFbMehK1I=", "dev": true, "requires": { "eslint": "^5.0.1", @@ -6699,7 +6699,7 @@ "dependencies": { "ansi-regex": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "resolved": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", "dev": true }, @@ -6711,7 +6711,7 @@ }, "chalk": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", "dev": true, "requires": { @@ -6784,7 +6784,7 @@ }, "lodash": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", + "resolved": "http://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", "integrity": "sha1-W3cjA03aTSYuWkb7LFjXzCL3FCA=", "dev": true }, @@ -6874,13 +6874,13 @@ }, "minimist": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", "dev": true }, "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -6892,7 +6892,7 @@ }, "strip-ansi": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", "dev": true, "requires": { @@ -7076,7 +7076,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -7265,7 +7265,7 @@ "has-binary2": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=", "dev": true, "requires": { "isarray": "2.0.1" @@ -7400,7 +7400,7 @@ }, "http-errors": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", "dev": true, "requires": { @@ -7417,7 +7417,7 @@ "http-proxy": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", "dev": true, "requires": { "eventemitter3": "^3.0.0", @@ -7428,7 +7428,7 @@ "http-proxy-agent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "integrity": "sha1-5IIb7vWyFCogJr1zkm/lN2McVAU=", "dev": true, "requires": { "agent-base": "4", @@ -7438,7 +7438,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -7476,7 +7476,7 @@ "https-proxy-agent": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=", "dev": true, "requires": { "agent-base": "^4.1.0", @@ -7502,7 +7502,7 @@ }, "iconv-lite": { "version": "0.4.11", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", + "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", "integrity": "sha1-LstC/SlHRJIiCaLnxATayHk9it4=", "dev": true }, @@ -7926,7 +7926,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { @@ -8070,7 +8070,7 @@ "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "integrity": "sha1-ezUbjo7dTTmV1NBmaA5mTZRpaCQ=", "dev": true, "optional": true }, @@ -8129,7 +8129,7 @@ "is-path-in-cwd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "integrity": "sha1-WsSLNF72dTOb1sekipEhELJBz1I=", "dev": true, "requires": { "is-path-inside": "^1.0.0" @@ -8217,7 +8217,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", "dev": true }, "is-retry-allowed": { @@ -8402,7 +8402,7 @@ "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==", + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", "dev": true }, "json-stable-stringify": { @@ -8434,7 +8434,7 @@ }, "jsonfile": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { @@ -8486,7 +8486,7 @@ "karma": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.5.tgz", - "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", + "integrity": "sha1-NxDHoucbHEOTE/KDhG2I4E5PkYw=", "dev": true, "requires": { "bluebird": "^3.3.0", @@ -8521,7 +8521,7 @@ "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -8555,7 +8555,7 @@ "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "integrity": "sha1-NW/04rDo5D4yLRijckYLvPOszSY=", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -8622,7 +8622,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -8635,7 +8635,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -8653,7 +8653,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", "dev": true }, "range-parser": { @@ -8665,7 +8665,7 @@ "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", "dev": true, "requires": { "bytes": "3.0.0", @@ -8677,7 +8677,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true }, "utils-merge": { @@ -8842,7 +8842,7 @@ "dependencies": { "iconv-lite": { "version": "0.4.15", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", "dev": true } @@ -8878,7 +8878,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -9190,7 +9190,7 @@ "log4js": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.11.0.tgz", - "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", + "integrity": "sha1-vzkC7/ZcaSPZzpz70ttUFg40AFo=", "dev": true, "requires": { "amqplib": "^0.5.2", @@ -9352,7 +9352,7 @@ }, "readable-stream": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "optional": true, @@ -9367,7 +9367,7 @@ }, "request": { "version": "2.75.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", + "resolved": "http://registry.npmjs.org/request/-/request-2.75.0.tgz", "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", "dev": true, "optional": true, @@ -9461,7 +9461,7 @@ "mailgun-js": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", - "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", + "integrity": "sha1-7jmqGNe7WYpc6e3oSvtoHe/IprA=", "dev": true, "optional": true, "requires": { @@ -9489,7 +9489,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "optional": true, "requires": { @@ -9565,7 +9565,7 @@ }, "marked": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.2.tgz", + "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.2.tgz", "integrity": "sha1-AV2xWIZEOPJKZL3WGgQotBhwbQk=", "dev": true }, @@ -9613,7 +9613,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -9731,7 +9731,7 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", "dev": true }, "minimatch": { @@ -9745,7 +9745,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, @@ -9772,7 +9772,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -9781,7 +9781,7 @@ }, "morgan": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", + "resolved": "http://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", "integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=", "dev": true, "requires": { @@ -9794,7 +9794,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -13117,7 +13117,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "optional": true, @@ -13131,7 +13131,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", "dev": true, "optional": true, "requires": { @@ -13148,7 +13148,7 @@ "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", "dev": true, "optional": true, "requires": { @@ -13163,7 +13163,7 @@ "pac-resolver": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", + "integrity": "sha1-auoweH2wqJFwTet4AKcip2FabyY=", "dev": true, "optional": true, "requires": { @@ -13374,7 +13374,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -13491,7 +13491,7 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", "dev": true }, "posix-character-classes": { @@ -13514,7 +13514,7 @@ }, "postcss-calc": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", "dev": true, "requires": { @@ -13546,7 +13546,7 @@ }, "postcss-discard-comments": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "dev": true, "requires": { @@ -13564,7 +13564,7 @@ }, "postcss-discard-empty": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "dev": true, "requires": { @@ -13573,7 +13573,7 @@ }, "postcss-discard-overridden": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "dev": true, "requires": { @@ -13582,7 +13582,7 @@ }, "postcss-discard-unused": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", "dev": true, "requires": { @@ -13633,7 +13633,7 @@ }, "postcss-merge-idents": { "version": "2.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "resolved": "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", "dev": true, "requires": { @@ -13672,7 +13672,7 @@ }, "postcss-minify-font-values": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", "dev": true, "requires": { @@ -13683,7 +13683,7 @@ }, "postcss-minify-gradients": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "dev": true, "requires": { @@ -13693,7 +13693,7 @@ }, "postcss-minify-params": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", "dev": true, "requires": { @@ -13705,7 +13705,7 @@ }, "postcss-minify-selectors": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", "dev": true, "requires": { @@ -13717,7 +13717,7 @@ }, "postcss-normalize-charset": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "dev": true, "requires": { @@ -13726,7 +13726,7 @@ }, "postcss-normalize-url": { "version": "3.0.8", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", "dev": true, "requires": { @@ -13748,7 +13748,7 @@ }, "postcss-reduce-idents": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", "dev": true, "requires": { @@ -13758,7 +13758,7 @@ }, "postcss-reduce-initial": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "dev": true, "requires": { @@ -13767,7 +13767,7 @@ }, "postcss-reduce-transforms": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", "dev": true, "requires": { @@ -13789,7 +13789,7 @@ }, "postcss-svgo": { "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", "dev": true, "requires": { @@ -13801,7 +13801,7 @@ }, "postcss-unique-selectors": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", "dev": true, "requires": { @@ -13818,7 +13818,7 @@ }, "postcss-zindex": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", "dev": true, "requires": { @@ -13925,7 +13925,7 @@ "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", "dev": true, "optional": true, "requires": { @@ -13978,7 +13978,7 @@ "qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=", "dev": true }, "qs": { @@ -14047,7 +14047,7 @@ }, "iconv-lite": { "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", "dev": true } @@ -14138,7 +14138,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -14189,7 +14189,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -14219,7 +14219,7 @@ "redis": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "integrity": "sha1-ICKI4/WMSfYHnZevehDhMDrhSwI=", "dev": true, "optional": true, "requires": { @@ -14231,7 +14231,7 @@ "redis-commands": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", - "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", + "integrity": "sha1-RJWIlBTx6IYmEYCxRC5ylWAtg6I=", "dev": true, "optional": true }, @@ -14244,7 +14244,7 @@ }, "reduce-css-calc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", "dev": true, "requires": { @@ -14324,7 +14324,7 @@ "regexpp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", - "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", + "integrity": "sha1-sqdTSoXKGwM7z1zp/45W1OB1U2U=", "dev": true }, "regexpu-core": { @@ -14456,7 +14456,7 @@ "requestretry": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", + "integrity": "sha1-IT7BAG7rdQ6LjOVBdig9FajVXZQ=", "dev": true, "optional": true, "requires": { @@ -14676,7 +14676,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", "dev": true }, "sax": { @@ -14748,7 +14748,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -14818,7 +14818,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -14876,7 +14876,7 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", "dev": true }, "shebang-command": { @@ -14925,7 +14925,7 @@ "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" @@ -15106,7 +15106,7 @@ "socket.io-parser": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "integrity": "sha1-7S2l7nnxCVUDbj2kE7/X8eTYbI4=", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -15118,7 +15118,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -15145,7 +15145,7 @@ "socks-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", - "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", + "integrity": "sha1-WTa/i3B6mTB5xvN9sgkYIb/6ZHM=", "dev": true, "requires": { "agent-base": "~4.2.0", @@ -15410,7 +15410,7 @@ "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", + "integrity": "sha1-odG3z4PTmvsNYwSaWsv5NJO99ks=", "dev": true, "requires": { "date-format": "^1.2.0", @@ -15442,7 +15442,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -15458,7 +15458,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -15475,7 +15475,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -15513,7 +15513,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -15662,7 +15662,7 @@ }, "table": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { @@ -15799,7 +15799,7 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -15947,7 +15947,7 @@ }, "debug": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -15962,7 +15962,7 @@ }, "iconv-lite": { "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", "dev": true }, @@ -15980,10 +15980,15 @@ } } }, + "tinymce": { + "version": "4.7.13", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-4.7.13.tgz", + "integrity": "sha512-6QbNYGV4VExH+p7+o/5km6jOnVSD5mO7aw0s+eKByKnpyG8gZfajxXPhwBM57r7SIravrCI6LFj8DARNe31qPw==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -16193,7 +16198,7 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", "dev": true }, "unc-path-regex": { @@ -16357,13 +16362,13 @@ "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "integrity": "sha1-NSVll+RqWB20eT0M5H+prr/J+r0=", "dev": true }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", "dev": true, "requires": { "punycode": "^2.1.0" @@ -16456,7 +16461,7 @@ "uws": { "version": "9.14.0", "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", + "integrity": "sha1-+sg4a+/DOno3BcvVjcR7Qwyk3ZU=", "dev": true, "optional": true }, @@ -16699,7 +16704,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -16838,7 +16843,7 @@ "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", "dev": true, "requires": { "async-limiter": "~1.0.0", @@ -16874,7 +16879,7 @@ }, "yargs": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 21e0eafc33..21bca45567 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -35,7 +35,7 @@ "ng-file-upload": "12.2.13", "npm": "^6.4.1", "signalr": "2.3.0", - "tinymce": "4.7.13", + "tinymce": "^4.7.13", "typeahead.js": "0.10.5", "underscore": "1.9.1" }, From 0e8c5f48fe6b29e63fb01e148fe598bb1ff8151e Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 11 Oct 2018 15:14:33 +0100 Subject: [PATCH 010/337] tinymce to correct version - 4.8.3 --- src/Umbraco.Web.UI.Client/package-lock.json | 244 ++++++++++++++++++-- src/Umbraco.Web.UI.Client/package.json | 3 +- 2 files changed, 230 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 5bfa1b0bc9..50be314bbd 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -807,6 +807,11 @@ "to-fast-properties": "^2.0.0" } }, + "@types/angular": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/@types/angular/-/angular-1.6.51.tgz", + "integrity": "sha512-wYU+/zlJWih7ZmonWVjGQ18tG7GboI9asMNjRBM5fpIFJWXSioQttCTw9qGL44cP82ghM8sCV9apEqm1zBDq2w==" + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -853,6 +858,11 @@ } } }, + "ace-builds": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.3.3.tgz", + "integrity": "sha512-PbSdoHw42kt5vaXkEVSfUYCd3K1BCfAvyXW9TvR/2ATkk65oImjS1v0evHmzHhOYPSTUO8BprvmpfYT9Vp2akA==" + }, "acorn": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", @@ -957,16 +967,72 @@ } }, "angular": { - "version": "1.3.20", - "resolved": "http://registry.npmjs.org/angular/-/angular-1.3.20.tgz", - "integrity": "sha1-sjo9fF5/mffZW5tNSbmsNVJpuu4=", - "dev": true + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular/-/angular-1.7.5.tgz", + "integrity": "sha512-760183yxtGzni740IBTieNuWLtPNAoMqvmC0Z62UoU0I3nqk+VJuO3JbQAXOyvo3Oy/ZsdNQwrSTh/B0OQZjNw==" }, "angular-animate": { - "version": "1.3.20", - "resolved": "http://registry.npmjs.org/angular-animate/-/angular-animate-1.3.20.tgz", - "integrity": "sha1-0XB8cn+K0N8hxKLewgzX/ElFtSo=", - "dev": true + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.7.5.tgz", + "integrity": "sha512-kU/fHIGf2a4a3bH7E1tzALTHk+QfoUSCK9fEcMFisd6ZWvNDwPzXWAilItqOC3EDiAXPmGHaNc9/aXiD9xrAxQ==" + }, + "angular-cookies": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-cookies/-/angular-cookies-1.7.5.tgz", + "integrity": "sha512-/8xvvSl/Z9Vwu8ChRm+OQE3vmli8Icwl8uTYkHqD7j7cknJP9kNaf7SgsENlsLVtOqLE/I7TCFYrSx3bmSeNQA==" + }, + "angular-dynamic-locale": { + "version": "0.1.37", + "resolved": "https://registry.npmjs.org/angular-dynamic-locale/-/angular-dynamic-locale-0.1.37.tgz", + "integrity": "sha512-m5Kyk8W8/mOZSqRxuByOwHBjv8labLBAgvl0Z3iQx2xT/tWCqb94imKUPwumudszdPDjxeopwyucQvm8Sw7ogw==", + "requires": { + "@types/angular": "^1.6.25" + } + }, + "angular-i18n": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-i18n/-/angular-i18n-1.7.5.tgz", + "integrity": "sha512-52+Jpt8HRJV2bqSbSU6fWkwOvGzj/DxbNpKXxnTuCS9heuJrlm77BS/lhrF4BA8+Uudnh7npr5/yRELobP+8Yw==" + }, + "angular-local-storage": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/angular-local-storage/-/angular-local-storage-0.7.1.tgz", + "integrity": "sha1-+9JzB2PCn6mvVyXgGGx4BiHozdI=" + }, + "angular-messages": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-messages/-/angular-messages-1.7.5.tgz", + "integrity": "sha512-YDpJpFLyrIgZjE/sIAjgww1y6r3QqXBJbNDI0QjftD37vHXLkwvAOo3A4bxPw8BikyGLcJrFrgf6hRAzntJIWA==" + }, + "angular-mocks": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-mocks/-/angular-mocks-1.7.5.tgz", + "integrity": "sha512-I+Ue2Bkx6R9W5178DYrNvzjIdGh4wKKoCWsgz8dc7ysH4mA70Q3M9v5xRF0RUu7r+2CZj+nDeUecvh2paxcYvg==" + }, + "angular-route": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-route/-/angular-route-1.7.5.tgz", + "integrity": "sha512-7KfyEVVOWTI+jTY/j5rUNCIHGRyeCOx7YqZI/Ci3IbDK7GIsy6xH+hS5ai0Xi0sLjzDZ0PUDO4gBn+K0dVtlOg==" + }, + "angular-sanitize": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-sanitize/-/angular-sanitize-1.7.5.tgz", + "integrity": "sha512-wjKCJOIwrkEvfD0keTnKGi6We13gtoCAQIHcdoqyoo3gwvcgNfYymVQIS3+iCGVcjfWz0jHuS3KgB4ysRWsTTA==" + }, + "angular-touch": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/angular-touch/-/angular-touch-1.7.5.tgz", + "integrity": "sha512-XNAZNG0RA1mtdwBJheViCF1H/7wOygp4MLIfs5y1K+rne6AeaYKZcV6EJs9fvgfLKLO6ecm1+3J8hoCkdhhxQw==" + }, + "angular-ui-sortable": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/angular-ui-sortable/-/angular-ui-sortable-0.15.0.tgz", + "integrity": "sha1-8kLlH4Uic34+9ndUC3J4dyxQzCA=" + }, + "animejs": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/animejs/-/animejs-2.2.0.tgz", + "integrity": "sha1-Ne79/FNbgZScnLBvCz5gwC5v3IA=" }, "ansi-colors": { "version": "1.1.0", @@ -1700,6 +1766,27 @@ "hoek": "2.x.x" } }, + "bootstrap": { + "version": "3.3.7", + "resolved": "http://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz", + "integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E=" + }, + "bootstrap-social": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/bootstrap-social/-/bootstrap-social-4.8.0.tgz", + "integrity": "sha1-ZtRj3JZtbbQH37mTNR1YxTSqLHo=", + "requires": { + "bootstrap": "~3", + "font-awesome": "~4.3" + }, + "dependencies": { + "font-awesome": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.3.0.tgz", + "integrity": "sha1-RO63kM35hmQnhvM/znhHZPGEHEA=" + } + } + }, "bower": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.4.tgz", @@ -2173,6 +2260,16 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, + "clipboard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.0.tgz", + "integrity": "sha512-gXzHBlzEVqCk2b8Wpkil89S0WSMAX7eZho2zANX+EEEa9LMutGe9ICU+wHRzsH7cCHaCbUzj900P+AXOM0FE3A==", + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -2268,6 +2365,11 @@ "q": "^1.1.2" } }, + "codemirror": { + "version": "5.3.0", + "resolved": "http://registry.npmjs.org/codemirror/-/codemirror-5.3.0.tgz", + "integrity": "sha1-JDyyaN1hynjdsn6C8uws74j7lGE=" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -3516,6 +3618,11 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, "depd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", @@ -3546,6 +3653,11 @@ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", "dev": true }, + "diff": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==" + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -5226,6 +5338,11 @@ } } }, + "font-awesome": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.2.0.tgz", + "integrity": "sha1-RzOKGgF9pr75XOLhsOF2go/Yreo=" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -6257,6 +6374,14 @@ "sparkles": "^1.0.0" } }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "requires": { + "delegate": "^3.1.2" + } + }, "got": { "version": "5.7.1", "resolved": "http://registry.npmjs.org/got/-/got-5.7.1.tgz", @@ -6697,6 +6822,18 @@ "vinyl-fs": "0.3.7" }, "dependencies": { + "angular": { + "version": "1.3.20", + "resolved": "http://registry.npmjs.org/angular/-/angular-1.3.20.tgz", + "integrity": "sha1-sjo9fF5/mffZW5tNSbmsNVJpuu4=", + "dev": true + }, + "angular-animate": { + "version": "1.3.20", + "resolved": "http://registry.npmjs.org/angular-animate/-/angular-animate-1.3.20.tgz", + "integrity": "sha1-0XB8cn+K0N8hxKLewgzX/ElFtSo=", + "dev": true + }, "ansi-regex": { "version": "0.2.1", "resolved": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", @@ -7465,6 +7602,14 @@ "requires": { "httpreq": ">=0.4.22", "underscore": "~1.7.0" + }, + "dependencies": { + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", + "dev": true + } } }, "httpreq": { @@ -8352,6 +8497,38 @@ "logalot": "^2.0.0" } }, + "jquery": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", + "integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=" + }, + "jquery-migrate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-1.4.0.tgz", + "integrity": "sha1-4AKOSDHMFH2PIvOCBRbr+5dReaU=" + }, + "jquery-ui-dist": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/jquery-ui-dist/-/jquery-ui-dist-1.12.1.tgz", + "integrity": "sha1-XAgV08xvkP9fqvWyaKbiO0ypBPo=" + }, + "jquery-validation": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/jquery-validation/-/jquery-validation-1.17.0.tgz", + "integrity": "sha512-XddiAwhGdWhcIJ+W3ri3KG8uTPMua4TPYuUIC8/E7lOyqdScG5xHuy9YishlKc0c/lIQai77EX7hxMdTSYCEjA==", + "requires": { + "jquery": "^1.7 || ^2.0 || ^3.1" + } + }, + "jquery-validation-unobtrusive": { + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/jquery-validation-unobtrusive/-/jquery-validation-unobtrusive-3.2.10.tgz", + "integrity": "sha512-z9ZBP/HslaGNKzFSpfLNJoFm2iqPJfE6CKM0H5e9LmKnYTFxErvCFQZomOLiTmLmZi8Wi/otW38cEXExVDha0w==", + "requires": { + "jquery": ">=1.8", + "jquery-validation": ">=1.16" + } + }, "js-base64": { "version": "2.4.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz", @@ -8747,6 +8924,11 @@ "dev": true, "optional": true }, + "lazyload-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazyload-js/-/lazyload-js-1.0.0.tgz", + "integrity": "sha1-jBA5sbaRec1J/cMkICOvSM4IOSU=" + }, "lazystream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", @@ -9779,6 +9961,11 @@ "minimist": "0.0.8" } }, + "moment": { + "version": "2.10.6", + "resolved": "http://registry.npmjs.org/moment/-/moment-2.10.6.tgz", + "integrity": "sha1-bLIZZ8ecunsMpeZmRPFzZis++nc=" + }, "morgan": { "version": "1.6.1", "resolved": "http://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", @@ -9891,6 +10078,11 @@ "dev": true, "optional": true }, + "ng-file-upload": { + "version": "12.2.13", + "resolved": "https://registry.npmjs.org/ng-file-upload/-/ng-file-upload-12.2.13.tgz", + "integrity": "sha1-AYAPOHLlJvlTEPhHfpnk8S0NjRQ=" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -14694,6 +14886,11 @@ "commander": "~2.8.1" } }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" + }, "semver": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", @@ -14906,6 +15103,14 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "signalr": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/signalr/-/signalr-2.3.0.tgz", + "integrity": "sha512-NrvIGftLz3QVujdjCvaNso56ltTr1FowSR0DCIaSOJ3J4t5pTebTfnh2VT0HHIM3PJ/v15lukIL4y+8MMknqzg==", + "requires": { + "jquery": ">=1.6.4" + } + }, "slack-node": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz", @@ -15899,6 +16104,11 @@ "dev": true, "optional": true }, + "tiny-emitter": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz", + "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==" + }, "tiny-lr": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", @@ -15981,9 +16191,9 @@ } }, "tinymce": { - "version": "4.7.13", - "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-4.7.13.tgz", - "integrity": "sha512-6QbNYGV4VExH+p7+o/5km6jOnVSD5mO7aw0s+eKByKnpyG8gZfajxXPhwBM57r7SIravrCI6LFj8DARNe31qPw==" + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-4.8.3.tgz", + "integrity": "sha512-kNEsKTqUYZRG+GTZ7tcVAktUlDeApz6d3IqnNaZXNX0CP0BsK8NPC02FCJ0EVYxdNnq6fvvknWkItmbreXD9aA==" }, "tmp": { "version": "0.0.33", @@ -16162,6 +16372,11 @@ "mime-types": "~2.1.18" } }, + "typeahead.js": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/typeahead.js/-/typeahead.js-0.10.5.tgz", + "integrity": "sha1-HZlxsPRNOF/q2/IsnzadtWKRLeE=" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -16208,10 +16423,9 @@ "dev": true }, "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", - "dev": true + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 21bca45567..02fa88cfbc 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -33,9 +33,8 @@ "lazyload-js": "1.0.0", "moment": "2.10.6", "ng-file-upload": "12.2.13", - "npm": "^6.4.1", "signalr": "2.3.0", - "tinymce": "^4.7.13", + "tinymce": "4.8.3", "typeahead.js": "0.10.5", "underscore": "1.9.1" }, From e2c16f15daf6402e02e948a7c0b51c072d2fcabe Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 11 Oct 2018 15:19:32 +0100 Subject: [PATCH 011/337] Adds in skins for tinymce --- src/Umbraco.Web.UI.Client/gulpfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/gulpfile.js b/src/Umbraco.Web.UI.Client/gulpfile.js index ed03193271..9bfb0af875 100644 --- a/src/Umbraco.Web.UI.Client/gulpfile.js +++ b/src/Umbraco.Web.UI.Client/gulpfile.js @@ -355,6 +355,7 @@ gulp.task('dependencies', function () { "src": [ "./node_modules/tinymce/tinymce.min.js", "./node_modules/tinymce/plugins/**", + "./node_modules/tinymce/skins/**", "./node_modules/tinymce/themes/**" ], "base": "./node_modules/tinymce" From 4fd54ba3399b6a2304b87d34288bd83b83887b24 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 11 Oct 2018 15:56:05 +0100 Subject: [PATCH 012/337] Adds a class to the DIV so we can add a border for the inline editor when the RTE is yet to have any content/copy added - to make it obvious there is something there to click into --- src/Umbraco.Web.UI.Client/src/less/rte.less | 6 ++++++ .../src/views/propertyeditors/rte/rte.html | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index 3413285859..e0296f63c0 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -4,6 +4,12 @@ .umb-rte { overflow: hidden; } + +.umb-rte .umb-rte-editor{ + border:1px solid @gray-8; + min-height:25px; +} + .umb-rte .mce-content-body { padding:10px; background-color: #fff; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html index a681cd0799..c3add7694a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html @@ -3,5 +3,5 @@
Loading...
+ id="{{textAreaHtmlId}}" class="umb-rte-editor">
From 43d44474986042fa339bdcc9ec2d027cb5691c9d Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 08:19:38 +0100 Subject: [PATCH 013/337] Something went wrong with a merge temp8 into this after the removal of bower --- src/Umbraco.Web.UI.Client/bower.json | 104 --------------------------- 1 file changed, 104 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/bower.json diff --git a/src/Umbraco.Web.UI.Client/bower.json b/src/Umbraco.Web.UI.Client/bower.json deleted file mode 100644 index 084cb1816a..0000000000 --- a/src/Umbraco.Web.UI.Client/bower.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "name": "umbraco", - "version": "7", - "homepage": "https://github.com/umbraco/Umbraco-CMS", - "authors": [ - "Shannon " - ], - "description": "Umbraco CMS", - "license": "MIT", - "private": true, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "dependencies": { - "angular": "~1.7.4", - "angular-cookies": "~1.7.4", - "angular-sanitize": "~1.7.4", - "angular-touch": "~1.7.4", - "angular-route": "~1.7.4", - "angular-animate": "~1.7.4", - "angular-i18n": "~1.7.4", - "signalr": "^2.2.1", - "typeahead.js": "~0.10.5", - "underscore": "~1.9.1", - "rgrove-lazyload": "*", - "bootstrap-social": "~4.8.0", - "jquery": "2.2.4", - "jquery-ui": "~1.12.0", - "jquery-migrate": "1.4.0", - "jquery-validate": "~1.17.0", - "jquery-validation-unobtrusive": "3.2.10", - "angular-dynamic-locale": "~0.1.36", - "ng-file-upload": "~12.2.13", - "tinymce": "~4.8.0", - "codemirror": "~5.3.0", - "angular-local-storage": "~0.7.1", - "moment": "~2.10.3", - "ace-builds": "~1.3.0", - "clipboard": "~2.0.0", - "font-awesome": "~4.2", - "animejs": "^2.2.0", - "angular-ui-sortable": "0.14.4", - "angular-messages": "^1.7.2", - "jsdiff": "^3.4.0" - }, - "install": { - "path": "lib-bower", - "ignore": [ - "font-awesome", - "bootstrap", - "codemirror", - "ace-builds" - ], - "sources": { - "moment": [ - "bower_components/moment/min/moment.min.js", - "bower_components/moment/min/moment-with-locales.js", - "bower_components/moment/min/moment-with-locales.min.js", - "bower_components/moment/locale/*.js" - ], - "underscore": [ - "bower_components/underscore/underscore-min.js", - "bower_components/underscore/underscore-min.map" - ], - "jquery": [ - "bower_components/jquery/dist/jquery.min.js", - "bower_components/jquery/dist/jquery.min.map" - ], - "angular-dynamic-locale": [ - "bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js", - "bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js.map" - ], - "angular-local-storage": [ - "bower_components/angular-local-storage/dist/angular-local-storage.min.js", - "bower_components/angular-local-storage/dist/angular-local-storage.min.js.map" - ], - "tinymce": { - "mapping": [ - { "bower_components/tinymce/skins/**": "skins" }, - { "bower_components/tinymce/themes/**": "themes" }, - { "bower_components/tinymce/tinymce.min.js": "tinymce.min.js" } - ] - }, - "angular-i18n": "bower_components/angular-i18n/angular-locale_*.js", - "typeahead.js": "bower_components/typeahead.js/dist/typeahead.bundle.min.js", - "rgrove-lazyload": "bower_components/rgrove-lazyload/lazyload.js", - "ng-file-upload": "bower_components/ng-file-upload/ng-file-upload.min.js", - "jquery-ui": "bower_components/jquery-ui/jquery-ui.min.js", - "jquery-migrate": "bower_components/jquery-migrate/jquery-migrate.min.js", - "clipboard": "bower_components/clipboard/dist/clipboard.min.js", - "animejs": "bower_components/animejs/anime.min.js", - "jquery-validate": "bower_components/jquery-validate/dist/jquery.validate.min.js", - "jquery-validation-unobtrusive": "bower_components/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js", - "jsdiff": "bower_components/jsdiff/diff.min.js" - } - }, - "devDependencies": { - "angular-mocks": "~1.7.2" - } -} From bf9bd4b1f53578a95a92c8e5e3faaaba39ac9183 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 09:46:52 +0200 Subject: [PATCH 014/337] delete the old skin files since we're not using them --- .../DELETE_skins/umbraco/content.min.css | 99 ------------- .../DELETE_skins/umbraco/fonts/readme.md | 1 - .../umbraco/fonts/tinymce-small.eot | Bin 9492 -> 0 bytes .../umbraco/fonts/tinymce-small.svg | 63 --------- .../umbraco/fonts/tinymce-small.ttf | Bin 9304 -> 0 bytes .../umbraco/fonts/tinymce-small.woff | Bin 9380 -> 0 bytes .../DELETE_skins/umbraco/fonts/tinymce.eot | Bin 17572 -> 0 bytes .../DELETE_skins/umbraco/fonts/tinymce.svg | 131 ------------------ .../DELETE_skins/umbraco/fonts/tinymce.ttf | Bin 17408 -> 0 bytes .../DELETE_skins/umbraco/fonts/tinymce.woff | Bin 17484 -> 0 bytes .../DELETE_skins/umbraco/img/anchor.gif | Bin 53 -> 0 bytes .../DELETE_skins/umbraco/img/loader.gif | Bin 2608 -> 0 bytes .../DELETE_skins/umbraco/img/object.gif | Bin 152 -> 0 bytes .../DELETE_skins/umbraco/img/trans.gif | Bin 43 -> 0 bytes .../DELETE_skins/umbraco/img/wline.gif | Bin 46 -> 0 bytes .../DELETE_skins/umbraco/skin.classic.min.css | 1 - .../DELETE_skins/umbraco/skin.ie7.min.css | 1 - .../tinymce/DELETE_skins/umbraco/skin.min.css | 1 - 18 files changed, 297 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/content.min.css delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/readme.md delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.eot delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.svg delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.ttf delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.woff delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.eot delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.svg delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.ttf delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.woff delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/anchor.gif delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/loader.gif delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/object.gif delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/trans.gif delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/wline.gif delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.classic.min.css delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.ie7.min.css delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.min.css diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/content.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/content.min.css deleted file mode 100644 index cf0fac0565..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/content.min.css +++ /dev/null @@ -1,99 +0,0 @@ -body.mce-content-body { - background-color: #fff; - font-family: Verdana,Arial,Helvetica,sans-serif; - font-size: 14px; - line-height: 1.5em; - scrollbar-3dlight-color: #f0f0ee; - scrollbar-arrow-color: #676662; - scrollbar-base-color: #f0f0ee; - scrollbar-darkshadow-color: #ddd; - scrollbar-face-color: #e0e0dd; - scrollbar-highlight-color: #f0f0ee; - scrollbar-shadow-color: #f0f0ee; - scrollbar-track-color: #f5f5f5; -} - -td, th { - font-family: Verdana,Arial,Helvetica,sans-serif; - font-size: 11px; -} - -.mce-object { - border: 1px dotted #3a3a3a; - background: #d5d5d5 url(img/object.gif) no-repeat center; -} - -.mce-pagebreak { - cursor: default; - display: block; - border: 0; - width: 100%; - height: 5px; - border: 1px dashed #666; - margin-top: 15px; -} - -.mce-item-anchor { - cursor: default; - display: inline-block; - -webkit-user-select: all; - -webkit-user-modify: read-only; - -moz-user-select: all; - -moz-user-modify: read-only; - width: 9px!important; - height: 9px!important; - border: 1px dotted #3a3a3a; - background: #d5d5d5 url(img/anchor.gif) no-repeat center; -} - -.mce-nbsp { - background: #AAA; -} - -hr { - cursor: default; -} - -.mce-match-marker { - background: green; - color: #fff; -} - -.mce-spellchecker-word { - background: url(img/wline.gif) repeat-x bottom left; - cursor: default; -} - -.mce-item-table, .mce-item-table td, .mce-item-table th, .mce-item-table caption { - border: 1px dashed #BBB; -} - -td.mce-item-selected, th.mce-item-selected { - background-color: #39f!important; -} - -.mce-edit-focus { - outline: 1px dotted #333; -} - -/* TINYMCE Macro styles*/ -.mce-content-body .umb-macro-holder -{ - border: 3px dotted orange; - padding: 7px; - display:block; - margin:3px; -} - -/* loader for macro loading in tinymce*/ - .mce-content-body .umb-macro-holder.loading { - background: url(img/loader.gif) right no-repeat; - -moz-background-size: 18px; - -o-background-size: 18px; - -webkit-background-size: 18px; - background-size: 18px; - background-position-x: 99%; - } - -/* TINYMCE IMAGE RESIZING LIMITS */ -#mceResizeHandlen, #mceResizeHandles, #mceResizeHandlee, #mceResizeHandlew{display: none !important; visibility: hidden !important;} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/readme.md b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/readme.md deleted file mode 100644 index fa5d63946c..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/readme.md +++ /dev/null @@ -1 +0,0 @@ -Icons are generated and provided by the http://icomoon.io service. diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.eot b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.eot deleted file mode 100644 index b144ba0bd949de3c0f87abdd78b517067169884f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9492 zcmcgyYj7Lab-s5Oz=CfqL2yNo1o0rSA|ZkhKoF!Pk}Fb@EmM-IM`Za;N@gTQlt?}7 zN^YjzI+ml=>J6ee66+Gi(ljj5V?YXgkiHL~VwhLrW_=jFxj4b&}2FxhUJr zGAxUpyHmmdVx*4QOl8^o5BBGpnpMn%-9VZ?c6w&v`+xksXECS)^||9S=NFKJUw#F- z|M=Xc&)3`&`5x+58SC<#n4Nh-J1%~evFHovA3T8u?G5!8sK0}H_leUNF8)|){yo$` zLjC64{IQw$x_|f(W3dlVzi@iy;sV>v-eW9&FY3`VGpA>rJwN#k)KB0Y?=H-rzW_dQ zbq`TLQ`P^%o4t%FzpKz2zV7DypIM&Q(6|*B2ivPJi?N@ps#p@tQjyR}Yf-(TvOsU6 z)PX)XSLLV<=3!H458#j5Ig6GymU5-S&()>!(h^!2T3D&KG*D^bOaB=4MAfJgF5rok zZ<2%2!tq?wiXI44aaaz#J^Jo#9-4(JR2w1^WD!E!2-{R5`|z) zAL5&1NP0e@52O-uL_*Jp+)*Rk&{a_?Uyt?o$COg6-?1&rc5H6jRx0e+;gp4(Tj7*F zrA(FjW96tEd0mLI&Dj#>5Kg7SOH8o^72dF&5aw)yHygaQfU^vi%*=52%@y9jiK#`n zktjrX7Y|DQh)-Rzs~&u=d3)HICW49`PPI2@e6{MEwYv9mJKl=-DnEFxxjhvw%a<$B z@b>0DuU`A6TI;)9UR1%BLo1CHToN9v5{}0(xF~=PvuJ7=-p>iWPlaT zC=xIE;wUc~MRSyo@uZe83&p$<^01eE&2=Zv+QGCDSPU5Hpndj4U9<1yJ2X4OmKR_6 z41-tD2)K_C@3g-b_LpQ*!>MgzEEo%6fo>;DwQpgOZ`q1f7L>5=OU&jL-9h4RG^(_g zX$S>tMrjR^yYRs)ye!k;*7}^>g+_Hg%QUKUTEhnB@)g#j{)#%yda*Kl0hNqru!F_y zC{LL+ypc!vWC#8opNSY;iDUda>D!JP}WsDeB7Ss6#8pQ-y&+R6;Gj z1cp#QBxL0fbvk~yXH0Z&sLwjW5!w0;-D0fgaD2F-zyI1$BI+3%^F$Lv*ZTV#h8?an zH|ae=e~UlhkLW!uDAaiP%k9ZzJ0+e+L$F70YF4J>n1WIFS*X?tKKW;8ymL zdpC*OMCtXnU-)2icOVe-`U4XYz1ich4g0_8(r!=wyWblO1iG93;ab0^S&vKvm{(#1 zL-vQ0PzKnY$LNTuCd+}DXYOT^g9L$RWs;5dYNBp`=Y!1nS&UMnU@8>6}Ap_xp%?U)iu59#UaZP))J%p zP^7mv@=>JMmiOLB`R1EVp-_{&y=BqN2+AJ zfgWuLa=Th`mP^cs<7i>777iDkZ^}=d4pfK<+FJV{S%+Flo zv|3hf+cgUpw=iLnM_LEGRIWo4Yj#nsiX<{OG>bssHkdfz@RnUFt%L-HEiT@fUKLd+ z=b9nuRTs_$n02U;zOa}r`Rih1Sc_al3AHpTiFigSm;<9qJ`^W-(EuQ^yYz9kao0d3 zGO%l-iJWgc@mu#7pGf%|G=Gz(+^x@u7Vqm#-&c$xPj?=AVcxp1sn;K<;rxyr5XuEG zjunC(z>=eciJ=-E8jNtCrij+=_~man*ZI`-cgF6YW0Q-|9`yW_Pw}ZAc`m*6@kN|N z&Mj=mRrh&bsNscFBX2b_e3ToC#iyL>-?$v_Zk@Y-?49e%AO6U>?p*(==isx8lNUdJ z>yn3dlAeDV&u3w_{yGQ(LLtOW+}F~@i)LzI45WauUA(oW2{4VL+K)YnplxuB4-S~J z0t8;}%mAIxRe7pdrPs(|vvdLG<%6RHVIV}1K2YR?Iis~jBl7CYmjgYmMo-|iSWMla zdcCiyn!+{pvMg~$Q*b>Yz$_^{{}h2dYG=tp26e=&P&aR$a8N zuFes@MoszgW$Jk?_Gk>`y$yIPs9vrXz(}>*`RWeE<;WePYV^tlSzwBKwXiu>XgE`t|(zMu@5iWIWCx>!f zgUEnwInWoEk71{axmG!_@)!vWL?X>y4gJg5)Bnbv+H!eu$BqgY(1Q)Ir>H1zW$R9( zVDc@G`u`S&fAx87DSCAG`kt;Z2L?ElZbcD&|BizkQ5^&sQpn*@8Dz){&BVA~!}S<9 zH7H@YDfn|37o@`_CbK1sET@G~ey4m&o_z~=X~8q*Wuj|2ggM0A1Zx^> zuBh7rD=pWIVa;r4U!83Mf8?g&Ky-2~Q79H-g_s#{RJ2Al)DlsQh?>uhD#cN?FpyEq zjGEwhIcM$3n~w-si?--HynlBznvLsvJR6Pf-ha67(=C!Ek!*kcC1`3}+-2nQv(Sap zOsI>BV6I%iZ-O4u;3jdtD9DJ(_xrWcy5gjnCUuGd=bE$!*(CK0j5>x1HSA*SC+_++6v3e&k`} z;l}jfc-o5d*fe!P~;RpNr9z1-=>=utLNDYGiJr3ZLGF_8_dlf|Xq17r%~ki(mSJ?IVLi0O2T;o#*pI({*_jnGMyr_l?5 zNLa2B>c%)o+9^3gUJAq<0T3iAsjO@%!m(@|E*pUpT!L zOZo~~;1UxowIng20r%3vafF!>3u~qbuSc{`~TrA1c-#JoC)x z^1rZc#Udx(w#(LXD++i8T0542IyldD%z&jxwmjg5a8FHWW}*f<*vNC(*dQZ*a^=R2 zD>P-wmsl=mUE7AF9Jp~~39UD7kk%lY*h|dHrO8*&)c#MJ$}cKJ&#a<}b;5#xDjNWo z1sC|}$VfO0B}}YL255L24K%c92}KM)wj;Ug=~o_o^p&S~C3ieF3}muWV|{J?`%jOK zp5EWz);E?S#IlpdJr8|hxQYqGUwG&qBRO6AFt~N{NOt_m2XeUwo*d5}ncN!uur$qF zADZ~t0FAO0p6Y|xOc_7Gfvp4;q{T|-ys#F!HmfTgyV%MKpwFzFejIj%O@6sh7#b=R zzC3xmM02UmiE@Cr>(TLL*U#GXrA;+`69@bI4^H&eZ2Hn3bzltf{rfX(QGxeBR) zSExAV25h4sHX5-Cp2xfiy+Vjr;20q#yyU{?24VZ6N2j$>>7dDzp$ZXB`8DUSzjmO+ z!JjBoY!!=wHNeqj&Eaq})(3+GHK^3tdQ}xH%XM z^T-xJ8}ehZZ#e7q(7lWd9`FV}z=@Zv9ojZBB1(WDS)C@K-EOWx*BF9Y&+J~+zt+Fj$cB>4W#EMyR+F;oNr>Ib533uC~^?~5HrU~XCW1|AkFm6#Z z2Q7Jua6`V1=SS6i5Mj7{ zNU^GzaF3nK6$-hWeGf{hT+O#jrPu2AJ@w7c31}VFuAcYl>JS>7dVGM?*#55`--_5B z_L-?batrpq1&tZS$0r8An~W|DbrjIv>|Rtp*CnrH}0mK?M^2~4rEF^nmI6% zm>T=Hj+TjNUtje6E9YA}UZE0yzvEzkde2a-%wj`((&HzM@3eG~ZGY9tcC=ij5*V_< z1O6bdj7ud<0t(%yT346YRmZ}owX0m;l)K?<1p3tjCq@EBI z{^26jvSB11AKB0nva9wRiI@UVGWzsTYimgFGbo^0cy!msjk_L2q>F(i$PCUC_=76t zu}sCA#UdDaGU-q!O@QzO8D>Dp2+Cy4nF(pD0R}32nlGrr`8fGle&XoSiJ=D@&-&7d z)J&l;lj`Z~>*1>6e5~;F@TdBkn%?1}y<>adrtSTS)Xs26S64^Zp}x$aF0OE^VKBbB zy*+PWiNN<_WnEiPsj4PKQsrME#%rZID)Yz&T!fwL980n3}T(y;e#e%d!|`GJb@zY28oh{i4upA6Yf!&azfB*d$o<) zt4U=R08U;q!%d=DwFPzeUlFp2Fp(~pJF72Omo`iL$_pePl)5bj%^3s0#DcMvrj<`K z;C)nL($aD%LcS5ROPR@KM+I`OE;`duXAx3z@ksQRZSg0}@oangzGFi}$L>peJc;KT z8p*p@m}<|p&g=Q0H>k8Yf0N(6J5LFx+NK~w*>22_@83kv(6a#6YxAwSc6x4Vp|Rn) z76lLH^~3H{`Q4R0hiuwd?-bTL3t7F(_ldxS;hXyuoPT3o630vGz-!u&BqcPD9^JvLoyiJOTL?gNzFb zf2CnU%Rm^ubfAqwXeru)7&ZaeyWAIA9#7^M1=@-*LCuxMmj<&0cm(wk%90zMO1zzk zhQpJm=pN0SnxuPYINYf$tl$3LNIE@2=|p-Yv#q(1*uHQ3NLm>`5zU-9HA(kO^u**T zx~C@E+9pzW>}Yf8jHF*0N%wA5+YEJ7Nj`KWJ;HF|_)rQwGx6QWo3{NYtMgDRdp|ou zUx{SCRKizWKfDZzcq-J23(v^!`Ou;0|HR{$l-xe|KI~F*EA$xZ7LrZvl`_?<=_@PB zG=@^OkMac%<16Z%t?8deeP5;R=9<0^)G4iae!cQi3GX1fHj=1}U##TQZocxpkSDro z<#+Zub{+BWEI+_6@E4V=@@vX}K&M_*7uB~tanHEts5j~x_f7j=_5F{wPdlUilmBV| z>;8{xJT-$g(>1?Y^M37A?F+SkRkx{bs_xr$PW^cOv-Q7U|3O2x;XuO|8(wetS>u+* z#l}yXo{=j(%-*GM(zvQSA}f_!Bm0xeesEaq?k>|vjlEcDSJ8fNrR+iZjY^rKO=hJ` z*8Y5@TnoSWePArUoT4R+9=EIj?Y~tiBZ$a8S1Ef?ezQ{c;zu*NO4*0@FILL6@G<}8 z!pSq2P9K}?JAZm+Ztl*%#W_5C?)=I5GtteN?D{{z`HXZv$Df>=Ik)=PKcDg0 zUGrxyM32v&nLRgiVfKmW(M!?Y$L9CW&!5S#UGgVG7g!WODVoKPhv - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.ttf b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce-small.ttf deleted file mode 100644 index a983e2dc4cb30880fffe00e1f0879be4d95eb4cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9304 zcmcgyYj7Lab-s5Ozyf??34$wvB!~xr6$uf90D>SbkzA3IY?+cwJtDttQZgecqA2QN zS8_A$#<3iwZW2{-ovAyiIrXDI+=r%r>Si?Q&5S4YbR3WCaoZ$KV@#^abf)c$o3^go z5tjYVU4W!$N%fy*!MpdlXV1O&-0wV=j5EgSnaxy|yYIk2zPUy1LCZCynIk7>7r*~U z-+PuZ-iiAB(b=<$$b+a~Lhe60f8q0iyQAMj{W4?So?~;fPiRNQuQC>U0sTYA(4f7c z{sQ%PQ13Z*^4$3!D=oi^`bVf=pFeeE_Pw4TKEzo31Juu*oIStDcCq&uOWcEcY+?4~ zoU{8UUqbyD-tq3@sk7(6C$64h>SwC@UwE^ZG39p@dc!x|oc}W`@Boclb8)bJ^JOvi zb5#|~f>|mOI%zFxS40VR z&3M8W)?3>O@%&Jc7sAP6D6S9l&2c2Xkkkj$NjV~^7sBqSQEup}C|9n=2L|FwIX>Xn zmSsCOw{0sOaqLLiLe8y7+MZUX%LDOBOpd%NM8)Q88FPrF(~)JS*n$dg*iIO8w!xbX z-de#~7E5Mkx%=iSZ{Wn#qTEOpqr97kB!9%GF4-|1#g3#qTC%=6_02ln zd$9v=#e0<>JlE2Zj#T8!l~`n3OTSmIdsD6RU92prV9TME#tJSA4_1lg*a)~Nf(^4| zYFR$OlUftkOwDNG%{**?70oCSFNM+=FBv6sjF0n_mNbi{f)Vzxmwheu$4=X!j1gQ4 z8kvxN`dEF7@8#PxJHnP1U;GS%*U$*Mj}h;*zZUkFWKzSaZDuSK4`YE=lcm}>u*f%T z#i|HOSodXSbBpdEaVHuzS}Qb!f;FSGj>sMO;8k8$XmIP+oZNv%Z9XeBYI9o02Ilfr z)~o)CI>Y*~GJDt&>}M7`Sjvs@v>D({Jjyp4TH1$wHQI)-i)P92wP9yVLuu2C&2Hk! zMA}SKS0PUwS}Bn(4i2FbZuKQGg!&;NYlo;ai9@~PqGv-x&Jm8tHEie+ zt-X5GALI!lBR1Xh2wuUh+#~mF601b%^{X#@u%#y$40-**$*A7q@z+KC-*Rbpr2gIS z4F!WeE&fQI-_xQ;Cxgr@F#;k2Of%UgoC2T(FAk*AA=EHHcFjotQi_Y=}mSTC#7YkhbaR4Lc zhN)E%{MHq2*G?Ga%dEEf>vPqz1%8UC$)0nI63&zjcoC2fm#@^#JgLQ`p2T(_g*7C~ zWxaSa8&DYdlb5ioZ{`bEIIWhI-+INu#Vt&jrZkNxI-r6DR=5KVx@cgGWV8Z$TM9B zUpQr*+tlX|1~|WM2ZVAFjAMmh2e8x_VPZJI!$VQ-(-hIxleqXz=PIAR`p)=$^K5GA z*#n-R@@YQ(BhQ7mK0c3g$hn2>xa>a9iveCtH}N(j%g4B(SbW;K`pt`pp0@e>#^1TB z{K1c$tIpM*dJa6hGG*eu3 z)rh?M^2K0po6#G5Ego05t6uMGs-|#Fy(mju(Ntx-66`hF_)?CF1FPi?up zxMN3!3+SOn*i%%Lw~BSUQ84*dM*V*a!@v5xwiG?Odwow=nF9kHO1G+rzJJ?6j;IZS z3@PMrs0=dXg=S)04{$xsO$|yIZVG-5!eH@NAA-%(&gx8R8H=D!c zf#KuUurjgr9Ksx8Zh|!pHrLc`ft8kP#;|5Kw6D(Y0)OPD;Xrh8Em&!|I;m! zC6VfQ{UvB>Tijvf%CpdgGfb#UieRo>z;A*c(%>d>z9h(+f^fj96BY@HY=9HU+y>0k z%l2Zjf2w|-)nQM1*%&(jU2nj-GMiK_Mb2L-tC}hyhiim)ak9w?!7+cDJk6Y@ozzJI zlm4wK-M#zLXLdw0dv|Oxl!MV7XVUwOEj#vRCOn#Yg=Bl7A>i{i2WF<9KfZPA@#m*& z`PSom`}_A&o0}`&D2zUAJlvESnn?d03ZsSe#89TG@{+=LeL&~v4@m z%FJ3iL=ST&KgY)2w!!Nypge~eW5QCAVQxkd&IPtmZZFhyiVD>YMl(4fD-H?#QdGzr zkpxOo`MDON2}<~b9bzT+^lg7}&z={z_w7lv4|bXd4?Wo5|KOp6X6Il#7dz~;htui9 zXYC!UrJAAm!@~T?$b7-v+10hvtZS|F`xmFD7yW(|-8TM7dVIsi-rkKH#?w!QQ$ZuS zp`l?z(g>!)PhIMneEhDv9-r)~S`!vFd0$lBas$so0=h}?TMpAjcCA!7h+7-Hd`mUedb^5pd*3`PX zH1kE})v;*Ia$#tsF_j=neLCUPEZRr6XP)uY4>tYG%_W+qfIOOnVU=Mo3IAS{8 z;y8E(jgDWOZliP(fl6Fdtke326M*swgN-C>Zif}9&hs#Fb1ec(j zW!rGX>4I#)c>snAg%Ch`@{+zn7P!O&OD#)GXas(-68J3QAS6TJEgUl8=E9pT;qYk| z`RI!Hhd;ac=7);)`_DWxw(=)zTd~NAx9y6x(ux9Jf!5AtpbpM+Ju_e_k}VIoA>31w znwbnh2O9+r8yjTAPcB`%c8R7;`7+Drtt(rRl>OJPEu;0?HPRYH6MKnSxitA2n%e(K zQ~5=e=)z4ju})YJP-TPQvgiUI9T^FS;iQR`$pQ^m(Lh6smQ=*ZW7|_ZpMK@hM_+k* zXKMRnBS0oAJ>K6wu`5R zd4E2C|C1BB2d1`!J}l2L*M}y4HbA3nfv5T)HdDqAaA2!J1!=L;IWMkmVAGd( ztAp!^NOHT^k|DCI9^s0Q_)#IVX==E;dw6P7rhxq=JhQMD7E0~FvY$`rkT!}RM$!T~MH8V`A!2;V9ncYS z`EX^z#~Kk+>;NBTDXy1{c*)S?hNc@@T-VIFX6kXX#LL2VmTUpFBy(Z&846CgIZo^? zTHQ9x*|#EpA&DL%&|H&vU$N?#8?cQ+*l5HmcmeY!^a>+hfn$V}^pXpoAA;?R9-Y=k zrGq9Y{`&qh2Y;eMu~jSz)&NJBwL~H=oiZnZ zCi8<<(ZS=S*2N6faC0yi=8-LcHsr@*-*DC&pnDk^Jm3v{fDY1)+q%QUFD*>RELCbsf~&fvU->bv439**4GzWzbB9kV-N_KzK^PO06m_4ua7L zBP3y30){bOhi50Wtw863kPEn!A67IG| z>jS}YO%u#P#zqC6Vceo-4q6t|R_5e~26E>UM?8ih3LPp?;%Z!lG$Vnt(z>MPf)zU$ z3o0xat1JZ-Dmy4&mMbr6cNH-)#Kj~R*fb#}THyWeg|$_d%Ou#ql{6xAtFeY+o&uDR zBG>Jua6_S<7sk{=2w}KFSg~rDaJQY$7mNA4eK$(!eBe9f@@w^bpZeD41hkH7*UtM) zZ3qocKR!rmY~R<8Zb9r0`^;1zxdr>*g2s$7STXRs$>@Ug#-;t0HqDhl8{&o(YJ;Y9 z<8I37o=kFdf40nH+5Mx*>G6N-Y@Lkt_s7n@a<;Ye6)N%fI}Z$Gb`QrZEIzzDGjZJb zZfhsm_LrSpXX|Aufgu|_;0JkSTqMvsG^vi(nMUq(hxF0m2hxm;oW9D3dW~CZ(+g7^v=Pp{NSy zyhaYS@?aL(7v&G_Uy0^c-m#d2NvBEPWpXzIFeus;W&TajhwhbiHJ0hLk z-JRVB`?CkTxx%f+p~TJY9R&kR1iqK5>)MJ+O*J8sDu2Z|w`tdC18vL3!BZ_NQ=22m zc>yY5ooVhi=H5zn!>y>4OfGIF%`}x;(V%nm`*I95ak>P4vAffRmTZaFb|OYeC)pQ-o|HOr#6u&dryrOIxIU-Z%Ao%{-&^NSAh~vwM{{WirrM0*tdzE zp=SZCS5CF%JLtLT#iqvRS`|E4&=0v!6?Rqk9I|O+z0+9h9Axzl-#2dYc|)qAFdPqB ze=>%RLUH|v4oJr8cMhBqiUGu8R&FV0#bU~*K6fY<;DXkl@CKuSFQ^F1#@a7`!eSo3 zIs<((#U5ZM;0egD7-U>f_$vbwS_Z=Kr2}mgLQB&Y#IXs$-j%-a%6KxrD9~1d32Lr2 zzBHI6z$2)SaE{#Qbn@+NEE1VILHAhp#1!4TB9Sg-@z(9{jb<{Vl#XRavs+t=$!&YL zjb@aIW3lY96H|20#*R&$pnH0VP(M;bKwcSw1l+;5HWJVb-93M)- zXD0vR@#d}n$?84S%HGe7(pMsxFPHHZ*AFj)BAyDh;=(iXdp>k1`akjbB_+4dy^pw* z+zLI0x`kv@d$mmUTKejmGL4~B>!WzcdHks8jS^KA|*fz_Age;b?`C&<=pXw3n!1v^`AXCJ3r6PvEyukUBIV|BM9I0v$H78vUxUt zXzt9}8=G?r5E=;FoCqU{65x;&Hu_e8&UY+?Qh z#$rYE4^z^PieEW~M#kc;sCQG+URQr{?Bw|iXxobV4N5;&nto^T)DetJ#85v^>D}%h zK6G;a0^XZ=9(8Juv7PMQrTLQ!X!}#V`yEQot`EL+`qVi*)BQ|!oQjgF{ujT(yo@Qo zt-Ou;H{6{6Gt2P+>Z>mvTwSBG#n{hORjdeRsYqzyNR=xl3-T=}b)b*R9k|n|4(4IA z$b2UTyJaXi;3sk@B| zV}()4(k;I3-sYiMs6w?_0}HVzD=?PQ&3M8W)|*>$@xkFd&xMouP+TA3o8m}%E~yWt zlX65-&xPGlW8BbHQ7m1H4-CYWVtl}{Ez5RnZrfHm;@FY2g`8WFv^}fL76;;`m>hXc zh?33O3g!?=rz0y&u>}=gx1BKNY=bu&yfuTfek_^U&)qkdc>^b=7Uf1VALU&5vg zb;+)}|JkN(5oeAFDt08@-qi1_QQxT1y_eeYR=ijF!Lv>6=}1YwT!}@tHT8M*nm5!M z-=)&B3bq_tSFGTQ@L-i#mW_goJlHS`rq<5~cv5TNnyDELype|uu%a0S;w4uY=LMr+ zj`Ing(voJrkTb#__L8ru_ShLalre(KK_e5g&m605^1XD2W=Gia;-^2w;8iq&?qkF| z?XQLX#X>R-C%=)gP&|wUx|J-|zKKP?X)9JqP{O*eFq>O+2Z_7UsL-m?5DM0e(mEn{ z;e(fXsnX!q?K!y%jmmtgG%9mi#|Gx|Ro0_^L7ij0Sef1I2==odJ6On$^RyY@4Lr&> z8Cu$heKlH!v5RKG@U>uP3&UyCi_LD}$wb;rQ&(<~IhsP}~Y&HkW2 zs`oUb5b*Gq+Eb}^N<4>#P>nqe>JRb+kr5m3eFU%IR`!v5H;P+C>Gii> z_+V3aFc|XsgHutx$>Xny_`l`SZcqKY-x~@ByPN!x8o#GWk4^=dS7HQ21Q=$rjW`8B z37#KHXWU!D*NHhx#Mr{a@q(V@ID|PQAcvO6_VRpADfm(vj($L0D^sJ_T; zAsmud4!BU*!h$V;212pWZPCfKLiG--4+%jB*0O|UmHvKV;Z?yg&Xr9j@v9eS^IrA< zI0G!i+;TZg*byU^O|x?c6dh~)@th0%Q^+S?obd9>G- z_ugpf#v6^{aHG7vY0=E&jc>ixtXRZ9K^@(Dqs}bR;3LjkGQSq>by%pL9<2{?yHawh zCFa9%v@ll-hl|c~D@!rb)L7ukj{_JnH%zUJ;J2@EyK=%PUtyKaU!SX%E$~xBMfRNA zlyIhOz>9!8B zl1Ewxyi~43BWrR|t%4*nH#Cbt;1-xT;P9qhEUtzGg)J}NnO+4|DCe3X=~Wia1(@4V zBYj~pTk_Y%Ca@NRQ6=2mpd=IhO5PkAS90M5!HWg}iQlDsT8ab>;RS;Crk_n zcz8I0INp*WRAEf04~BKeONS6F$plf8@FN=0~vF80QwY3(#p1KhwQpWZbhj+tKk@c8<@bN&Tyw7d#IygI<(Uf~y?N0?J4w&Kgy*yD zB>OcG1cX9}8@aE!ixUW4m}ub0c6HM|A*u5=Gna1RowUWd#Ua?d%6Sp{x8< zp+c{L!)ECM%*zMI3Bo{#AbqI7hX;+8W{t?JFI@`uv=}|XSL1PYyXy76s%i??)Jw9& z6-`yPE5RP4MUHSTZ&y`CQ7ePW<+a0tx*n_$rLy{$T7$2)mRq&4+S*!2_!>0j$Cs$* z)%c@vkoVT(t)P0TQUD{BZs%*;6_+D-h^o=cWVtfR<<2GO&P6%t^WtTAV=XdAczxJ9 zSnjm;wD<1Xf1Q1s{W1G4`@t`J7Yy1{Y{T#%?J{Xv?8_LJy0w!-xvoQGz_uLdOUTEt z(}lqnIk5Z~2@FIc!(9#i%h=QZ#-7@8d2z>%3K!5r^{}U?C~qa}PNQJ*RY(1Q3&X$q zytWiQx_f<3m6-zr97?yWh`xWvL5`>lf($9-aHtG2jAFExv4=3!%e}@VO)?7 zmzc~}FtU^pLiw%I33>J{$e#tzsGDuV)2sat($nO8s9G(V6;(fEjj97RX~V1XE|!ae ztoM-(8%8Lp@I6YfI9xZNWMM0K%!w&Bynv!RWMl(lfwEp9KEf=*y1-2j{Ei&?t)JkD zC-b?mUcGTLZgSPC?1<~BwTzWq^=5OJJTQFR8dfH@oJ%uTSS!RD&EEwIvZ&6qs1 z9;UO+;E&ui9EeV?CG&-RJRdg`4T{#FhMS{`5mj@8<4R#%%@6e}X1|)`csXb7sT+?7 zSc|skJGggeES62^dLkQ(?c95??~^T(C6Q`>?L}y6Tij)2^;zh`IVRL)MKD(`;5R`J zX>gM`UlwFdK{#O535$e8HoysFZUg4&WqUB$KT$u+YOp6gY@F?ft~cOZnGLFzBImEr zubL_$hiim)aTnU zNGi`YMYmX6J408_Z2sxyGr#$_rqj7MXZ69X*Wc;#}N*V}d(Qf8HHOAqjX zVj``qlO?3z17r%}ki(mSJ?IVNi0O2Tc%)o+9^3g zUJAq<0T3iAsjOrv!m(@|E*pUpT!LOZo~~;1UxowFnIM zuzKJZD}c{D4ni^n-ohahZZ5pp0uG;Mk&mv3fB3UYZ+xg&zxVXh$p;1pA9!*yduV1$=)>Y1bA4#yrxhAy3p~{a zv6(V{fCF0&DoBf!&Ut=4bZt^sJ9hEa6+oX^KK(fC3Y+;#K0h*&&wpj+R*B|PnG@vz zao3~cRoBnj_2rF$zN!5K1N*1?0vo@)OC4HAM3URJnhcS>L+@rXyJ`Yj_)SNt#@0(0AHH zp>|5D1!<%BVI(b(Q#2836(Yu$-2v?(mk(Dad^jJ?tQ~xqg}7cY;sryG8=7utaa}Xx znyJUl0xt^NS+)h#lFWt8=O{Sg<~XspX?5E$XJ1wRLJ~bjp}D5;zI@p+H((ouu+fNB z@Eqn%=oLo10>=m`=_MC_a2U2PdURSFl@6Lb8LAMGv|n@n`s@3O9Q=tA#a6K>SOXkg z))a{}VSO-2P=iXnj;IRZOD(szTvFb zLH9B;c)%O@04H9uc4*tkkf2LpH*o`S30bu*3PK5ir2vXr<+JGe>pG~l0acS_>uQvZ zv2CCa%AlDHAr)kVfbf)nm0DF=90a2gMo7Z61PYU&U~Ob84m8FPWJ$afmR-hCs#_F= zwo0~i*{u?A5-VoOX@g}8oT5UJCERU`)(3*)nkJZojExFB!?;Dw9JDN^Rp;b~26E>U zM?8ih3LVN(;%Z!lG$Vnt!n&kpgC#o{3o0xaD=h~VDmy4&kt;7McNH-)#Kj~R*fb#} zTHyWeg|$^yiX_;;l{6xAw_*+XK?+bpid?ss!VS4vo*P$lA%x*_Va2Lo!aerjU_L)M zXy1cUdNA;vV)515J)i&9X9Tp4YFEztTxAFiPCq_GYHaV+6f1 zd-+^*$IDdW?{(}S$m|-4msoscS7!3K@!jSQvhA-p*^cHbR02abc)$DpD9U8anMrA@0S3x@n#-%g`6%^RZtC#isgVa8&iFFP^n5-)pYG}F>*1>6 ze5CNq=qLIb8{g)ly<=P7#%%-1^o~eJS64^Zfxi9&U0mT-{cvJ!dwb5n5`pjK^13#o zQc+Eaq{?4D&TZN?+CbZ~aqv`&%GBlva$bN6SZA8Mjk!0I-Ecc91(S=lgdB?2eUey- zxwt~Ug}a`2qzN~}T1!*8Jxu~aOqEGJEzeU8aH|P8l>oQNya}|y!7;=5)Ta zc|%IG^EbJjJ9Ct9s%;7~l5|MY_oy~bNWH|soc); zo6o%tL>rck8k;||D&;iM~^_>H!gkk`(n3Y}5TCte& ziO(I11-PK~C%nOE;0r3kva$9nAG4Upug*c=%&gOi**R@uk5m0UkkpgtO#Er;~5>$0CuL6LgRDpO~S0 zXC%_8oW6bgyJMNm7^P#GvHq=1`Q)}e+r~1=oK zE}gN=i({GIEoz&gjw`8$4rRs|E*u|9!KbJG;_=3<|H*1S)XLt=j?q^lnXeS_71s|h zgCd>^wc^4v@_RmXDEdG4_$4K`&%KYjl-vqEhPs7hQ+v5g^-B8csxpnCROzGqw1@Fk zb$~Yr01|V=9~1*`Cjq;kG4l!(*DW+l>asVM*&Y@I4~FZ z^}u^Ivo+7x{8jD7+S%Ig)H-#Ob5^%KO1#vAerWBQ^Fyxm`v3z2!1_y|0(c6m2rgWwQ29mCH5oi{Asr z;>#&oBIt3;3ef)B@(%E2jw@)WiM;N_cnLD5A9zpmuui-{>%B}OBYWbS?D`= za(;0U|EzMHEwPLElyL;%n?809rFs18%;Ld?v*(VVT8eGz&$5H)I*YF3;BJY<5c%w9 z*-uI5Qx4m=aP-N=`Lk>vUUif`2@dAj*-!cG^r@xuv7-x13uougFFX-Dd@;83$f@0@ uPA&DbY02?<@O%`6m*hO=G3f>N1lkT`;`CoRM=)wP63q_(y@A!b>-E1{Pg!yR diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.eot b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.eot deleted file mode 100644 index f99c13f32f5c968849f08a3d8a399157bfb0cccb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17572 zcmdsfd3+pKo#%U1eW)dMt6P0kt97_r?e3N(t97(WE!&b@wru%O6f1Uo#KeglTk(M% z%U1{)GE>-$0W%3+t{Jik7VBil1_FE*$ZkUBGqnR`2R7l851V0tnXrN^83YL*K7pA8 zR$bcf?^Tu5lI?hy{p>$m-LKw#|L*s?AKSnfgX2s>p#0(N5~ui0W96w77Rm7cF8vdo z;)|aEJHw8!d)Rx~adv=BATz+W!#~8%vSVyNJB5@O+l7=<>@-TAK-nbgVtLjn$}X*q zMC!1L=}cyw+jewx*VI;h1}V?MjUPC^fAW9cefj4o)Bx9WX#eR+qz4(3XxtTtj=lHp z2P&T$Kzt8l{hv5IvHxIIMV zXRo31?^bO;U-~H;oxzgO6=q)+TrdwZQulZkV{W+UqqK(K* z!%SAR(K)kfW-Z!y0&S?GjTe@*!RKC0x{`8YRiZD^7~i6dC|i^b%6g?==}`(wm(roE zRN9p4==0HUMF%1;MykS3h93*p)IM8#uGWS5mCs)c=-=?-jAJ%6Wo-fYi>pM_3+=yi z8diGFz<>-_vWSP`RAF|1rM=gspDp7sW~H|JFXyoN^=49lw&oA@$bC=T+X zQq19<^QLoZv7orvWlwF@;gfo}O$kl~mA0^c@^DqH=km3aKdXy}Pu{p_Sqn)~i7{Xq z!*<9-DZHQxH)%qcbwc7jxDyZ%r3VcO0WTLFsHm#5{0euUipujZ*6JR=HhtF_nYr0e@<&`xwUy9P>8Kb zw(Ll^G<(;r^ES7nceEte#0r6d(rcbjRaHDtT~}4zSY2J=aeIPQRds>tc(oOOIHRf= zINptTRb6!;UR4!BsS1%FuMX5zRRu--e>bN!&f*(3Z-|>Z*F|8CY3b&H%Y|4h-Q02@ zzkYrGKudEv7AssH_^`jOa=xW1^jF?;RdwCx)GT$KRcFPhLRFP@{_48wDtnaHsN)m| z41zugI#bWGtd+I10%2oMw#|Aqdm6EPHnoVRiXq;|y9#j8wCYt;(Xd)5rU~+8E$pAp zCiFyh+8+-4d6FAO35a7zOrNMXO!$&Mhm6kD99aX>x>fH%LdZ;sKY zuc@`QiFY=&>Xz49y6|>QG+INiuW2+fdhrwUi898n&0!XnYi%mMB$~L-{1EvPnkwmG zKh^Yyx#5INtbmmUyjVQvDyFbB>%cD9*h*A|JJ5{z5OEfhTM}MCXbY)FRCVN94oC?y zgs-gG1geOjcG0p*4@M)5r(^)q-Z1{rJM7Tn(G;q3Qm<++)iX z0W_rgxS9>{n39zSxgu$VQ%`)pFWYux+wiO3mj3o_6A7kk;^C)9Px0{UkGR1>^Qiwl z(YHoIJCF4iIf#AM;{_im3Nl`U5P-Y`BLhmWMK;mxA_SObPYw4(mT|!&C?n?;f(@mE zb)d*X1u6wTU^kY7umirbmiP8>&7TYK{s8yGH@_L+Ps*-J-<8U^-yioKsPy?NulVBr ziW={_Xjfg+D&YCIApDrG(j~7824m>zT>Ak9&z07*`E^q5Lin9(J=T5>AP9Mp*)+WyYS0lVN++Ql zy_Y?JRW4tO|5xjpbAx3UK^EL_klu1$^2xn&qgA@W0zYQ0)3x`eq!@YQh^7G*4Vl9K zQPVgx4BmKyHETZ@QxxptAGXr%7tqCwVQA*xBe25YhK9A5m;t!f0M{-C{VN>u@sJFc zGPuTxQ_P_ViRoN3!FOl>J#h}12n`X&-;!MwR?n8PW~(Q@K)MU0YlO?< zZi^Bcf^_SWX3{jRND2K?moh79BE=GVtxO_{crZ5`9%abPeQXqPNYKz7Yvf+y9VxZg z9FV*LIT~q_lqR{*Jt!3iWwj?S)Ph|={*JsA``w1H#Q zVMlxgL4%ZQ39cY#JQt9?3M5~5F)tHQbEl(_p1YtQNo?#RNBaAZ(3FM$z7Dl=PdyNXeOYgqd+Iyx0?vj|}GPVUK8Zkq!y~%mm>xeR#9|$Bwdr*8!R3}9b-vFq0 z3?v&uX-)|2Pz=KW3js1KJ?N0Or{==?{8Y0 zY~GMgZ)i@gZR*&WPVelf>rMnhlVf9(p+KU$PNcQ0*tvUeKEHSO&J`=SXIl5G+0n5b zt*tx8MziYv*39;mlD>TC&ef~$99r)9x@aGLm~%Dp3h~5i;_F&k*2Vo1Z>+a*Y;tm} zu{Y+8_(dxJT69^ostT{zs?_n7Tk6A&;mS(9>bI;so>~fz0+p99Gg>LD|*=9O?jx@Cml5ZtDVOIDQBP)cgmkba>66fI?km^8n@d9!h7!Yh8 z955gO*wH&$N6XNUnJ$J2+8|GZURrXd0!s->P^o&Z$nKmMRsnDm*Z`QMp&Q94X**wh z-#4X-bLR$~uZHIJk|qa}rJ&&?BA0Nq0qyI+QIe}!rc7Fu)7~6mYf&jcW)srsKYr-B z=RQQ!C4Y`}+mflY{ki7|XP~N@7 z$Ig3)HGPhKKf3wO$-%KdJG5rap+6fNoV;^$^!uPtsk$A<^i3o-lEAr1KenR|d*hxT zQy6elU~5SeTS}i~l5Wd}B*TQ{Xy5L#FejQG0M>%0H^~xPLXnT&_L;LAHk|#;ZMOeI z2buUhTFo(a|Mv9}Z{N=20|Uo*_IV@gx9^t?XNrzLJ66_=Xil26ai8#?ocZZUb9-Dn zaZ5+XEhn^idvk<=N6q65;R^7C@W5?b%GQ8`hlmEjT1MP4Q$8~Q891Ub3*9%HFn|N_ z&DThF=7IWfxSkxTBH4tAEJCDgfcT0|OpNb{=6jr3)`R{ z7RF^TkoSN)4+2LE(E=vg#!2xngutsas;zLZ;c7bM74`vIj{z8N(%rq_;zIB9ak;2) zF;y&vrt7jsi;;lZN3TS-Hj$`BGO=%Se0uvsd|U#lKv}E})@y!|G_H-0C$c8i3|{tm zFlv*T8cz;?g6C=MASQ$_0Cq}lvl&~vC8<`#sXHtVR_h(}g*4Sg1H$|aOkIQA zVQL}_l~>32n#q!&tQb6OxOhN=bM=jsUu(o= zz6{Z_K;osG0*^_7AY!=;&<4i~21_iM3`%;iqy=RPmh>QmUgv>WsBr)tKn-gRA49}G z%}v{Qm4S@IxFgA_!n8*$U1)P;(JNH(!l2AS=L%6tTOdZ=-KyH%t#8_-cW1kO&rVN2 zUUl=mf6k+1!O)3bQPFXy2o=uW*+V;g%Y%p3m}0$&^I$NL%XL-@yjqTt3_?ZBOKBjp zkhHQST0yRA<6&&72uj~E~IBo!yW^soiUPJ4!8?B z)&pVTf_MXrgG8hfWs(fNd-vJ(>(B1)*6ZU9TUuJSG{oychx8KKG{^go+}z%N^O1f& zWsW!XDe?OHxYE~TPGLyE9eYpu7*3rmop4_8QVWi>WeH-7{RtrH{X2f)XgG%t<+M6I6wdT^1D>^uH~ua_}-=V+;me<&rKqDb)s9N zb)2%-kuW_4q_aLY=Yj19P^#;;bp(qm)DgxF$M%8gN?2b8TBifcVN1G3D}K(6MGcu> zBuU^J&6)c2G@3-4$s4rU>N@Y;e-A2r#eF=B#10xxjOMkojs@6m~ZTkjVi~@yS8* zQ_@&?5IBf$M4Jnsu?A32mvm!d!qmxu#NY@BB-79h$JJlMG;obDpsvC$`yCa1Htgogf`v&{z05J4`<1IqBq6TDc?QrEB659$s7oC<%f2 zFUDy-me1|jyoX@`pLED_(+sN=_VFCg={(7&b#rP8U_Nby2(;PU_gt7i$~7{TtwYsR zF6B)@bcSSEE<$;{3bYK6AqT2^i$F6Nhq4(*hyhKIfkR1iN|W`zk@i`p@&A=u-&x)QBvdPWPSim?z}JFpz6O?gm8~MHBBaeCP64Cfw>SeVs5!xl#cPSJ zeyORR_z*xgsdY|wYVelW>xpoH*h^Su((k#U6L--#({y90-Ci<~Ow6dHNgAMs*|KXB zYi3!DQ5HunSktr$?M$4?kaAYf3o?ww9Dq!Q4gTuKy#co?;H|EayfI%qTkZC_-9G95 zPwjhtx7p~jtQ@eLjD;J#6>fRhElZWv?tr&4Qf1kJieZu z{PBDLXia|n&OMpFeotpl`O`;GLZtrh!hb!fVLT1&)hyJvu zz0;jtu}k4OhDB_LeD#!Ufb$)}c0ywp;xA55`nig4S7(pf+0!*BlZt~>I$Kd>k=>P- zyEe7Dr8BZhYT(fZzDmMekf+YKB|oq?p>4gT?dFR|200HkW@1MB)6(h# z?XLSidN#9WBs1*xyO;IH$5!v?%17kQE?t>3XLw?wA`u-yqkNQC0!Nr zILojRwwoOVmV$eb$Vi|`yfq5Gfly4OWl4G@^h;SVJf9bxFRxlMW-l3Zb7eBOS1=(M z0=&^qvXf-ff16Jx5+m=XcQXI(5qdW!5{=U2wbNf3XlolFcergJ-(Rby*WJ8spiNqT zIGI2E?h$(DlZQv%P4DbbUENUjx*2s=I|JVuXlq>~*D3O#l-awd4XEm6cmy3>435GQiYekgX96%>?nWUYc=( zbtb_(x?ttt_F7YqI%HO3k!{18t7X%eH6YGvl2~Wrm{@YGHs;uvp<1fDGd_@n8HnH?SoHS%olSGTO>(Zh{v$SSQZ_Li22^J|>46y{JHa=n^ z4z&I&`*NVw@o6RJ7jdDVg-}^<3)o+_Ue&mjw;ZyEmuw~WLUAk{%zO|@l|mE~D#GR9 z&$-P5WD=c7ATO4O^m71c}q1B`NXQ-WRqAfzO1P;yp2(bQ_Vn<+46}QQJvdoJa5*cuyu*!q8l6if4l}Fei za#H1nUAuOfm-v?@k9q5E^Y>{hl#*X8a`cX~V zWk{{oy-1n0LYDl#{1hNA2(6I$pcLYuJ6G)OUdCgQ8V;2RCCVjmAqb`KTuPUTwYg=uR2f@O20B$UAeKidNder;Jdz`%;l1) zOpXV`ndar0NK|ewY+BX7sT)>J+olP9p$<3X7`M*2q6OQ!u0WOXhHaBju9ylHtwS_b zzCXQl{AeFp)W_GI{EJ=r-P<-ceu|G@$S%apsSERkvuD>|BF1);uq{8N3 z&c{&LDM927JZbI?0V7G)!d7BrIjAfJa0nb7MN_~i?0Xs-3K6sJ-mVPJsBky4kSQu@ zsr5ZgJ#A_KMe~_`=ChI~zPXU$_cm`C z9c$T#XXsCg%STtPKH51mG;?X+8>N>Xd~oJF-=XnTa1D!P$of1!k>%F5nOW9|48WCW z3i$-O=7SaY-4DO zKCr@{;t!gq{{y`~L6$&~mbCbUCeL9h9U4HktYX-^0z3lDDNWJ^`I7dV7k)GQTdJwi z*zACG`IgdWZ;=dGjxlu|3qUPtpb4PrpmPfD9FZjtCj)rNp+z@*VS7|@(j{+-E_0dx zb=k(~Gv+06MHd%!A<|A!FVgR#8<+95u4Pg48LrP?;_al{6f_3WAG7uRT0kh-rDz$7 zi@JjSwg9aTwiyLi0(3sEn~d%vNJdLvvNSa%jqfSF-N~mr`II>&>3UyFNfY^uPl@c! zdrCUxqdx~9$YzW4C~kLzvlv{U5=Sv|$_q0{N}ifU^L;H-IC?*hz-IGLzh%e_=9(7j zo!BTwfKbW!(wDeFbAkN=3uwsW!d{W*U7fwf?%rHaFHs-dWQuxXxcl7I35$UoO~Fts zod|h0RyHaP6^R{t_wGnkG$@Ug8$F@=$&))}edozZ&gH>f+QGW&-FIx=ddKeSx`W!T zLD|(lytlJ+?{GW%6!VdEz-=9AWgy_z8B5s>OKVyg>;57RXr-~>$!+?!lfg(sLqtmA zZQd>}SwcNy#7M!!7E6fjjCHOt{L`wHUZ$x@SP^RZ^dV^dS zWVY=j4ry={Bl;?#HMDu@J7t_}#VJumAlo89OfJ6xviUVU1<r1cEz%);V zvBg;7g)u3RysjD(DK25M@&nRBg{wyKB%loN0yw+6W8eYPK;-BQZlNEa1;-fJQ|Jq0+{r={ugRFcLCngQ;Y0h>5_2hYI`Cdest7b!s8$GN)& z>#8h7H{95yl)AD4K%eQi$D)mUq!^Bm0n7#zMD&WSZZGYgYc3FHx{*5D>A?3WF?hCPd0-BMBn z>1EZk;f3gDYW_4FwMf)0q;Tb&h#GFrSnbKv=2X~^+U69s$j3#5k0T;!!t-CN0J@?v ziaSyob7PE(j~8KUg4r7uE({(a@M!Q3lrwC8k8&KprBOI8HQU)TS*NUm)E?%HZKrbh zU4<8tijym$Rn$S#xWmi1CNoLHjzY4LL5Dz%G{NncKUkq9(qHy?c$zw11*lT4GRWleBTx)+mHis`buC+VntX)Z0{zTT03XdU=1Y;9^+xDx7 zROtF`-wg#hPU)RBCcmpKm83GYW<{`=rRy%jWn$CaS@ zLtYF*j^ABjepc4z7zs$`Svh!}r{W{?Srz74?1u(CGq5eT%;NmUjkG<@GGhu0t}ZhJ z+{eIj;Lf2{k3h_Y}LpK876?$38GF(V0(g*z&CN9*^})9b7gNzuCf_ zF*`^<;c+W5*rb{}cortAZk(zKp9~&I&3Is|>cL?xOjl$8v3)!BY6idXn=nZTJGNXz zH^TVi6w&Ba!o^?_z)O0dJsb|JwfWlGuo^C1D2qvlkWz~r6(!nB7s_LNU>+iT@ zJsj?`%{N^Zo@35!H<61`lw6>JUiJRf3EebEwVLf{e+C zl9cE=vNebEYzSw(1L95%@iwqQ;+Q!9G+!}a*~^>FAMfR9p5ANzSb7yN-n=M7tiu#& z>NwWH4Hj9Xiv-e?!xf3&TI><)<;!Z9s8UNf&d-*hLzu*h}g0 zpAjr^o!<4C(z`^|L=+Zek@&OHyR1#O%KS`v+=^m+L=O$Y7iwXV!!H5o_pW4Y0kMGM zAjmYNHwC{eAne0EB9agAB5?tF2-hS7>5wyV)L`hKbCgDsAi;oe`cKk-cV|uiKeH+b z{CHjt|Kb;pKQ}$6;}q9Gyn^;rJg6srCk~Q_{I^{dq9r?1cn?@DSxHol;&7VnJ8{Q9 zz9esHImEdKW%71?V@W$yzSmBBX-QrK;^f#8M|H~5$STVWINkOc{3$pME(wP?hZFha zYgQWTgx`*pc-xLs-XH3mww!vci`yWnb-vB(g{dy`xDG#1R-V$yU0#xASaF(@D75x<-sQ6gL-&DNri}}WV->-~Uj#YlK@}(-R>Ri?H z)eJ`To2nnHe!lwG{)B(b|Aha!Kr(P9@Ly_J&3!=@>JQ}^RUB+-)SPmCq*NE}O?OFWVI$NFG>bA3(@yDg5Qf8Tbd0b{Br*mc(yN S4xrR19F>Jx9kYDL=l=i@ywbP; diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.svg b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.svg deleted file mode 100644 index 5727cea425..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.svg +++ /dev/null @@ -1,131 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.ttf b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.ttf deleted file mode 100644 index 16536bfd7a292e7090b9d4e0ae61061da9bc042f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17408 zcmdsed3+pKo#%U1eW)dMt6P0kt97_r?e3O!v|4JFTDB#*Y}xXmC|2zFh=~(9w&DXH z@)bgc%oH|bf|&#_*9_SNi*Yh!0s%e?WH%x6nc4xe1Do*4hs`p;Ojtpd41$CYp8%7< zs!RL*y{eX4vK-Ns>n%b&QBjq``@%_j4P5!UD zFaL}&-T>EgaNp@kr283@#^6^RJo?_d@2`An0P)?7^?&@(#J&Snov{F8gRdjM_Ye}? zpL6swwq`lv%MTqpbMMck(EAbJg!X=O^u+#s-<|l$t&FYhNB-=wefLhX2iYeWTi1tp z{P@0O6IX5xIT1(u{KDjk(`PVFJVVoz&t!R)Ut-9YJ|(??l#f_G{{_o)58~wy$FLVa z8e_k_S2pGhrpa)~q_rqLaS@>2$Tc9(@?}w~fjM{->FZF>$t0x3r(34g*Q#Fgz1H?K zK2tGMH4~T#&os`o%(TvQ%&0R1Gizt|{rt(FfBqM}zxeFyM_zyN^_Sl`@`mxo?|ymj zTybtr^cJ6H)2*+u*SxQ_{*28q(MD*dVJ0ow$jz*rS%Ws7KpU!P+GlIe)jBZ0 z^7)Ga{Tp7Kam=QstSyPL!b;KfLi_KWhLxT(Fd&0DSOo(-@k9W>d?1NH9>KgK>$AFp znM~KYUSyi2ji|CQ%Vd2Hi83<{uBq^~IYY*e1+jx&XeX29$wad&90*17iSAxC(35sI zaV4qZ6%4tMmquDI@*+w&-^9c62Oo-#CCqrDvoj%0Cpr@wWQTM`c1d6LxQlVO$K&SH zjtYm#x%9h-qR5|}5=F-oV-d+EUy&U0?9)_C9(Q{m#vo0__Ady3tbZ2O|VQEJe*UW?al&uO>A%iH5(bkwN%ZyBRC>xH)%V`*e1 zU(8v0Bn4|yBAxY zDJZUp9qUbJoB$5-Pd29kG-?l(vHp30EC4p-DgcH7!rc*sQQj&^5LPO0l|*5yyj%XG z=384DwYexB^Zn-g$)D32TW)P0@Z}?`<1O2hEzRz=Yu(K)$?Yxi)seh!p!k|AP*oN6 zRo7KjH&$0yxSTG3RaKp@I$CYTA5N)i3XXRpUR77^i&j+yP^v=YN2`5xRaJfw|3A%1 zjkD7
qE0fV3qg3i>lG;3uYEKk_jlWwzK&8|i)pG_^o zi9&$)@vb~vIH|hTL^!DC3rT`}Sqpln(=k1kp7sWVULNO$Q3T=`64NK@4HLekPkDn{ zES-*_Y*F_H4J2}=X@;g1-!-8blEz%~bb)Ye1!%(tw%x+A6rh(Ui3;L3KPIAJ`7&BY zn~l9+&Bf*i7sVFmX&jJ`0pQK=?VDrt>uYLlZQ{A6R^9Siix=Lm35RRw^;L}~MlXJ1 zK2gTlwK>efa;;6pmqZiynh%gKp{b%C^ioZ4kQ=3ti50NYfESDBT*VZYWS!Ur8(WF0 z@Dem*K17_wu) zQcbGCa2}vgKqwy$BPCBExW%KPRniSW0~|d73jB>ZW@yDXyS0z@!~N2vQksB)tLSXR zf&rprr5}asxKj|G#l2Ys4dM!sTCI_}<$>+oOUD>Oh?eO^B6}8gl z>u0f24f5lAuiQ7R=du;SN{L@L0{}*QEd3s`ffvkZkY~9&?BU_wCN4?8Z%g-m?g=7B z-+Fa;t2X-d!xP}}h`#N78)q;}In-4RS@&2&bO-Twl8F@Ydm1 zza{}9kJsn%m1=Kz9`7nx1dyV(Rg%#N{>>@0gPyC17uz7+qj)-~e<%PxQ{IN>0@W!&VG zd*w!}bb|$c%vz^w?@duLvc_Re11cIah5uU9I5Q01c!M?TI1o`3?BXA`(j6Dj#f)KS z=06~?!r+F6wU?LyxYhvI4hH=z81V3b43{vt#)(tRp$LiTTr|Dh$eMPgcrg<)qqG zPA)-6xdEMr)u#*{a)r@4HnP64sbiVnzpSIFas9|x>(wbozV_j{AyMX*{c?|ga7XJHI9A35R@QRl9_LljOxvecVv?>?e*)-lSWp@U1tA43X9=D3V)W=E|V zy6sKQ%I=aVgZY6#LbM0Pw?uVP^ziqAdPhLAA(Uo>zz)SQ2(SQkwDIKHoGO}u%1GP%AvzNV>jM>4siv#vYl3rvoUO$L0i z?mCgyvSP=sJ=yG@T{~8^Z%eiAQ`4hk+gn?=kBz3)eXXf&?UKHH=+0HE?i^ZP@^#TZ z`Y`8eq7~wa)cnm{*c~-6~$O>Xb2UoO*cEs^>uRgnGyf zta&9IkZzHlYT-NbV9a6I?0_0_-LXiV3z<^v*cUJPM8%w z#mEXF>qP^Eki>cT2BbPrUA%yt1_lJ12L}vD0Cx0_*3mNbW2TE?f;Pz0pqG}MslZZ# z5>%?5E3z}=hE)LE1U3LBY3N2WirS7B-}eov;@r8x(qBXKdQp@8@uJ@-B_fw_v;pnw zz)_N`S*lE0m6PraVQWFjLuM1w=|4U2+;b1mbjhD%-L_;ZZF}xH!rAAZ6XqMV3B1=a zX3-`uYtwzhHl>oddwfxwXxOHa(7#g9vl6OB0132GZRa!rZ>qFTSAeK-1h0S>(`(C^li5PgAy|Fd9<2i>b`C3LhimD#|8$D?dWrd)@|D- z8>K0h{MoUxW<+z+q>cN8|K!Y1g_=8}+KF2_J8wCmMLU{93_NNcX9!n-Cxi!1+fud~ z96UfY2-Y&6if=fN#D=vNQM92ZQzGNEJ!POk@!vrDGg=FtAIT zwzBK3?n^M>fRe21aOiN6-aP^1+bxpD}aT9gI#?2=*t()d+3e6{^g>nBjx)@ zf-f5)_VPthi0iX+0k^OZ(0UBOaFgur1s4~3pNGo@g^Q_TF*IG5HCl`q)INH}(zUTzEs}|So8!~l z9^&H?NCnDbZLnVRi==UFd_0ymv1ahn&x28$%+z>%_~SfFV+S!Id=YpZ#5&OcFzRp; zW2LQvg8>2pf}u;=EXXKB>lD|iAKC-Ppt;P;C2nEOQ?Lp|BRc`@1;G0dBP%^xC22Ng zYquoTia2$L#ldR5W4@54x@bU{pMj}skULCGgrV~4_+K+w5|kB#hYc4GXt1ss2%t70 zJq4F0VyZd`mjarxzvc6@WWIXLkM`FZahWeew9J!uDJQ^V5+I0JE(5foxvGr^v8f^`eWM}XGQ3xXC0$qd z4!5i~KQPhS-@oGS%a<>=4-WEwY`(RV(r0xlHGGB-leq;mXXK*`rlU^`lB7c}RG@^K z2dIJ=m;gi#YlK`#&zgok227X6NOC#gE>N-_2n!d)8(SXDJ z^MaR}FG*XLAht;EOak3O6sSZ*A%Q{q$DFF>+D{G+o@~#l`l*|5K6UD55x!PxF-4r8 ze{K0)s(RP*#B%)aQhRQ?si)^A5xhFlsnI%4+3QG{o&eHWKb!Nw_5&!@b=x|E#TDuZ z<3`E$f$2(EUj|yILk@*4=^CwgIX4zHWPX7pfon8p>eJI`5^ctB&}IjR*k3+4>6ZkU z*JyLru-aVUxgN-TH7pFf8w1E>0H^q6Ao(dtEIbGt#5bbNdC*t`sHaQ1F)?B4mjA4%gL;6k1>1ZL zEb}T`NmfNjn+2Q#hQV)f2AEeff)|U|5?lRJQ$6t^fNWgLP3JUtOYHSTI6&+rEHml% z+|Y@;Xq;)fvD9ua8Av8(RMaF5(8Fv#+Qgb!8e^2jQ47{IsX{vwr!u6R)$_azV=)IH zlVO9u`Z2f9>F~L$Yb1BX6HQk;Jx-@by6=;FpWkIRIxH&(>?UKu26u&19(Kx7Wwq1i zt_)S1ukh1m>-033B=&n2TLV;Nxw(Il@0V8zcwRwrbO5`Kjs{_CzyLxxSCZ112w4~4 zXC-Vuw(4~8Z=|8k=1u%7<`33A{`tq((UU!P&mXPMj^DXE)z|OJ^>m#1<3H)!Y5p)W z#vj}WWZEbSQQ?mM24}ERZpf!rUVP|JdpdH?^opGd&oC@v2jr`#WCNV@SN;;&yT<}kFyjTVY}E7U@5o2TAHLs zLcfFs!}EFJ`SPkIWA>6kH&Z5ay9E=1A;2BZk)0%+{QGP?78`jtz2n(;kI=g@7HgCy zubuwVKwH}YxkGIO+5TEJx%TF@18vf}L-FjPcaP9J8$UGiZhEJO>gtBl*UhN2+8Oxf zKwIl-xlWM>rPQ9?Z9r8w!z1X>V)`m9dysSHwQuKQt=rUzNeG==(mA_I*M>v}QNem_ z6d;9HA)ieczQ z&6+g~WY-9hkpZR#gKUjpXeNk{_0o(RtTPGT;RP!Px7V6_)FHDPi)8E!-`>c7y!AuxTByC}yH1ofC zde77NOJAp{&Ki@dShV^R zeSw_6Lx0e%N>jAvr$RrroJ#$D`O@$u{EMTd4y_4VZ|a2?FI^hCbct(rm$bA4{Ob(Q zb=H*6YjtXp`lK^I5<6*a#hQ*B`jnxImyA*X1FKuD1iT9iOri0C^XE%{YfL%@V6QclC!_di zDI4W5Ch*evF;&0@0DBp1@fb~luEdmeJIe;-^RxF$Z;ZeAV(Bk>V6=(F|4~XqCN)X4 zNV_gAS~N>*w)DpAN;JVD1&bk;z|_V^Or!*@|H{5f&|30oCFd7$p`V3NS#Jy2U$$P= zxRtjYvWJ^&CH6vbEF8>y5J{DM7!xYMW#Hs{9+?`QdUSN^%IK9xH_u*#s1eb2?$Khv z|6a|!$WLqLi;y%29;ISiM6ppmL|_ZO8$a=)b%i8q?-$+Ess`tyJ61~AtvVIeP5lFm zGIUddUH~AafPv5};KVrTY7;E>1(J4!gE)ixc+8uhV|gz@P_mJ;oF6jT^rIN;BR7c= z@n36R?ZHv)qQ+mMLFsvK&z?O!-h5HJC)s%Vbk4tB`udSaXm+Eb0%Q?wP8a%*S7;Qf zGZl6QP7~Fq8yZ?#8t~9tLV`|~MC79sH#nP~ z&unP8q3s!4LH1qJ6v};JQz=V_&IHh!HAo=UgXUSn73YF;zsA@uVQe0>n_wGpH|r2P!#+Z^2b7kSZPiH|X5aEC*}=pukJ5=033W;m zV!t@Qfz(Hb@+6nx%0m*1PIvmOW1Ir+?cvPEGO>_}0s6eMU~+KbN*F5HWvOOK5mS<4 zb$D)QhzBox>%xU^@!$&|!c&})Rkg9rS5qZbY=JNuh(}iBvTC}zDijPV^3cZ|)t*=| zSQ`j5c=RoSWjN~^$VD4{8#gvaB8~M?NTe4eB}68YkRolYSd%NP8(Imua)?iB{8#2v z+&}cg-l0!vg`tNZHlG?A+Bh^+jI_7-s;lF%$xwBr+v)aIwI!M}Znxxid%V7yyyS2@ zYCP4xnn3cE$?D1tg;k^eU<2Rzy?7=QPoy&3A51kbPldvAM}FhV{*B$RYT7nU=nHkY zA;-9N#ud)n)^!D{j5}zXgffLhpkN)Msq%fv9pgv($f7>J_T*pe%t0FC@p(gKY}g%Xj|8$+f}d`8X9e|7t#l!le>K-oTUQ-ViVnXDzH9Bg;T#$%8}S z=qQ{3Mq%HR&`^k&b@z6qa7Kl@nfX*fNlLBnY3gZ9dM}#K>@}a2T+vPWL~rEw*!s3N z*3Vp$mvh(Nm-gmg$?rA4JUaR?&)w6!d33C0FP@=4DJ&mtUv(rmGcU;7j+@hPEjw?@4_3F@imTR zVe=WT&tKxr(QOJEgXoXhdVVb+lERtMXRf-30K%M^~@k0G$h{L^n5GK0CMg?cA8iV+}GG`{#nZqQs{zrX?-^0=^9WO-Mv zx6s|2>FFivgPTlYR|I#TyK=A?$l(MG#nOp@YeQwD(ohlGzGu(&SVe=L!sGmH! zL)Lekoa9^{+^HR?tKN0TmMwSes;)br?HrUH9m9Kaxjn-j=u^x`(gC-1q?LhyTW2g~ zH!Q7brL6mlIG~lr{3o~STTl8!4GkeFj<?3Lj6)DtP)3%wEP4M3Tmzv&HfotN3xlQ^WoQH8vQBI@NsGS(-KR`%)H|iMu?Hu(p&3fsOJwraFZ= zS{@FAnQkYMI%DS<5YUzsGYnnU#H9SX?E%BTMDu&c1RKAwiU`pO8B<_AOhJ@OgmDzF zCZKphI>9(3;0NSF;3JM3bPXyaDFMd$tnhDJW+a2OaqalGq{C*JQf_MIK(>PaJfntk{!&PhRi?Bm8(uC)|RsnQHV-$C!H0Hz@6%Q}K)&#RREL<2oLg3Nh9Vlnm z{2t{vzNJw(E;ZZPGFhjrg47=7jBTfK_^!eYNu`u4p;gpD)40RSxF$16!;V6-kwJ$* zjWogSm*kOz02u+~35`o|I_epyhaNnV2PyQ!aPgA>ln9GAN@xH;1N6^B6qIf-*f#k< zhBTOrWavadbz*3ooi{)IF24UfPRi*MCh;<-&YO?Ei{Et~*>R@H)3PSGC*6xlDura( z-IHY4zBHGVa9{6mzwy>vM%$JHD_0(%GnWG^OIRywgq3f-RZ1uScnMK4$VL6oiFMwc z$26-Qbm@gp{X6=hJ!OK{igkpgr;b~iprqjx9gc8~2|jMGH4h{pFqX3Iqkh8g z@5?`v4V=F8vUNE3z@a*BnTzx7(vWd-?26D;=t6Irmxgbj#uKdrzlE($P0G`61~dM) zuF`UlkCS)q4}7P7q(0^-o}(jgI`FprDk2rSe%p5fevVW6(i)TB)#lFx-)wTk>PNU# zRz+0hhNy=nSUmn!fB5+6JE=c-+`pwu3V-;hHJ$cE?3;$oyBXk;0Q{>s^t_=HwkNVb z2?sS87x~~Y`gzA?U=iVh1YfENEc11&_HEwnyZemq+<)+0e#-Z?Z`FMNHQ#ScvxW!E zANzQR`Ar|+Y(C-s@XP<;|L3>-=I^-TH-Eqje#r5=D$LKw+8iSR$vi9juk%!Vcs{Gb zJd6F%fM*7_#g%|G1n`pX?+6BiYHhZ*HmC-R z7s_JNL8R0oM@5N_;)U`UA6SAT>bg7bSOr6vxbQ(Ji{h7J;tinNxlMbRvcbboM43fcj*MF^h9Xq)9JyjCW;ws}e0O zr#|?Jk*1OC?ce^}$5b_%zwdTgkHua64}Rj$Hw+(I8?DR?#YFP$|NU>TKn@_hn3u6g z8=WUT)=g$klsW*?bCn=tMoQG?YC*BtE-&*Vu>s6Xh3-~g9 zV@9mLWSs)vr`v$ysFE(`kg;yS(SQ^j|QsEH^n$RhEl#dleoZk73| z^tctp_=p}Ff-lsO)rKsw}1 z95om^=p3byBuFqIoc`nF|GcxN|F^6P0zaOYgFpXy$)B5^({YMxAYMUxDjw7m--(0d zA^&Yhg=opn6yE(-OI8w9qd1&q`=xlvKei-qX*tBX3uUr)ePc;GRKC|vdud5t1LEY^ z5=V8)(#R^y3^?8P8T=_Y4K5CcIENGYe&_F95!bNm1Fm1W{qA!W@rwS64^(`# z;_oV6_e4D7p6^vgE5|CoQ2A1oR&}oG`Dz9u`c2i3RX<<-D{ss@=6%BZoG

%>5G!E9d;po#12=2c3%XA;0_N`e8{oF62b@VFl-07 zDP*NP5PqK>cH-t++zz{tzReC-;@n$2TVXQEC*9 N%EGLUS-#`*e*qFO!Ds*g diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.woff b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/fonts/tinymce.woff deleted file mode 100644 index 74b50f4c3001da7fdfffd8638213dcf1a396da78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17484 zcmdsed3+pKo#%U1eW)dMt6P0kt97_r?e3O!v|4JFTDB#*EZOp*C|2y)PMkQAV=F%J zeT0x9Glk8VU?#!KHA6PRVw?<_K!DEz*-glNrgnhrz$Se1VY3V{6IPHVgCOCe7CHud1b%Y{!$C&;GO3{p#KK?|!e|yJcjAafWBz4XjG|%!*TZ@v~)HXE!n{kUBxG zrnc%cdyninj>q^-Isp8f6pnTNspiml_lrjfB1cOBkeK9`aePL{>rBY4ovRZ z$Jm-aWl>rAQ5S(&z6&Of8No1;K=EFk%oHwx8!~yg+6fj*j|)d`vA(!lKbA| zPj5c5=U&ts`XJ(Q;T~k4Ji6z|B+}3?KTq!R%^~OUW2a7IzU}knWQ1gSmS1E}jPcXb z3y6Qz^7$`Wo_i24f4ILqMq!PyU)?Jka|Y97IHZU*g-=ghyhSevH6V||4R}+j2Ik;V z_(Q1YWD?Ti(=F5LYgMoLUTga~pQ)IsnhDH=XBuZ(W?E-DX4IL1nYA-}e(~flzVOT5 zUw-cOL$AO1`pa(|dc%0*_rJP#t~fV`w$SG^n{IuLz2<$b_2+Dci8ewr4Kr!cMs8;1 z%o?=u1lmwV8!s$rgU`Jhcf{q`%2;2lF}g_^RW>Q>lp&>G=~41Zm(r=UD{V@3`1$a+ z!ULffLsh{igO3GkYM-q=TkEiACI<5FcyY!tn;Nl7Rx=V~g_UAy7uNTk)3DNW1_op> z2Ou$kjY$OX%LkGOqVwX+NdfUvrN|KkSH_L;F=0wn=@qmSP(nb zg?2Joo=h~m!hujEpXlyY13hVX6IYTdUcrzHd1<8eA}^wZ^G!S~f9Rp;c*2Y)Iy)26 zbfPn{UUo>AWta3dkGmLmdpvGF?Wk~=oJ+rdD2n{qDN%GHF&>dz@@2^(&pu7X{;Vz@e*F4H%UXzwN{j)^7`8*!v8rxR zof@nu3ns$i7r?vZP-vD(dQm4wVREvrYuFl{i#IiO&Gr<#E!p-(eWTQ%ajh1w*`CvG zhnKg<#ptL}^WQQ?Yt{>IF~-u!O1_x0hIwncSh^#C#gAkCy4enP7yA%nsVr~fncyJr zNoPFV$3qb%=uS4f00G$ee0MLlJX26y5j)nK&Nu-a;-73z18CG9Dr5cg09gQR$W;Ig z1BAOH2&24Jk|3;9-YSX0R(ZGlN6k04G-`8EJmv??50F2nHMZQ`JmAYmR>xbmC0m-^ zYuCD)Taw#a;;SQh-$3y-SD>mY>Z`7+s&1^Vu5dYB{;H}vUv;$Fia(rE)f61>M!c%7 z+83>=3ZPVl$d6Y0>Z+>zBL07xlNx8ybsN`3O`Yo^FvqlH^T4HiB$8}y*_$02%IY28RE7S^Tdu0E`<$AluG8wQ7*(LEvd&vwS6yX~(i(M?;($TW2SI1* zS(>%74wffu>`Av-uVz;xmd~aZ;Y1<8`*>F#E}T@|Y9bs|^MxcqzN`hk)9IKVOHX@) zK`)PU!zcoA42kKJ^@a&w(x<#ZEtXElP`0Rhg9Z{g(=U zsa3bU*5diMYr^3gdVNi!iP4K6n@^N6c5M!`uv}|X@g>p3z2*btOK7U72fb9&8{|eQ zWMT!ZG~mVJIae`-C0QqS!NyjiD!c^Em=6(WF}Wq-1%$ScdQ??MujYW1AVc`enq9#B z+R^~VRDuhO)&*E2c7xF#l&D-LkW`auFq{V{6cEaX!$`?f2yXFcXq9vW&;UmdfC7JG zju~3<&2H^u{cyiBsgx#Q;0ih$v0#8GS?NdNI_?yNXK`;9L4&wLB-i?ZC+mi_*8keJ zc_8%;ZO@grE&+xN2A;+=2M6nJVgnd&caszj`J`lXR#G!PgHk>$2%CG5C$63KlkC=k zWO86@mV7>P-{sxfnGTQNT~RA-x^@;T)gV8<`|^DwdM;ZLtd#gQGXP+;$I>4l8+gHt z26>jd!yX>)ZQ_#jhqiRz=bs>A^zBziwrFEdKRgKzkLcUZM_xDIV4S;bxx$BrR1a6v zJ|0oh(jZqPjd1FT&-bO<4sIEF_1n_lzilGHbWA?{^w>!reEkt8IA|92zbE?E*h#bz z=`C;&`?SjqK2Q*3yapivc_&5&lwN~uqT2-sFwL$S?g}mAf=5tB#w`RJN(bvek%bCW z3VgtBECXQ&d}R&q?ctg?e*ZA@l;;+M76qQS5qEIrCy<{l1JBK03?z-8B{H=Q8!P7yTgo zn5WVqul4&Q=<008UIowP)-&0)Qtd+cooYSSaTXv*nu|@-yV)c=$d0fR>0@W!&VGd*ynobe#o$%vz_b?@duLvc^G811cIah5uU9I5Q01 zc%3!t*cVY0?Bcsy>5lX0V#Y8u^B)jcVQ@pk+Dps;Tx)=92ZR0<40w1zhD#V+WRfvurT3W|B`5+DjK%`mRBGRnT@_Z(ma%55C%!Op5*mVZ z>yl>DG_6Px{Zf}QD{3Oe5_+vnB8qr0Hya*h$jp6g3~)%$&>d;yZsHvYwb1O7+&(!R zYLb*DIo~}f6$WLsCo5&La#HOoCzl|k+Qjaexx#22A6?hj)UnL(U)IsoxNda3 z^~#h(U;oJX_(#5e$o8>Tl9sAB1ap{rhkElZO_bFZtzcdf)0iO}lEIv0gYZas4^JdL zJkPmC;s7=XYzGoQBe5U5Lc32XmXBJnAIRU4H)Frs5Z2gctPECymVwrQ79dy>UqR3y zy!Bwjcu4rj*Z@JBim>&ovM0-$tOH?OC4}Tx1cLXFGLTN?_ z>`)AY01E*!U|CcOAVZMD6%|6h#I}6w-0}AI{V4j|Y6Q?mCgyvSRzrUD@oeo!eKmZ%wuCQPX4N+ge+4a>D zbdoz0@Xvs9V1Dkt3;!q$S4hs-9V(|>y4x#u3B>5@Ok zx^2l++WOpcgtN~*C(Ji!6L_y<%%V+R)~5TqZAv9^_voTF(XdS;p?{^IXC+jN01}uB zvIxOjNvK&+MM#o1L3B%4XE403t^J9@guZE$K2b>YZ|yR5jkA$^ws)4OR_FG6Ml^kn zeLuYM&f|mQf3|=1>ivH8NBl1aKP8jqC)p7Xa_WY$Mu6t0c{)Z0(k$S`nx2usB$)cgz>kR2K~h^D{7Y4RVL6i7-@N z9sjE)OMM)PD09%cd|1*Jh*5X9s&;ql8#d_O>2A-n)6I!TqaEvEIaaFc`??I;#aE1T4@rk zAXl~VAU0J5rEfOGTSj)Pu%zqi?va*t<_9NR`}gT$AIb57)dS%+yzS317YEU zcms@sM5GdBk_^3j=b53QGdsKW`e?(ZmX=Ko(R$D!y@)o=iT;B(c68i$u%Azv6HR?e zw7x#7^fj4N7!q*D-jhDokA8$sI4^jq`I59{31W-n&Lq$sM1e{~6cQMuf6S?BuKmQ| z;EDE}s-L{^#*-&+6yd9-7E{Fe`PY}MHlao-HKs5{yM^*zOsLPsU z06R+O84Ge^n@t5*qkqr|(%}Vtg`cs* zxgDGLFbv?64q0xRVU>a&p5Ymt$N98wPE7&Kr>ziyHkf1K&?d#jS zxy|9&`@Gjj>cjEz`tHb=0{NgbD48F~Z`zcHlQBn=aiggF@N)sXMlM%BY3fREwR-vHPsUz z0?5X-+;mQZx5QpggagE0!ZMS7&kdcpi^iFz8%yo>l7VDmMnz5106om+qfM-tr7=cX z9JOFglPa_`aVkT~Sv}9oFcxzFG8s1bs~>m!oDQG6x<+zGJkfNu)8lk{r29U#`}v(_ zqr2Akzj>hzfV~H#mcpazj3~^1?%Z+S8G9rdRAx zc!psSJ0M>@B^%&;2eF;d*oF9u)02L#;@_3)QFA?AgEFZ&NTstCMHbmzS-C3*n+R$6 z_;-=wD=WFsN~wW|8~92Ib3vXu-e1AQ)9YN;AC2}eTd}4+%AL-!>Okbyrd)Gy_1zyHm&C(mIkRPKbJFPe&&B_?kLP5^ zdw=rf_rzCi?HX~{y3<3^=uo<6?;Sfc4l2$AO@Xmx8Fnv$&%|o?t09%676t zz*2Az5*Z0JiMNKqHxP=5v@}VNgnkJNhUfFb^W{}b#_T17Zl+A;b_*s1Lx4M+BRfet z`S;m)EH?TcddIWx8Krk)EY>I;zk2#h18r>s_N_%*S?*L zwQf@_ic_oBM9MRj-T*bV# zr=Q;O?6c+}2Qy(Xk+g+*(#-$n>0M9bFMWfiI%`Nqk>-f$U8_G~cK|u1UPXXj=NbIDw6>BEwv*r$!aCm8 z4$@>fI>g^nrgU@&Ui^&#%+k8yW$oi)`~>MH+dK6oi(aTFf?KOk8M=7MD23`)w^|8! z7Z#X869ebYmHyV4bPT{=YbZ}f@zGK?%3)04rSmkS0yY5H%V3MgXcBZKrmWjpHXxsy zy8zBf6)V@O)UP8QW`R;NuovCHEGeJSz5EDH)dC&2^J|>46y{JHa=n^C20Lu z_Emz`l20o+zlaO{EQHE>TfqLZ^{Qrmwj8pDn`|ZaLUAk{%zO|@m3$ZzD!^sn4_Z0hpZ&$-P5WD=c7ATO4zMB71d4s1B^0sQ-WRqAfQM)JEcUW!}8g{6kXGo^;lDBB82kPknWDtkUBRMce_0{PAH?&>WXs{42A+!7)~T zle4Be+8IQl%IeB$T*?Wy*H_mNe2_jejqywYS}i?m$*r+~Wf3Rcxa4@Hen^vc7*eZs zFH&Z$kR`t_KLv>MLn~w+D1|ua&J=pPm+?rbhC`)IsM4!u<+J>)XS8RA18srBfxvLl zEq`J5X6ck!`3!&S*@0(=1A!yR8ZPR`>9#7)1?PT)v0cR2JZLw;HsEg70d|^wlxPnq zEh*colQzu0|S^jXI^1>D=inT=&) zArk}id1b-m;KG$KRI!XlJ&r3>( zOe7&i+EB43R~Q;z3Au8ZPiy?w=2P51{G;CCPiuwYhaWbd8Xn#-JY0;lxA>~7PolM?W<}_G-upy$?f)deKmQ>;daz`s(m$q0WnM^#9%5Z-$ z)x10v3d_Q_a(Pa z9O@&B`o!83f3YLGbIbb1Pw|QK>4lg%b$-5(97_+jDP%9-@fRo72AAjKRM`Bh`4|e9 zN)UMiPnvr}z(}06Fx)@p8K^9Ia0nb7g%iLi?0XU#3K6sJ-mVnRsBkwkpDHLxsr9{0 zJ#9(v1@oER=ChJ3x-p;Vjocnv*Y?J`nTzsr?%Ms*?))qH-R4)u#vbOmdzv?mjkoN^ zGyErop5BX!0DEvP1*OmQ@J4SAa)=IVDNDAYamc^TKate@itr8k-%E zF5Oi8>`jsZ%Q2>|V*#io4Kx8%9du5?og=d3;bZ_WIk4!4FKmx0PP*g`;bjiTE=1ZX>P7l}c>OZI#<47HKEw6-OT0O{O+jN2{V`k5uLXpXU5b{Wu&688 zZ}ZUVV4G2JB|zsBy2wjBa2A6LRN^Q`PPkzPNyt;PXuhvy3P9-7-!Cccqy%QV7 z2oNe7U-}X^XfCi{U;zzzLf9*^yerpR= z$r9=rGq#*KvBhWznUo&l)1d~Ou;82pU15IME5YxnCsMi>dLz;sfHFOQ(;MVEFS9Kt za7crr7|~Y|t)b0}C$`8sIXHhy6h5uy_^roeibf+&{=<0xKDK=Fcff^kT|56FeUM;tfk8dOHeDVk+Vir`vf1^{v4dsW?vV00D?cDDkiTLSPXfvSFMzWvI|d#w4MdL4;1>GvSa6);5bK1)L!ytH(^G(BeOj6>PbF!bpc&wP39yNyckmqCV1k@NcaeO=eM)z?U|p4k z=!P3R)@?3s-Q97^d+J7SKU63jx_z{+#xI2;bsKM;RMp8_H`YZ$lE3DU6Yn2cabuz~ zRM~#>=7CVN?5zsA1J%v^pVyy#@8QnQ!|y%2zU`J%&*MQwA6TI3TV!Y2@sG~s!#Rsdbm7{wha zjX5z!#ls7*HNor+3l|2D5O_3r2g(^XzehQaZ)p^cOU-t+Ox7u@Ahm}%W80}5zN>IU zQYqz1XccwPH16;+uE|W&u%nP{WY8f{BTaDoC3z$vKt=$0LgNygj(P^_p$CuTK??ma zT>K;eCBov35*h%|0R8h21*IDdwoN{eAq^%Y89EVAofsNt=giOC#`m7XNjZJOBwps! zIrGum_+96a9cP+6Eo*{%(!H3ZQb?BFJxPY`OLIvH_w^3;8*ja3v~AwEa^*fcbJ@4D zgtf9pSozjlrF8O-mJk(#T+|PpSm)iDJRKI7?&gI{mtOePzoQ@8QzmGwSVvfT>bRu| zN*Yel;Rx55;N$jM^FRUuV=3D{>L>jEf&6pX!0Agb8^XB<4%KnXT%2#0hK!SASA?!Y z7kbmYG<^Fso@gETEo^OSQl5S@nDMuDm6n5ioV;^?;Jfvs^)W~BEFF2%fw%2f5vkDi zTfZCdbDYwb)|mXRHh(7gW|JdUKgy-DDxxYkL_I9Q;_c;%5JO_A%_JIQD^YiOzg_gO+EV_qePtb#U28e6xi+V|I`} z;c+Sv*rb{}c^W3FZk(zKp9~&IO}SvJ>cL?xOjl$8v3)!BN(R61O_(Hv9a}D<8)5u$ zifHsI;$pA};3eJP5ex>^+H7rYPz@H(m&K(0NU24RiV_{g^W`xyh}mBr<3C-BW9EeD7F}bDK-cojDL()@5kmwz zdlL>oeX_-v#W^F=q!&6Sy0X1hiI$d=ANu5I(`feg@BHm!sv6DTce|{|;;#M&Kl$hD zM-HrwR%V7{BKh|J{o5hHI)Qa? zf<+eSB7rnj;)=v?E%u1@D$S<_e3`y6BUWFsPJ!>!Z9s8UNf&d-*hLzu*h}g0pAjr^ zo!<4S;%y>oA_@z#Nc>sxHfz(ZGCz|Zx1tyy(L+P{f=okt zQ}AU0VIS@hk$iv`i3`v}xF#7$hn$I{215s(qcoBP2?m7If0F#4ch>a(j#WY6$MbUV z7r!X^bJKG=PH_#yD`-!}gL>jSagaRZzwM|HE!mmEyWeWbN}_5Mhtq7o6fgNlmgFrh zhd6hkOxCV%ENO?z_u6SMEy-&@oE%%?s7_fLS!J04r`tY*KLw}3#o-X=a3Y_4%}QfA z_#Ie@x9vFPy<1mmt5mObaT_GH&bN83Fx5pK*Wvrh%2PVIOH0xWD^7DNx%s)qmz1UY z(!+8{zC(Tl-#5JN7hWCZP5dLYz70E>oM5ZF&RVtK0<)ktlm7-12UD4<3{B`T< z4%hu%-H&6TSWB!wHXgepb~tu6_C)NT>izZ2^*!~UsDHiT_J(^JH#Xke_+;Y?jnhpH zO`8P<+|NEvngyN`rih6B^06<9QiOAEq!IQ}NjICY!^B~G?XUykGj^E1C<)tP7t%-V za3yH>1yBg?@F2y994jm#yx$JPc7U5gR=NY>_uFA7Zob9sunXy1?QkXT{XTa3;L-OT z**git|3P*XAB!CU^Pb!>dGgf3V@Km%*&I#UK1Co#}7_z+|dJ9*WTBgc-Oj_;p5I(c%>>B)WZyWSVywD;K9v13QGkSVC|)98Ia jnmH;)vjEB<5wG8q|kKzxu40~1eAV&{y5e`l1KFoiKNSOWkz C+YCGa diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/loader.gif b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/loader.gif deleted file mode 100644 index c69e937232b24ea30f01c68bbd2ebc798dcecfcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2608 zcmdVcdr(tX9tZGC9yiG~=H_*Q-0%n(kWqP*D#hw{AQu8;1%gl-Hrf&{2?48KX;hHy z3Ze*zEz4t3XdUFyLbNPUYlA`|B}P=N1fqtL1*}S;87#|-W9v<#G;ul(e%d3)N(^9c$d2Dz{7}?ErjNd;{EMKkCsk21~b9Gvg zDo<7L=3Z5HNbVlZUcm1eg#o#CZCJU`3IYHwM->zCd?uYrF3vKFeM}v?f+%s?E>ly|3W25ry9#NNbTx-}0ON58dTrs^ix{_1O0Wh~SVSBlH)Ajn zPn^Gbjz}PCtN@#keR&hK&Dhl-b$kZ8^S)x#dh0{7X=X%CCJk7P1PSO>T&S8I4{#Lg zb5#)o=;!ZP*1nM{cI4@(x7o27*SA()NHmrn67aN@Pmi~(i_SnrjYnwh36aG%!@i0d zqbvfa44f|?OG4ntP|nbjhEl1)Yp6ZN@yjy zy4==QmLy%t;ps3R?~f2KfTTI|2?q8dFd6^z5GF+Xa&Y)sjG)hxit80pPcOP zJ z*LW{SyGHD%hUotV+W%I}fBLAIx!8|7#}$;clKQ+{&FjDqGQ2ZNx(lYM3*%~}ILnao zM`aui55~ZFJlu^!5rdA9Q_7H68H_;##u{x(Yn-vSfIRCb^Nqsg zGRS!Egm>h+o<}LeV4&CLReo9FrDjDvs}8?JwC)#Qs|ie=r?~xUh)&*d`Fx>FG}%X# zNdtDHBKhLPC0wpooFDAQKL%*6T|ULH$=wX!NhcasgD3d;-d$I6yRK3yN+E~C1335_iLOt+*9uvSZ`>*KA}vm}08wRq=>5l|t*Na&jR z-C1&C`nkEk#sB|@yyt-#fXngP04My zm7u$Q%EJbHp`>~`5W&L{W!6`y&}LMS;jfUpgO~7TLVMRZ9IC)IZp0A${`yp0{&wco z#1nx@XMkhqeK%7?RE7JdLr1^nwFfaJ0Q&Lv?WNJ%9}VSJsNY2+UYs2%EU0J~ayFXv zi*?7KCXQHkD)O6!0Q%4N+HTODHxJ{kQSuQX$l-rSwkwh(zMkdfzxyGwl@yHC)C4p< z&n2%8#M?)Q@mgHL1ot8`SFdSEj9ye|jHy+U8#@HoUExG=@AVkRAe_qYm4EpzK6L*& zh`)26?V#f4#_h^P9G^%>h2-H3)$QP zQovu6J9qDvsxqweDdNNa!Lb?L4_UF{tLX_nN7r0U_vF14YKcGR-*Gl} zx3oG)bzf|65dBxD-;2ZCp??K;+TuQ9onnK?==5hzbkb^r_g>z4#D8mcv8(+XdoszA zCx-qhdgxMNMotj}SiL_6V(tLcsK7(M(r(%u<}QrVfOvyK6_;~NOTlPGfX@M7S5YQF z&*$(ylJMHJt^_aQeu{C6NaTE$G3HNN@_SnN8YcaKn%`)F@~L1x+ah7-gEJPpc6w%3 zyX}r+Qk$4RHZzfH){e~F*qJ{d*L8a6n4;U?+{de0-t)mal#TVxe)3F}^UBh+zd T)6_**#cgp_+?JL9(ew3BlNF>u diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/object.gif b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/img/object.gif deleted file mode 100644 index cccd7f023fb80908cb33bb7d9604236cd21b7ae7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmV;J0B8S4Nk%w1VG#fg0J9GO<>lo+KR<78Z?v?uS65g4{r%Y3*xlXT%F4>`@9+2b z_ww@cot>Tk|Nk>HGXMYpA^8LW000jFEC2ui01*HU000C<(8)=wd#<&tyXIMjHBV`d zBSi|xsj3(;nD0kQ0aJq8eLH~x02P|t2!_J&Wqb%0io?#xD.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #EEE;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#CCC;text-shadow:0 1px 0 white;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#AAA}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:whiteSmoke;border-top:1px solid #DDD;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #c5c5c5;position:relative;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-btn:hover,.mce-btn:focus{text-decoration:none;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn.mce-disabled,.mce-btn.mce-disabled:hover{cursor:default;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);zoom:1;border-color:#04c #04c #002b80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary:hover,.mce-primary:focus{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#005fb3;background-image:-moz-linear-gradient(top,#0077b3,#003cb3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0077b3),to(#003cb3));background-image:-webkit-linear-gradient(top,#0077b3,#003cb3);background-image:-o-linear-gradient(top,#0077b3,#003cb3);background-image:linear-gradient(to bottom,#0077b3,#003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3',endColorstr='#ff003cb3',GradientType=0);zoom:1;border-color:#003cb3 #003cb3 #026;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary button{color:#fff}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #444;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#999}.mce-caret.mce-up{border-bottom:4px solid #444;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-btn:hover,.mce-btn-group .mce-btn:focus{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-disabled,.mce-btn-group .mce-btn.mce-disabled:hover{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-active,.mce-btn-group .mce-btn.mce-active:hover,.mce-btn-group .mce-btn:active{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn-group .mce-btn.mce-disabled button{opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn-group .mce-first{border-left:1px solid #c5c5c5;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #c5c5c5;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0}.mce-checked i.mce-i-checkbox{color:#000;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox{border:1px solid #59a5e1;border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-colorbutton .mce-ico{position:relative}.mce-colorpicker{background:#FFF}.mce-colorbutton-grid{margin:4px}.mce-grid td div{border:1px solid #808080;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:hover{border-color:black}.mce-grid td div:focus{border-color:#59a5e1;outline:1px solid rgba(82,168,236,0.8);border-color:rgba(82,168,236,0.8)}.mce-colorbutton{position:relative}.mce-colorbutton .mce-preview{display:block;position:absolute;left:50%;top:50%;margin-left:-8px;margin-top:7px;background:gray;width:16px;height:2px;overflow:hidden}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;width:100px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-combobox input{border-color:1px solid #c5c5c5;border-right-color:rgba(0,0,0,0.15);height:28px}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox *:focus{border-color:#59a5e1;border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#000}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:gray;color:white}.mce-path .mce-divider{display:inline}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0 solid #c5c5c5;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#999}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ddd}.mce-menubar .mce-menubtn button{color:#000}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubtn:focus{border-color:transparent;background:#ddd;filter:none}.mce-menubtn.mce-disabled span{color:#999}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-listbox span{width:100%;display:block;overflow:hidden}.mce-menu-item{display:block;padding:6px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal}.mce-menu-item.mce-disabled .mce-text{color:#999}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);zoom:1}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-shortcut{display:inline-block;color:#999}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 20px 0 20px}.mce-menu-item .mce-caret{margin-top:6px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #666}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret{border-left-color:#FFF}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item-sep,.mce-menu-item-sep:hover{padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#e5e5e5;border-bottom:1px solid white;cursor:default;filter:none}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item.mce-active{background-color:#c8def4;outline:1px solid #c5c5c5}.mce-menu-item-checkbox.mce-active{background-color:#FFF;outline:0}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#FFF;border:1px solid #CCC;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub{margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}i.mce-radio{padding:1px;margin:0 3px 0 0;background-color:#fafafa;border:1px solid #cacece;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}i.mce-radio:after{font-family:Arial;font-size:12px;color:#000;content:'\25cf'}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#000}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #ccc}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #ccc;border-width:1px 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#FFF;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:normal;color:#000}.mce-textbox:focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.svg#icomoon') format('svg'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-inserttime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e026"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#BBB} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.ie7.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.ie7.min.css deleted file mode 100644 index bb0ca2bac6..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.ie7.min.css +++ /dev/null @@ -1 +0,0 @@ -.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,0.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;border-radius:2px}.mce-wordcount{float:right;padding:8px}.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:center;padding:2px}.mce-charmap td:hover{background:#d9d9d9}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#c5c5c5}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#e8e8e8;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#c4daff;background:#deeafa}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:#ccc 5px 5px 5px;-moz-box-shadow:#ccc 5px 5px 5px;box-shadow:#ccc 5px 5px 5px}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{position:absolute;top:0;left:0;background:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #EEE;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#CCC;text-shadow:0 1px 0 white;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#AAA}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:whiteSmoke;border-top:1px solid #DDD;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #c5c5c5;position:relative;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-btn:hover,.mce-btn:focus{text-decoration:none;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn.mce-disabled,.mce-btn.mce-disabled:hover{cursor:default;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);zoom:1;border-color:#04c #04c #002b80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary:hover,.mce-primary:focus{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#005fb3;background-image:-moz-linear-gradient(top,#0077b3,#003cb3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0077b3),to(#003cb3));background-image:-webkit-linear-gradient(top,#0077b3,#003cb3);background-image:-o-linear-gradient(top,#0077b3,#003cb3);background-image:linear-gradient(to bottom,#0077b3,#003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3',endColorstr='#ff003cb3',GradientType=0);zoom:1;border-color:#003cb3 #003cb3 #026;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary button{color:#fff}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #444;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#999}.mce-caret.mce-up{border-bottom:4px solid #444;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-btn:hover,.mce-btn-group .mce-btn:focus{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-disabled,.mce-btn-group .mce-btn.mce-disabled:hover{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-active,.mce-btn-group .mce-btn.mce-active:hover,.mce-btn-group .mce-btn:active{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn-group .mce-btn.mce-disabled button{opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn-group .mce-first{border-left:1px solid #c5c5c5;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #c5c5c5;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0}.mce-checked i.mce-i-checkbox{color:#000;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox{border:1px solid #59a5e1;border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-colorbutton .mce-ico{position:relative}.mce-colorpicker{background:#FFF}.mce-colorbutton-grid{margin:4px}.mce-grid td div{border:1px solid #808080;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:hover{border-color:black}.mce-grid td div:focus{border-color:#59a5e1;outline:1px solid rgba(82,168,236,0.8);border-color:rgba(82,168,236,0.8)}.mce-colorbutton{position:relative}.mce-colorbutton .mce-preview{display:block;position:absolute;left:50%;top:50%;margin-left:-8px;margin-top:7px;background:gray;width:16px;height:2px;overflow:hidden}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;width:100px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-combobox input{border-color:1px solid #c5c5c5;border-right-color:rgba(0,0,0,0.15);height:28px}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox *:focus{border-color:#59a5e1;border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#000}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:gray;color:white}.mce-path .mce-divider{display:inline}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0 solid #c5c5c5;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#999}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ddd}.mce-menubar .mce-menubtn button{color:#000}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubtn:focus{border-color:transparent;background:#ddd;filter:none}.mce-menubtn.mce-disabled span{color:#999}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-listbox span{width:100%;display:block;overflow:hidden}.mce-menu-item{display:block;padding:6px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal}.mce-menu-item.mce-disabled .mce-text{color:#999}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);zoom:1}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-shortcut{display:inline-block;color:#999}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 20px 0 20px}.mce-menu-item .mce-caret{margin-top:6px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #666}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret{border-left-color:#FFF}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item-sep,.mce-menu-item-sep:hover{padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#e5e5e5;border-bottom:1px solid white;cursor:default;filter:none}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item.mce-active{background-color:#c8def4;outline:1px solid #c5c5c5}.mce-menu-item-checkbox.mce-active{background-color:#FFF;outline:0}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#FFF;border:1px solid #CCC;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub{margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}i.mce-radio{padding:1px;margin:0 3px 0 0;background-color:#fafafa;border:1px solid #cacece;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}i.mce-radio:after{font-family:Arial;font-size:12px;color:#000;content:'\25cf'}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#000}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #ccc}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #ccc;border-width:1px 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#FFF;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:normal;color:#000}.mce-textbox:focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'icomoon';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.svg#icomoon') format('svg'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype');font-weight:normal;font-style:normal}.mce-ico{font-family:'icomoon';font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333;-ie7-icon:' '}.mce-ico,i.mce-i-checkbox{zoom:expression(this.runtimeStyle['zoom'] = '1',this.innerHTML = this.currentStyle['-ie7-icon'].substr(1,1)+' ')}.mce-i-save{-ie7-icon:"\e000"}.mce-i-newdocument{-ie7-icon:"\e001"}.mce-i-fullpage{-ie7-icon:"\e002"}.mce-i-alignleft{-ie7-icon:"\e003"}.mce-i-aligncenter{-ie7-icon:"\e004"}.mce-i-alignright{-ie7-icon:"\e005"}.mce-i-alignjustify{-ie7-icon:"\e006"}.mce-i-cut{-ie7-icon:"\e007"}.mce-i-paste{-ie7-icon:"\e008"}.mce-i-searchreplace{-ie7-icon:"\e009"}.mce-i-bullist{-ie7-icon:"\e00a"}.mce-i-numlist{-ie7-icon:"\e00b"}.mce-i-indent{-ie7-icon:"\e00c"}.mce-i-outdent{-ie7-icon:"\e00d"}.mce-i-blockquote{-ie7-icon:"\e00e"}.mce-i-undo{-ie7-icon:"\e00f"}.mce-i-redo{-ie7-icon:"\e010"}.mce-i-link{-ie7-icon:"\e011"}.mce-i-unlink{-ie7-icon:"\e012"}.mce-i-anchor{-ie7-icon:"\e013"}.mce-i-image{-ie7-icon:"\e014"}.mce-i-media{-ie7-icon:"\e015"}.mce-i-help{-ie7-icon:"\e016"}.mce-i-code{-ie7-icon:"\e017"}.mce-i-inserttime{-ie7-icon:"\e018"}.mce-i-preview{-ie7-icon:"\e019"}.mce-i-forecolor{-ie7-icon:"\e01a"}.mce-i-backcolor{-ie7-icon:"\e01a"}.mce-i-table{-ie7-icon:"\e01b"}.mce-i-hr{-ie7-icon:"\e01c"}.mce-i-removeformat{-ie7-icon:"\e01d"}.mce-i-subscript{-ie7-icon:"\e01e"}.mce-i-superscript{-ie7-icon:"\e01f"}.mce-i-charmap{-ie7-icon:"\e020"}.mce-i-emoticons{-ie7-icon:"\e021"}.mce-i-print{-ie7-icon:"\e022"}.mce-i-fullscreen{-ie7-icon:"\e023"}.mce-i-spellchecker{-ie7-icon:"\e024"}.mce-i-nonbreaking{-ie7-icon:"\e025"}.mce-i-template{-ie7-icon:"\e026"}.mce-i-pagebreak{-ie7-icon:"\e027"}.mce-i-restoredraft{-ie7-icon:"\e028"}.mce-i-untitled{-ie7-icon:"\e029"}.mce-i-bold{-ie7-icon:"\e02a"}.mce-i-italic{-ie7-icon:"\e02b"}.mce-i-underline{-ie7-icon:"\e02c"}.mce-i-strikethrough{-ie7-icon:"\e02d"}.mce-i-visualchars{-ie7-icon:"\e02e"}.mce-i-visualblocks:before{content:"\e026"}.mce-i-ltr{-ie7-icon:"\e02f"}.mce-i-rtl{-ie7-icon:"\e030"}.mce-i-copy{-ie7-icon:"\e031"}.mce-i-resize{-ie7-icon:"\e032"}.mce-i-browse{-ie7-icon:"\e034"}.mce-i-checkbox,.mce-i-selected{-ie7-icon:"\e033"}.mce-i-selected{visibility:hidden}.mce-i-backcolor{background:#BBB} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.min.css b/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.min.css deleted file mode 100644 index 6fa010bce0..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/DELETE_skins/umbraco/skin.min.css +++ /dev/null @@ -1 +0,0 @@ -.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,0.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;border-radius:2px}.mce-wordcount{float:right;padding:8px}.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:center;padding:2px}.mce-charmap td:hover{background:#d9d9d9}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#c5c5c5}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#e8e8e8;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#c4daff;background:#deeafa}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:#ccc 5px 5px 5px;-moz-box-shadow:#ccc 5px 5px 5px;box-shadow:#ccc 5px 5px 5px}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{position:absolute;top:0;left:0;background:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#FFF;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #EEE;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#CCC;text-shadow:0 1px 0 white;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#AAA}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:whiteSmoke;border-top:1px solid #DDD;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #c5c5c5;position:relative;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-btn:hover,.mce-btn:focus{text-decoration:none;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn.mce-disabled,.mce-btn.mce-disabled:hover{cursor:default;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);zoom:1;border-color:#04c #04c #002b80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary:hover,.mce-primary:focus{color:#fff;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#005fb3;background-image:-moz-linear-gradient(top,#0077b3,#003cb3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0077b3),to(#003cb3));background-image:-webkit-linear-gradient(top,#0077b3,#003cb3);background-image:-o-linear-gradient(top,#0077b3,#003cb3);background-image:linear-gradient(to bottom,#0077b3,#003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3',endColorstr='#ff003cb3',GradientType=0);zoom:1;border-color:#003cb3 #003cb3 #026;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-primary button{color:#333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #444;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#999}.mce-caret.mce-up{border-bottom:4px solid #444;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-btn:hover,.mce-btn-group .mce-btn:focus{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#e3e3e3;background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#ccc));background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(to bottom,#f2f2f2,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffcccccc',GradientType=0);zoom:1;border-color:#ccc #ccc #a6a6a6;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-disabled,.mce-btn-group .mce-btn.mce-disabled:hover{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fff,#d9d9d9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9d9d9));background-image:-webkit-linear-gradient(top,#fff,#d9d9d9);background-image:-o-linear-gradient(top,#fff,#d9d9d9);background-image:linear-gradient(to bottom,#fff,#d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffd9d9d9',GradientType=0);zoom:1;border-color:#d9d9d9 #d9d9d9 #b3b3b3;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.mce-btn-group .mce-btn.mce-active,.mce-btn-group .mce-btn.mce-active:hover,.mce-btn-group .mce-btn:active{color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#d6d6d6;background-image:-moz-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#bfbfbf));background-image:-webkit-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:-o-linear-gradient(top,#e6e6e6,#bfbfbf);background-image:linear-gradient(to bottom,#e6e6e6,#bfbfbf);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffbfbfbf',GradientType=0);zoom:1;border-color:#bfbfbf #bfbfbf #999;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-btn-group .mce-btn.mce-disabled button{opacity:.65;filter:alpha(opacity=65);zoom:1}.mce-btn-group .mce-first{border-left:1px solid #c5c5c5;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #c5c5c5;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0}.mce-checked i.mce-i-checkbox{color:#000;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox{border:1px solid #59a5e1;border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-colorbutton .mce-ico{position:relative}.mce-colorpicker{background:#FFF}.mce-colorbutton-grid{margin:4px}.mce-grid td div{border:1px solid #808080;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:hover{border-color:black}.mce-grid td div:focus{border-color:#59a5e1;outline:1px solid rgba(82,168,236,0.8);border-color:rgba(82,168,236,0.8)}.mce-colorbutton{position:relative}.mce-colorbutton .mce-preview{display:block;position:absolute;left:50%;top:50%;margin-left:-8px;margin-top:7px;background:gray;width:16px;height:2px;overflow:hidden}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;width:100px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.mce-combobox input{border-color:1px solid #c5c5c5;border-right-color:rgba(0,0,0,0.15);height:28px}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox *:focus{border-color:#59a5e1;border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#000}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:gray;color:white}.mce-path .mce-divider{display:inline}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0 solid #c5c5c5;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#999}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ddd}.mce-menubar .mce-menubtn button{color:#000}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubtn:focus{border-color:transparent;background:#ddd;filter:none}.mce-menubtn.mce-disabled span{color:#999}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-listbox span{width:100%;display:block;overflow:hidden}.mce-menu-item{display:block;padding:6px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal}.mce-menu-item.mce-disabled .mce-text{color:#999}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0);zoom:1}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-shortcut{display:inline-block;color:#999}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 20px 0 20px}.mce-menu-item .mce-caret{margin-top:6px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #666}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret{border-left-color:#FFF}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item-sep,.mce-menu-item-sep:hover{padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#e5e5e5;border-bottom:1px solid white;cursor:default;filter:none}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item.mce-active{background-color:#c8def4;outline:1px solid #c5c5c5}.mce-menu-item-checkbox.mce-active{background-color:#FFF;outline:0}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#FFF;border:1px solid #CCC;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub{margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}i.mce-radio{padding:1px;margin:0 3px 0 0;background-color:#fafafa;border:1px solid #cacece;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top,#fdfdfd,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fdfdfd),to(#ddd));background-image:-webkit-linear-gradient(top,#fdfdfd,#ddd);background-image:-o-linear-gradient(top,#fdfdfd,#ddd);background-image:linear-gradient(to bottom,#fdfdfd,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd',endColorstr='#ffdddddd',GradientType=0);zoom:1}i.mce-radio:after{font-family:Arial;font-size:12px;color:#000;content:'\25cf'}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#000}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#c5c5c5;border-right-color:#c5c5c5}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #ccc}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #ccc;border-width:1px 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#FFF;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);display:inline-block;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:normal;color:#000}.mce-textbox:focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-inserttime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e026"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#BBB}.mce-i-tablerowprops:before{content:"\e604"}.mce-i-tablecellprops:before{content:"\e605"}.mce-i-table2:before{content:"\e606"}.mce-i-tablemergecells:before{content:"\e607"}.mce-i-tableinsertcolbefore:before{content:"\e608"}.mce-i-tableinsertcolafter:before{content:"\e609"}.mce-i-tableinsertrowbefore:before{content:"\e60a"}.mce-i-tableinsertrowafter:before{content:"\e60b"}.mce-i-tablesplitcells:before{content:"\e60d"}.mce-i-tabledelete:before{content:"\e60e"}.mce-i-tableleftheader:before{content:"\e62a"}.mce-i-tabletopheader:before{content:"\e62b"}.mce-i-tabledeleterow:before{content:"\e800"}.mce-i-tabledeletecol:before{content:"\e801"}.mce-colorbtn-trans div{text-align: center;vertical-align: middle;font-weight: bold;font-size: 20px;line-height: 16px;color: #707070;}.mce-grid td.mce-grid-cell div{border: 1px solid #d6d6d6;width: 15px;height: 15px;margin: 0;cursor: pointer;} \ No newline at end of file From 8b6ede49b4a5ee1a15301d4a0e71f0fa368adccd Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 09:47:16 +0200 Subject: [PATCH 015/337] wip for trying tinymce5 (will revert and come back to this later) --- .../components/grid/grid.rte.directive.js | 2 +- .../src/common/services/tinymce.service.js | 15 ++++++++------- .../views/propertyeditors/rte/rte.controller.js | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index 5d2d763ca3..5d030342ee 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -23,7 +23,7 @@ angular.module("umbraco.directives") //queue file loading if (typeof (tinymce) === "undefined") { - promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope)); + promises.push(assetsService.loadJs("lib/tinymce5/tinymce.min.js", scope)); } var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"]; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 5f79f921e0..8988c489e1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -187,9 +187,9 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //create a baseline Config to exten upon var config = { selector: "#" + args.htmlId, - theme: args.theme ? args.theme : "inlite", - inline: true, - plugins: plugins, + theme: "silver",//args.theme ? args.theme : "inlite", + //inline: true, + //plugins: plugins, valid_elements: tinyMceConfig.validElements, invalid_elements: tinyMceConfig.inValidElements, extended_valid_elements: extendedValidElements, @@ -199,13 +199,14 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh autoresize_bottom_margin: 0, content_css: styles.stylesheets, style_formats: styles.styleFormats, - language: getLanguage(), + //language: getLanguage(), //this would be for a theme other than inlite - toolbar: args.toolbar.join(" "), + //toolbar: args.toolbar.join(" "), + //these are for the inlite theme to work - insert_toolbar: toolbars.insertToolbar, - selection_toolbar: toolbars.selectionToolbar, + //insert_toolbar: toolbars.insertToolbar, + //selection_toolbar: toolbars.selectionToolbar, body_class: 'umb-rte', //see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index c10fd989e8..e7de12ffd3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -65,7 +65,7 @@ angular.module("umbraco") //queue file loading if (typeof tinymce === "undefined") { // Don't reload tinymce if already loaded - promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope)); + promises.push(assetsService.loadJs("lib/tinymce5/tinymce.min.js", $scope)); } //stores a reference to the editor From 08bf996737df13b1e192d7e3feca35e0e6241626 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 09:47:40 +0200 Subject: [PATCH 016/337] Revert "wip for trying tinymce5 (will revert and come back to this later)" This reverts commit 8b6ede49b4a5ee1a15301d4a0e71f0fa368adccd. --- .../components/grid/grid.rte.directive.js | 2 +- .../src/common/services/tinymce.service.js | 15 +++++++-------- .../views/propertyeditors/rte/rte.controller.js | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index 5d030342ee..5d2d763ca3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -23,7 +23,7 @@ angular.module("umbraco.directives") //queue file loading if (typeof (tinymce) === "undefined") { - promises.push(assetsService.loadJs("lib/tinymce5/tinymce.min.js", scope)); + promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope)); } var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"]; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 8988c489e1..5f79f921e0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -187,9 +187,9 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //create a baseline Config to exten upon var config = { selector: "#" + args.htmlId, - theme: "silver",//args.theme ? args.theme : "inlite", - //inline: true, - //plugins: plugins, + theme: args.theme ? args.theme : "inlite", + inline: true, + plugins: plugins, valid_elements: tinyMceConfig.validElements, invalid_elements: tinyMceConfig.inValidElements, extended_valid_elements: extendedValidElements, @@ -199,14 +199,13 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh autoresize_bottom_margin: 0, content_css: styles.stylesheets, style_formats: styles.styleFormats, - //language: getLanguage(), + language: getLanguage(), //this would be for a theme other than inlite - //toolbar: args.toolbar.join(" "), - + toolbar: args.toolbar.join(" "), //these are for the inlite theme to work - //insert_toolbar: toolbars.insertToolbar, - //selection_toolbar: toolbars.selectionToolbar, + insert_toolbar: toolbars.insertToolbar, + selection_toolbar: toolbars.selectionToolbar, body_class: 'umb-rte', //see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index e7de12ffd3..c10fd989e8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -65,7 +65,7 @@ angular.module("umbraco") //queue file loading if (typeof tinymce === "undefined") { // Don't reload tinymce if already loaded - promises.push(assetsService.loadJs("lib/tinymce5/tinymce.min.js", $scope)); + promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope)); } //stores a reference to the editor From 9198d7976ff3cbdaa8e048264fbf2fe24b1a12bb Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 09:50:53 +0200 Subject: [PATCH 017/337] changes the default to classic --- .../src/common/services/tinymce.service.js | 2 +- .../src/views/propertyeditors/rte/rte.prevalues.controller.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 5f79f921e0..266b50fdcb 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -187,7 +187,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //create a baseline Config to exten upon var config = { selector: "#" + args.htmlId, - theme: args.theme ? args.theme : "inlite", + theme: args.theme ? args.theme : "modern", inline: true, plugins: plugins, valid_elements: tinyMceConfig.validElements, diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js index f0fae34628..2ffc40db68 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js @@ -20,7 +20,7 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", $scope.model.value.maxImageSize = cfg.maxImageSize; } if (!$scope.model.value.theme) { - $scope.model.value.theme = "inlite"; + $scope.model.value.theme = "modern"; } tinyMceService.configuration().then(function(config){ From ab846ec4f631727337d7519627fc483ee0833dbe Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 10:00:47 +0200 Subject: [PATCH 018/337] Changes default theme to Modern --- src/Umbraco.Web.UI.Client/package-lock.json | 3009 +---------------- .../propertyeditors/rte/rte.prevalues.html | 4 +- 2 files changed, 161 insertions(+), 2852 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 50be314bbd..2d6c56ffba 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -872,7 +872,7 @@ "acorn-jsx": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", - "integrity": "sha1-6OQeSOov4MiWdAYQq2pP/YrdIl4=", + "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", "dev": true, "requires": { "acorn": "^5.0.3" @@ -894,7 +894,7 @@ "agent-base": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha1-2J5ZmfeXh1Z0wH2H8mD8Qeg+jKk=", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { "es6-promisify": "^5.0.0" @@ -955,7 +955,7 @@ "amqplib": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha1-0tcxPH/6pNELzx5iUt5FkbbMe2M=", + "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", "dev": true, "optional": true, "requires": { @@ -1036,7 +1036,7 @@ }, "ansi-colors": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { @@ -1055,7 +1055,7 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha1-9zIHu4EgfXX9bIPxJa8m7qN4yjA=", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, "ansi-gray": { @@ -1293,7 +1293,7 @@ "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", "dev": true }, "arrify": { @@ -1333,7 +1333,7 @@ "ast-types": { "version": "0.11.5", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", - "integrity": "sha1-mJCCXWYMA8KDOfMV6foKNg4x7Cg=", + "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", "dev": true, "optional": true }, @@ -1362,7 +1362,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "dev": true }, "asynckit": { @@ -1405,7 +1405,7 @@ }, "axios": { "version": "0.15.3", - "resolved": "http://registry.npmjs.org/axios/-/axios-0.15.3.tgz", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", "dev": true, "optional": true, @@ -1415,7 +1415,7 @@ "dependencies": { "follow-redirects": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", "dev": true, "optional": true, @@ -1512,7 +1512,7 @@ }, "basic-auth": { "version": "1.0.4", - "resolved": "http://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", "integrity": "sha1-Awk1sB3nyblKgksp8/zLdQ06UpA=", "dev": true }, @@ -1736,7 +1736,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2139,7 +2139,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -2508,7 +2508,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2565,7 +2565,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -2631,7 +2631,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2666,7 +2666,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -2743,7 +2743,7 @@ "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha1-+XJgj/DOrWi4QaFqky0LGDeRgU4=", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", "dev": true }, "core-util-is": { @@ -2769,7 +2769,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -2884,7 +2884,7 @@ }, "cssnano": { "version": "3.10.0", - "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", "dev": true, "requires": { @@ -2979,7 +2979,7 @@ "data-uri-to-buffer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha1-dxY+qcINhkG0cH6PGKvfmnjzSDU=", + "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", "dev": true, "optional": true }, @@ -3661,7 +3661,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -4006,7 +4006,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, @@ -4142,7 +4142,7 @@ "engine.io": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha1-Dn751pDrCzVZfx1K0Comyi26OEU=", + "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -4173,7 +4173,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -4190,7 +4190,7 @@ "engine.io-client": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha1-W96xMPi5SlCsXL63JYPnpKBj3f0=", + "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -4209,7 +4209,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -4220,7 +4220,7 @@ "engine.io-parser": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha1-TA9M/3mq7su9z96maoI8YIVAkZY=", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", "dev": true, "requires": { "after": "0.8.2", @@ -4316,7 +4316,7 @@ }, "es6-promise": { "version": "3.3.1", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", "dev": true }, @@ -4371,7 +4371,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true } @@ -4515,7 +4515,7 @@ "eslint-scope": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha1-UL8wcekzi83EMzF5Sgy1M/ATYXI=", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -4525,19 +4525,19 @@ "eslint-utils": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha1-moUbqJ7nxGA0b5fPiTnHKYgn5RI=", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "dev": true }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, "espree": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", - "integrity": "sha1-JTmY8goPgttdhmOFeZ2RKoOjZjQ=", + "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", "dev": true, "requires": { "acorn": "^5.6.0", @@ -4553,7 +4553,7 @@ "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -4562,7 +4562,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -4615,7 +4615,7 @@ "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", "dev": true }, "exec-buffer": { @@ -4879,7 +4879,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -5130,7 +5130,7 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true, "optional": true }, @@ -5182,7 +5182,7 @@ }, "finalhandler": { "version": "0.4.0", - "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", "integrity": "sha1-llpS2ejQXSuFdUhUH7ibU6JJfZs=", "dev": true, "requires": { @@ -5194,7 +5194,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -5505,7 +5505,8 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", @@ -5515,7 +5516,8 @@ "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5632,7 +5634,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5644,6 +5647,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5769,7 +5773,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -6050,7 +6055,7 @@ "get-uri": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", - "integrity": "sha1-XHlecTJvbKEoby/IJXXNK6sq9Xg=", + "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", "dev": true, "optional": true, "requires": { @@ -6071,7 +6076,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -6088,7 +6093,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, "requires": { @@ -6229,7 +6234,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -6349,7 +6354,7 @@ }, "lodash": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", "dev": true }, @@ -6484,7 +6489,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -6557,7 +6562,7 @@ }, "gulp-connect": { "version": "5.0.0", - "resolved": "http://registry.npmjs.org/gulp-connect/-/gulp-connect-5.0.0.tgz", + "resolved": "https://registry.npmjs.org/gulp-connect/-/gulp-connect-5.0.0.tgz", "integrity": "sha1-8v3zBq6RFGg2jCKF8teC8T7dr04=", "dev": true, "requires": { @@ -6615,7 +6620,7 @@ "gulp-eslint": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-5.0.0.tgz", - "integrity": "sha1-KiaECV93Syz3kxAmIHjFbMehK1I=", + "integrity": "sha512-9GUqCqh85C7rP9120cpxXuZz2ayq3BZc85pCTuPJS03VQYxne0aWPIXWx6LSvsGPa3uRqtSO537vaugOh+5cXg==", "dev": true, "requires": { "eslint": "^5.0.1", @@ -6836,7 +6841,7 @@ }, "ansi-regex": { "version": "0.2.1", - "resolved": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", "dev": true }, @@ -6848,7 +6853,7 @@ }, "chalk": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", "dev": true, "requires": { @@ -6921,7 +6926,7 @@ }, "lodash": { "version": "2.4.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", "integrity": "sha1-W3cjA03aTSYuWkb7LFjXzCL3FCA=", "dev": true }, @@ -7011,13 +7016,13 @@ }, "minimist": { "version": "0.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", "dev": true }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -7029,7 +7034,7 @@ }, "strip-ansi": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", "dev": true, "requires": { @@ -7213,7 +7218,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -7402,7 +7407,7 @@ "has-binary2": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", "dev": true, "requires": { "isarray": "2.0.1" @@ -7537,7 +7542,7 @@ }, "http-errors": { "version": "1.3.1", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", "dev": true, "requires": { @@ -7554,7 +7559,7 @@ "http-proxy": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { "eventemitter3": "^3.0.0", @@ -7565,7 +7570,7 @@ "http-proxy-agent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha1-5IIb7vWyFCogJr1zkm/lN2McVAU=", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "dev": true, "requires": { "agent-base": "4", @@ -7575,7 +7580,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -7621,7 +7626,7 @@ "https-proxy-agent": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { "agent-base": "^4.1.0", @@ -7647,7 +7652,7 @@ }, "iconv-lite": { "version": "0.4.11", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", "integrity": "sha1-LstC/SlHRJIiCaLnxATayHk9it4=", "dev": true }, @@ -8071,7 +8076,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { @@ -8215,7 +8220,7 @@ "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha1-ezUbjo7dTTmV1NBmaA5mTZRpaCQ=", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", "dev": true, "optional": true }, @@ -8274,7 +8279,7 @@ "is-path-in-cwd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha1-WsSLNF72dTOb1sekipEhELJBz1I=", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { "is-path-inside": "^1.0.0" @@ -8362,7 +8367,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-retry-allowed": { @@ -8579,7 +8584,7 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify": { @@ -8611,7 +8616,7 @@ }, "jsonfile": { "version": "2.4.0", - "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { @@ -8663,7 +8668,7 @@ "karma": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.5.tgz", - "integrity": "sha1-NxDHoucbHEOTE/KDhG2I4E5PkYw=", + "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", "dev": true, "requires": { "bluebird": "^3.3.0", @@ -8698,7 +8703,7 @@ "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -8732,7 +8737,7 @@ "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha1-NW/04rDo5D4yLRijckYLvPOszSY=", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -8799,7 +8804,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -8812,7 +8817,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -8830,7 +8835,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "range-parser": { @@ -8842,7 +8847,7 @@ "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "dev": true, "requires": { "bytes": "3.0.0", @@ -8854,7 +8859,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "utils-merge": { @@ -9024,7 +9029,7 @@ "dependencies": { "iconv-lite": { "version": "0.4.15", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", "dev": true } @@ -9060,7 +9065,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -9372,7 +9377,7 @@ "log4js": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.11.0.tgz", - "integrity": "sha1-vzkC7/ZcaSPZzpz70ttUFg40AFo=", + "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", "dev": true, "requires": { "amqplib": "^0.5.2", @@ -9534,7 +9539,7 @@ }, "readable-stream": { "version": "2.0.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "optional": true, @@ -9549,7 +9554,7 @@ }, "request": { "version": "2.75.0", - "resolved": "http://registry.npmjs.org/request/-/request-2.75.0.tgz", + "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", "dev": true, "optional": true, @@ -9643,7 +9648,7 @@ "mailgun-js": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", - "integrity": "sha1-7jmqGNe7WYpc6e3oSvtoHe/IprA=", + "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", "dev": true, "optional": true, "requires": { @@ -9671,7 +9676,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "optional": true, "requires": { @@ -9747,7 +9752,7 @@ }, "marked": { "version": "0.3.2", - "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.2.tgz", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.2.tgz", "integrity": "sha1-AV2xWIZEOPJKZL3WGgQotBhwbQk=", "dev": true }, @@ -9795,7 +9800,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -9913,7 +9918,7 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { @@ -9927,7 +9932,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, @@ -9954,7 +9959,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -9968,7 +9973,7 @@ }, "morgan": { "version": "1.6.1", - "resolved": "http://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", "integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=", "dev": true, "requires": { @@ -9981,7 +9986,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -10267,2702 +10272,6 @@ "sort-keys": "^1.0.0" } }, - "npm": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.4.1.tgz", - "integrity": "sha512-mXJL1NTVU136PtuopXCUQaNWuHlXCTp4McwlSW8S9/Aj8OEPAlSBgo8og7kJ01MjCDrkmqFQTvN5tTEhBMhXQg==", - "requires": { - "JSONStream": "^1.3.4", - "abbrev": "~1.1.1", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "aproba": "~1.2.0", - "archy": "~1.0.0", - "bin-links": "^1.1.2", - "bluebird": "~3.5.1", - "byte-size": "^4.0.3", - "cacache": "^11.2.0", - "call-limit": "~1.1.0", - "chownr": "~1.0.1", - "ci-info": "^1.4.0", - "cli-columns": "^3.1.2", - "cli-table3": "^0.5.0", - "cmd-shim": "~2.0.2", - "columnify": "~1.5.4", - "config-chain": "~1.1.11", - "debuglog": "*", - "detect-indent": "~5.0.0", - "detect-newline": "^2.1.0", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "figgy-pudding": "^3.4.1", - "find-npm-prefix": "^1.0.2", - "fs-vacuum": "~1.2.10", - "fs-write-stream-atomic": "~1.0.10", - "gentle-fs": "^2.0.1", - "glob": "~7.1.2", - "graceful-fs": "~4.1.11", - "has-unicode": "~2.0.1", - "hosted-git-info": "^2.7.1", - "iferr": "^1.0.2", - "imurmurhash": "*", - "inflight": "~1.0.6", - "inherits": "~2.0.3", - "ini": "^1.3.5", - "init-package-json": "^1.10.3", - "is-cidr": "^2.0.6", - "json-parse-better-errors": "^1.0.2", - "lazy-property": "~1.0.0", - "libcipm": "^2.0.2", - "libnpmhook": "^4.0.1", - "libnpx": "^10.2.0", - "lock-verify": "^2.0.2", - "lockfile": "^1.0.4", - "lodash._baseindexof": "*", - "lodash._baseuniq": "~4.6.0", - "lodash._bindcallback": "*", - "lodash._cacheindexof": "*", - "lodash._createcache": "*", - "lodash._getnative": "*", - "lodash.clonedeep": "~4.5.0", - "lodash.restparam": "*", - "lodash.union": "~4.6.0", - "lodash.uniq": "~4.5.0", - "lodash.without": "~4.4.0", - "lru-cache": "^4.1.3", - "meant": "~1.0.1", - "mississippi": "^3.0.0", - "mkdirp": "~0.5.1", - "move-concurrently": "^1.0.1", - "node-gyp": "^3.8.0", - "nopt": "~4.0.1", - "normalize-package-data": "~2.4.0", - "npm-audit-report": "^1.3.1", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "~3.0.0", - "npm-lifecycle": "^2.1.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.11", - "npm-pick-manifest": "^2.1.0", - "npm-profile": "^3.0.2", - "npm-registry-client": "^8.6.0", - "npm-registry-fetch": "^1.1.0", - "npm-user-validate": "~1.0.0", - "npmlog": "~4.1.2", - "once": "~1.4.0", - "opener": "^1.5.0", - "osenv": "^0.1.5", - "pacote": "^8.1.6", - "path-is-inside": "~1.0.2", - "promise-inflight": "~1.0.1", - "qrcode-terminal": "^0.12.0", - "query-string": "^6.1.0", - "qw": "~1.0.1", - "read": "~1.0.7", - "read-cmd-shim": "~1.0.1", - "read-installed": "~4.0.3", - "read-package-json": "^2.0.13", - "read-package-tree": "^5.2.1", - "readable-stream": "^2.3.6", - "readdir-scoped-modules": "*", - "request": "^2.88.0", - "retry": "^0.12.0", - "rimraf": "~2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.5.0", - "sha": "~2.0.1", - "slide": "~1.1.6", - "sorted-object": "~2.0.1", - "sorted-union-stream": "~2.1.3", - "ssri": "^6.0.0", - "stringify-package": "^1.0.0", - "tar": "^4.4.6", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "unique-filename": "~1.1.0", - "unpipe": "~1.0.0", - "update-notifier": "^2.5.0", - "uuid": "^3.3.2", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "~3.0.0", - "which": "^1.3.1", - "worker-farm": "^1.6.0", - "write-file-atomic": "^2.3.0" - }, - "dependencies": { - "JSONStream": { - "version": "1.3.4", - "bundled": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "abbrev": { - "version": "1.1.1", - "bundled": true - }, - "agent-base": { - "version": "4.2.0", - "bundled": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "agentkeepalive": { - "version": "3.4.1", - "bundled": true, - "requires": { - "humanize-ms": "^1.2.1" - } - }, - "ajv": { - "version": "5.5.2", - "bundled": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-align": { - "version": "2.0.0", - "bundled": true, - "requires": { - "string-width": "^2.0.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true - }, - "ansistyles": { - "version": "0.1.3", - "bundled": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true - }, - "archy": { - "version": "1.0.0", - "bundled": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "asap": { - "version": "2.0.6", - "bundled": true - }, - "asn1": { - "version": "0.2.4", - "bundled": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "bundled": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true - }, - "aws-sign2": { - "version": "0.7.0", - "bundled": true - }, - "aws4": { - "version": "1.8.0", - "bundled": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bin-links": { - "version": "1.1.2", - "bundled": true, - "requires": { - "bluebird": "^3.5.0", - "cmd-shim": "^2.0.2", - "gentle-fs": "^2.0.0", - "graceful-fs": "^4.1.11", - "write-file-atomic": "^2.3.0" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.5.1", - "bundled": true - }, - "boxen": { - "version": "1.3.0", - "bundled": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.0.0", - "bundled": true - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true - }, - "builtins": { - "version": "1.0.3", - "bundled": true - }, - "byline": { - "version": "5.0.0", - "bundled": true - }, - "byte-size": { - "version": "4.0.3", - "bundled": true - }, - "cacache": { - "version": "11.2.0", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "figgy-pudding": "^3.1.0", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.3", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^6.0.0", - "unique-filename": "^1.1.0", - "y18n": "^4.0.0" - } - }, - "call-limit": { - "version": "1.1.0", - "bundled": true - }, - "camelcase": { - "version": "4.1.0", - "bundled": true - }, - "capture-stack-trace": { - "version": "1.0.0", - "bundled": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true - }, - "chalk": { - "version": "2.4.1", - "bundled": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true - }, - "ci-info": { - "version": "1.4.0", - "bundled": true - }, - "cidr-regex": { - "version": "2.0.9", - "bundled": true, - "requires": { - "ip-regex": "^2.1.0" - } - }, - "cli-boxes": { - "version": "1.0.0", - "bundled": true - }, - "cli-columns": { - "version": "3.1.2", - "bundled": true, - "requires": { - "string-width": "^2.0.0", - "strip-ansi": "^3.0.1" - } - }, - "cli-table3": { - "version": "0.5.0", - "bundled": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "cliui": { - "version": "4.1.0", - "bundled": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "clone": { - "version": "1.0.4", - "bundled": true - }, - "cmd-shim": { - "version": "2.0.2", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "co": { - "version": "4.6.0", - "bundled": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "color-convert": { - "version": "1.9.1", - "bundled": true, - "requires": { - "color-name": "^1.1.1" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true - }, - "colors": { - "version": "1.1.2", - "bundled": true, - "optional": true - }, - "columnify": { - "version": "1.5.4", - "bundled": true, - "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - } - }, - "combined-stream": { - "version": "1.0.6", - "bundled": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "concat-stream": { - "version": "1.6.2", - "bundled": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "config-chain": { - "version": "1.1.11", - "bundled": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "configstore": { - "version": "3.1.2", - "bundled": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "copy-concurrently": { - "version": "1.0.5", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "create-error-class": { - "version": "3.0.2", - "bundled": true, - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-random-string": { - "version": "1.0.0", - "bundled": true - }, - "cyclist": { - "version": "0.2.2", - "bundled": true - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.1.0", - "bundled": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true - } - } - }, - "debuglog": { - "version": "1.0.1", - "bundled": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true - }, - "decode-uri-component": { - "version": "0.2.0", - "bundled": true - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true - }, - "defaults": { - "version": "1.0.3", - "bundled": true, - "requires": { - "clone": "^1.0.2" - } - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true - }, - "detect-indent": { - "version": "5.0.0", - "bundled": true - }, - "detect-newline": { - "version": "2.1.0", - "bundled": true - }, - "dezalgo": { - "version": "1.0.3", - "bundled": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "dot-prop": { - "version": "4.2.0", - "bundled": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "dotenv": { - "version": "5.0.1", - "bundled": true - }, - "duplexer3": { - "version": "0.1.4", - "bundled": true - }, - "duplexify": { - "version": "3.6.0", - "bundled": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editor": { - "version": "1.0.0", - "bundled": true - }, - "encoding": { - "version": "0.1.12", - "bundled": true, - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.1", - "bundled": true, - "requires": { - "once": "^1.4.0" - } - }, - "err-code": { - "version": "1.1.2", - "bundled": true - }, - "errno": { - "version": "0.1.7", - "bundled": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es6-promise": { - "version": "4.2.4", - "bundled": true - }, - "es6-promisify": { - "version": "5.0.0", - "bundled": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "extend": { - "version": "3.0.2", - "bundled": true - }, - "extsprintf": { - "version": "1.3.0", - "bundled": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "bundled": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "bundled": true - }, - "figgy-pudding": { - "version": "3.4.1", - "bundled": true - }, - "find-npm-prefix": { - "version": "1.0.2", - "bundled": true - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flush-write-stream": { - "version": "1.0.3", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" - } - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true - }, - "form-data": { - "version": "2.3.2", - "bundled": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "from2": { - "version": "2.3.0", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs-vacuum": { - "version": "1.2.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "genfun": { - "version": "4.0.1", - "bundled": true - }, - "gentle-fs": { - "version": "2.0.1", - "bundled": true, - "requires": { - "aproba": "^1.1.2", - "fs-vacuum": "^1.2.10", - "graceful-fs": "^4.1.11", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "path-is-inside": "^1.0.2", - "read-cmd-shim": "^1.0.1", - "slide": "^1.1.6" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global-dirs": { - "version": "0.1.1", - "bundled": true, - "requires": { - "ini": "^1.3.4" - } - }, - "got": { - "version": "6.7.1", - "bundled": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true - }, - "har-schema": { - "version": "2.0.0", - "bundled": true - }, - "har-validator": { - "version": "5.1.0", - "bundled": true, - "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "bundled": true - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true - }, - "hosted-git-info": { - "version": "2.7.1", - "bundled": true - }, - "http-cache-semantics": { - "version": "3.8.1", - "bundled": true - }, - "http-proxy-agent": { - "version": "2.1.0", - "bundled": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "2.2.1", - "bundled": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - } - }, - "humanize-ms": { - "version": "1.2.1", - "bundled": true, - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "bundled": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "iferr": { - "version": "1.0.2", - "bundled": true - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "import-lazy": { - "version": "2.1.0", - "bundled": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.5", - "bundled": true - }, - "init-package-json": { - "version": "1.10.3", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", - "promzard": "^0.3.0", - "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", - "validate-npm-package-name": "^3.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true - }, - "ip": { - "version": "1.1.5", - "bundled": true - }, - "ip-regex": { - "version": "2.1.0", - "bundled": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-ci": { - "version": "1.1.0", - "bundled": true, - "requires": { - "ci-info": "^1.0.0" - } - }, - "is-cidr": { - "version": "2.0.6", - "bundled": true, - "requires": { - "cidr-regex": "^2.0.8" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-installed-globally": { - "version": "0.1.0", - "bundled": true, - "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - } - }, - "is-npm": { - "version": "1.0.0", - "bundled": true - }, - "is-obj": { - "version": "1.0.1", - "bundled": true - }, - "is-path-inside": { - "version": "1.0.1", - "bundled": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-redirect": { - "version": "1.0.0", - "bundled": true - }, - "is-retry-allowed": { - "version": "1.1.0", - "bundled": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "bundled": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "bundled": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "jsonparse": { - "version": "1.3.1", - "bundled": true - }, - "jsprim": { - "version": "1.4.1", - "bundled": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "latest-version": { - "version": "3.1.0", - "bundled": true, - "requires": { - "package-json": "^4.0.0" - } - }, - "lazy-property": { - "version": "1.0.0", - "bundled": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "libcipm": { - "version": "2.0.2", - "bundled": true, - "requires": { - "bin-links": "^1.1.2", - "bluebird": "^3.5.1", - "find-npm-prefix": "^1.0.2", - "graceful-fs": "^4.1.11", - "lock-verify": "^2.0.2", - "mkdirp": "^0.5.1", - "npm-lifecycle": "^2.0.3", - "npm-logical-tree": "^1.2.1", - "npm-package-arg": "^6.1.0", - "pacote": "^8.1.6", - "protoduck": "^5.0.0", - "read-package-json": "^2.0.13", - "rimraf": "^2.6.2", - "worker-farm": "^1.6.0" - } - }, - "libnpmhook": { - "version": "4.0.1", - "bundled": true, - "requires": { - "figgy-pudding": "^3.1.0", - "npm-registry-fetch": "^3.0.0" - }, - "dependencies": { - "npm-registry-fetch": { - "version": "3.1.1", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "figgy-pudding": "^3.1.0", - "lru-cache": "^4.1.2", - "make-fetch-happen": "^4.0.0", - "npm-package-arg": "^6.0.0" - } - } - } - }, - "libnpx": { - "version": "10.2.0", - "bundled": true, - "requires": { - "dotenv": "^5.0.1", - "npm-package-arg": "^6.0.0", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.0", - "update-notifier": "^2.3.0", - "which": "^1.3.0", - "y18n": "^4.0.0", - "yargs": "^11.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lock-verify": { - "version": "2.0.2", - "bundled": true, - "requires": { - "npm-package-arg": "^5.1.2 || 6", - "semver": "^5.4.1" - } - }, - "lockfile": { - "version": "1.0.4", - "bundled": true, - "requires": { - "signal-exit": "^3.0.2" - } - }, - "lodash._baseindexof": { - "version": "3.1.0", - "bundled": true - }, - "lodash._baseuniq": { - "version": "4.6.0", - "bundled": true, - "requires": { - "lodash._createset": "~4.0.0", - "lodash._root": "~3.0.0" - } - }, - "lodash._bindcallback": { - "version": "3.0.1", - "bundled": true - }, - "lodash._cacheindexof": { - "version": "3.0.2", - "bundled": true - }, - "lodash._createcache": { - "version": "3.1.2", - "bundled": true, - "requires": { - "lodash._getnative": "^3.0.0" - } - }, - "lodash._createset": { - "version": "4.0.3", - "bundled": true - }, - "lodash._getnative": { - "version": "3.9.1", - "bundled": true - }, - "lodash._root": { - "version": "3.0.1", - "bundled": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "bundled": true - }, - "lodash.restparam": { - "version": "3.6.1", - "bundled": true - }, - "lodash.union": { - "version": "4.6.0", - "bundled": true - }, - "lodash.uniq": { - "version": "4.5.0", - "bundled": true - }, - "lodash.without": { - "version": "4.4.0", - "bundled": true - }, - "lowercase-keys": { - "version": "1.0.1", - "bundled": true - }, - "lru-cache": { - "version": "4.1.3", - "bundled": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "1.3.0", - "bundled": true, - "requires": { - "pify": "^3.0.0" - } - }, - "make-fetch-happen": { - "version": "4.0.1", - "bundled": true, - "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^11.0.1", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" - } - }, - "meant": { - "version": "1.0.1", - "bundled": true - }, - "mem": { - "version": "1.1.0", - "bundled": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "mime-db": { - "version": "1.35.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.19", - "bundled": true, - "requires": { - "mime-db": "~1.35.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "minipass": { - "version": "2.3.3", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - }, - "dependencies": { - "yallist": { - "version": "3.0.2", - "bundled": true - } - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mississippi": { - "version": "3.0.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "move-concurrently": { - "version": "1.0.1", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true - }, - "mute-stream": { - "version": "0.0.7", - "bundled": true - }, - "node-fetch-npm": { - "version": "2.0.2", - "bundled": true, - "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node-gyp": { - "version": "3.8.0", - "bundled": true, - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "nopt": { - "version": "3.0.6", - "bundled": true, - "requires": { - "abbrev": "1" - } - }, - "semver": { - "version": "5.3.0", - "bundled": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - } - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "bundled": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-audit-report": { - "version": "1.3.1", - "bundled": true, - "requires": { - "cli-table3": "^0.5.0", - "console-control-strings": "^1.1.0" - } - }, - "npm-bundled": { - "version": "1.0.5", - "bundled": true - }, - "npm-cache-filename": { - "version": "1.0.2", - "bundled": true - }, - "npm-install-checks": { - "version": "3.0.0", - "bundled": true, - "requires": { - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "npm-lifecycle": { - "version": "2.1.0", - "bundled": true, - "requires": { - "byline": "^5.0.0", - "graceful-fs": "^4.1.11", - "node-gyp": "^3.8.0", - "resolve-from": "^4.0.0", - "slide": "^1.1.6", - "uid-number": "0.0.6", - "umask": "^1.1.0", - "which": "^1.3.1" - } - }, - "npm-logical-tree": { - "version": "1.2.1", - "bundled": true - }, - "npm-package-arg": { - "version": "6.1.0", - "bundled": true, - "requires": { - "hosted-git-info": "^2.6.0", - "osenv": "^0.1.5", - "semver": "^5.5.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "npm-packlist": { - "version": "1.1.11", - "bundled": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npm-pick-manifest": { - "version": "2.1.0", - "bundled": true, - "requires": { - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" - } - }, - "npm-profile": { - "version": "3.0.2", - "bundled": true, - "requires": { - "aproba": "^1.1.2 || 2", - "make-fetch-happen": "^2.5.0 || 3 || 4" - } - }, - "npm-registry-client": { - "version": "8.6.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", - "npmlog": "2 || ^3.1.0 || ^4.0.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "safe-buffer": "^5.1.1", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3", - "ssri": "^5.2.4" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "bundled": true - }, - "ssri": { - "version": "5.3.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.1" - } - } - } - }, - "npm-registry-fetch": { - "version": "1.1.0", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "figgy-pudding": "^2.0.1", - "lru-cache": "^4.1.2", - "make-fetch-happen": "^3.0.0", - "npm-package-arg": "^6.0.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "cacache": { - "version": "10.0.4", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^2.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^5.2.4", - "unique-filename": "^1.1.0", - "y18n": "^4.0.0" - }, - "dependencies": { - "mississippi": { - "version": "2.0.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^2.0.1", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - } - } - }, - "figgy-pudding": { - "version": "2.0.1", - "bundled": true - }, - "make-fetch-happen": { - "version": "3.0.0", - "bundled": true, - "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^10.0.4", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lru-cache": "^4.1.2", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^3.0.1", - "ssri": "^5.2.4" - } - }, - "pump": { - "version": "2.0.1", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "smart-buffer": { - "version": "1.1.15", - "bundled": true - }, - "socks": { - "version": "1.1.10", - "bundled": true, - "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" - } - }, - "socks-proxy-agent": { - "version": "3.0.1", - "bundled": true, - "requires": { - "agent-base": "^4.1.0", - "socks": "^1.1.10" - } - }, - "ssri": { - "version": "5.3.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.1" - } - } - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "npm-user-validate": { - "version": "1.0.0", - "bundled": true - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "oauth-sign": { - "version": "0.9.0", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.0", - "bundled": true - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-locale": { - "version": "2.1.0", - "bundled": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true - }, - "p-limit": { - "version": "1.2.0", - "bundled": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "bundled": true - }, - "package-json": { - "version": "4.0.1", - "bundled": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - } - }, - "pacote": { - "version": "8.1.6", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "cacache": "^11.0.2", - "get-stream": "^3.0.0", - "glob": "^7.1.2", - "lru-cache": "^4.1.3", - "make-fetch-happen": "^4.0.1", - "minimatch": "^3.0.4", - "minipass": "^2.3.3", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.10", - "npm-pick-manifest": "^2.1.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^5.0.0", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.5.0", - "ssri": "^6.0.0", - "tar": "^4.4.3", - "unique-filename": "^1.1.0", - "which": "^1.3.0" - } - }, - "parallel-transform": { - "version": "1.1.0", - "bundled": true, - "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "path-exists": { - "version": "3.0.0", - "bundled": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "path-is-inside": { - "version": "1.0.2", - "bundled": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true - }, - "performance-now": { - "version": "2.1.0", - "bundled": true - }, - "pify": { - "version": "3.0.0", - "bundled": true - }, - "prepend-http": { - "version": "1.0.4", - "bundled": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true - }, - "promise-inflight": { - "version": "1.0.1", - "bundled": true - }, - "promise-retry": { - "version": "1.1.1", - "bundled": true, - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "bundled": true - } - } - }, - "promzard": { - "version": "0.3.0", - "bundled": true, - "requires": { - "read": "1" - } - }, - "proto-list": { - "version": "1.2.4", - "bundled": true - }, - "protoduck": { - "version": "5.0.0", - "bundled": true, - "requires": { - "genfun": "^4.0.1" - } - }, - "prr": { - "version": "1.0.1", - "bundled": true - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true - }, - "psl": { - "version": "1.1.29", - "bundled": true - }, - "pump": { - "version": "3.0.0", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "bundled": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "1.4.1", - "bundled": true - }, - "qrcode-terminal": { - "version": "0.12.0", - "bundled": true - }, - "qs": { - "version": "6.5.2", - "bundled": true - }, - "query-string": { - "version": "6.1.0", - "bundled": true, - "requires": { - "decode-uri-component": "^0.2.0", - "strict-uri-encode": "^2.0.0" - } - }, - "qw": { - "version": "1.0.1", - "bundled": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } - } - }, - "read": { - "version": "1.0.7", - "bundled": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "read-cmd-shim": { - "version": "1.0.1", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "read-installed": { - "version": "4.0.3", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "graceful-fs": "^4.1.2", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - } - }, - "read-package-json": { - "version": "2.0.13", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "json-parse-better-errors": "^1.0.1", - "normalize-package-data": "^2.0.0", - "slash": "^1.0.0" - } - }, - "read-package-tree": { - "version": "5.2.1", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "once": "^1.3.0", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdir-scoped-modules": { - "version": "1.0.2", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "registry-auth-token": { - "version": "3.3.2", - "bundled": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "bundled": true, - "requires": { - "rc": "^1.0.1" - } - }, - "request": { - "version": "2.88.0", - "bundled": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true - }, - "resolve-from": { - "version": "4.0.0", - "bundled": true - }, - "retry": { - "version": "0.12.0", - "bundled": true - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-queue": { - "version": "1.0.3", - "bundled": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true - }, - "semver": { - "version": "5.5.0", - "bundled": true - }, - "semver-diff": { - "version": "2.1.0", - "bundled": true, - "requires": { - "semver": "^5.0.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - }, - "sha": { - "version": "2.0.1", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "readable-stream": "^2.0.2" - } - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "slash": { - "version": "1.0.0", - "bundled": true - }, - "slide": { - "version": "1.1.6", - "bundled": true - }, - "smart-buffer": { - "version": "4.0.1", - "bundled": true - }, - "socks": { - "version": "2.2.0", - "bundled": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" - } - }, - "socks-proxy-agent": { - "version": "4.0.1", - "bundled": true, - "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" - } - }, - "sorted-object": { - "version": "2.0.1", - "bundled": true - }, - "sorted-union-stream": { - "version": "2.1.3", - "bundled": true, - "requires": { - "from2": "^1.3.0", - "stream-iterate": "^1.1.0" - }, - "dependencies": { - "from2": { - "version": "1.3.0", - "bundled": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~1.1.10" - } - }, - "isarray": { - "version": "0.0.1", - "bundled": true - }, - "readable-stream": { - "version": "1.1.14", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - } - } - }, - "spdx-correct": { - "version": "3.0.0", - "bundled": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "bundled": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "bundled": true - }, - "sshpk": { - "version": "1.14.2", - "bundled": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "6.0.0", - "bundled": true - }, - "stream-each": { - "version": "1.2.2", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-iterate": { - "version": "1.2.0", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "stream-shift": "^1.0.0" - } - }, - "stream-shift": { - "version": "1.0.0", - "bundled": true - }, - "strict-uri-encode": { - "version": "2.0.0", - "bundled": true - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringify-package": { - "version": "1.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - }, - "supports-color": { - "version": "5.4.0", - "bundled": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tar": { - "version": "4.4.6", - "bundled": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.3", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - }, - "dependencies": { - "yallist": { - "version": "3.0.2", - "bundled": true - } - } - }, - "term-size": { - "version": "1.2.0", - "bundled": true, - "requires": { - "execa": "^0.7.0" - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true - }, - "through": { - "version": "2.3.8", - "bundled": true - }, - "through2": { - "version": "2.0.3", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - } - }, - "timed-out": { - "version": "4.0.1", - "bundled": true - }, - "tiny-relative-date": { - "version": "1.3.0", - "bundled": true - }, - "tough-cookie": { - "version": "2.4.3", - "bundled": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "optional": true - }, - "typedarray": { - "version": "0.0.6", - "bundled": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true - }, - "umask": { - "version": "1.1.0", - "bundled": true - }, - "unique-filename": { - "version": "1.1.0", - "bundled": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.0", - "bundled": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-string": { - "version": "1.0.0", - "bundled": true, - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "bundled": true - }, - "unzip-response": { - "version": "2.0.1", - "bundled": true - }, - "update-notifier": { - "version": "2.5.0", - "bundled": true, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "url-parse-lax": { - "version": "1.0.0", - "bundled": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "util-extend": { - "version": "1.0.3", - "bundled": true - }, - "uuid": { - "version": "3.3.2", - "bundled": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "bundled": true, - "requires": { - "builtins": "^1.0.3" - } - }, - "verror": { - "version": "1.10.0", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "1.3.1", - "bundled": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "requires": { - "string-width": "^1.0.2" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "widest-line": { - "version": "2.0.0", - "bundled": true, - "requires": { - "string-width": "^2.1.1" - } - }, - "worker-farm": { - "version": "1.6.0", - "bundled": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "write-file-atomic": { - "version": "2.3.0", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "xdg-basedir": { - "version": "3.0.0", - "bundled": true - }, - "xtend": { - "version": "4.0.1", - "bundled": true - }, - "y18n": { - "version": "4.0.0", - "bundled": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true - }, - "yargs": { - "version": "11.0.0", - "bundled": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "y18n": { - "version": "3.2.1", - "bundled": true - } - } - }, - "yargs-parser": { - "version": "9.0.2", - "bundled": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -13309,7 +10618,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "optional": true, @@ -13323,7 +10632,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "optional": true, "requires": { @@ -13340,7 +10649,7 @@ "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "dev": true, "optional": true, "requires": { @@ -13355,7 +10664,7 @@ "pac-resolver": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha1-auoweH2wqJFwTet4AKcip2FabyY=", + "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", "dev": true, "optional": true, "requires": { @@ -13566,7 +10875,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -13683,7 +10992,7 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "posix-character-classes": { @@ -13706,7 +11015,7 @@ }, "postcss-calc": { "version": "5.3.1", - "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", "dev": true, "requires": { @@ -13738,7 +11047,7 @@ }, "postcss-discard-comments": { "version": "2.0.4", - "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "dev": true, "requires": { @@ -13756,7 +11065,7 @@ }, "postcss-discard-empty": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "dev": true, "requires": { @@ -13765,7 +11074,7 @@ }, "postcss-discard-overridden": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "dev": true, "requires": { @@ -13774,7 +11083,7 @@ }, "postcss-discard-unused": { "version": "2.2.3", - "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", "dev": true, "requires": { @@ -13825,7 +11134,7 @@ }, "postcss-merge-idents": { "version": "2.1.7", - "resolved": "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", "dev": true, "requires": { @@ -13864,7 +11173,7 @@ }, "postcss-minify-font-values": { "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", "dev": true, "requires": { @@ -13875,7 +11184,7 @@ }, "postcss-minify-gradients": { "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "dev": true, "requires": { @@ -13885,7 +11194,7 @@ }, "postcss-minify-params": { "version": "1.2.2", - "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", "dev": true, "requires": { @@ -13897,7 +11206,7 @@ }, "postcss-minify-selectors": { "version": "2.1.1", - "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", "dev": true, "requires": { @@ -13909,7 +11218,7 @@ }, "postcss-normalize-charset": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "dev": true, "requires": { @@ -13918,7 +11227,7 @@ }, "postcss-normalize-url": { "version": "3.0.8", - "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", "dev": true, "requires": { @@ -13940,7 +11249,7 @@ }, "postcss-reduce-idents": { "version": "2.4.0", - "resolved": "http://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", "dev": true, "requires": { @@ -13950,7 +11259,7 @@ }, "postcss-reduce-initial": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "dev": true, "requires": { @@ -13959,7 +11268,7 @@ }, "postcss-reduce-transforms": { "version": "1.0.4", - "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", "dev": true, "requires": { @@ -13981,7 +11290,7 @@ }, "postcss-svgo": { "version": "2.1.6", - "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", "dev": true, "requires": { @@ -13993,7 +11302,7 @@ }, "postcss-unique-selectors": { "version": "2.0.2", - "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", "dev": true, "requires": { @@ -14010,7 +11319,7 @@ }, "postcss-zindex": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", "dev": true, "requires": { @@ -14117,7 +11426,7 @@ "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", "dev": true, "optional": true, "requires": { @@ -14170,7 +11479,7 @@ "qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "dev": true }, "qs": { @@ -14239,7 +11548,7 @@ }, "iconv-lite": { "version": "0.4.13", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", "dev": true } @@ -14330,7 +11639,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -14381,7 +11690,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -14411,7 +11720,7 @@ "redis": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha1-ICKI4/WMSfYHnZevehDhMDrhSwI=", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", "dev": true, "optional": true, "requires": { @@ -14423,7 +11732,7 @@ "redis-commands": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", - "integrity": "sha1-RJWIlBTx6IYmEYCxRC5ylWAtg6I=", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", "dev": true, "optional": true }, @@ -14436,7 +11745,7 @@ }, "reduce-css-calc": { "version": "1.3.0", - "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", "dev": true, "requires": { @@ -14516,7 +11825,7 @@ "regexpp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz", - "integrity": "sha1-sqdTSoXKGwM7z1zp/45W1OB1U2U=", + "integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==", "dev": true }, "regexpu-core": { @@ -14648,7 +11957,7 @@ "requestretry": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha1-IT7BAG7rdQ6LjOVBdig9FajVXZQ=", + "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", "dev": true, "optional": true, "requires": { @@ -14868,7 +12177,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "sax": { @@ -14945,7 +12254,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -15015,7 +12324,7 @@ "dependencies": { "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -15073,7 +12382,7 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, "shebang-command": { @@ -15130,7 +12439,7 @@ "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" @@ -15311,7 +12620,7 @@ "socket.io-parser": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha1-7S2l7nnxCVUDbj2kE7/X8eTYbI4=", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -15323,7 +12632,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -15350,7 +12659,7 @@ "socks-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", - "integrity": "sha1-WTa/i3B6mTB5xvN9sgkYIb/6ZHM=", + "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", "dev": true, "requires": { "agent-base": "~4.2.0", @@ -15615,7 +12924,7 @@ "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha1-odG3z4PTmvsNYwSaWsv5NJO99ks=", + "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { "date-format": "^1.2.0", @@ -15647,7 +12956,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -15663,7 +12972,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -15680,7 +12989,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -15718,7 +13027,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -15867,7 +13176,7 @@ }, "table": { "version": "4.0.3", - "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { @@ -16004,7 +13313,7 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -16157,7 +13466,7 @@ }, "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -16172,7 +13481,7 @@ }, "iconv-lite": { "version": "0.4.13", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", "dev": true }, @@ -16198,7 +13507,7 @@ "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -16413,7 +13722,7 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", "dev": true }, "unc-path-regex": { @@ -16576,13 +13885,13 @@ "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha1-NSVll+RqWB20eT0M5H+prr/J+r0=", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", "dev": true }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -16675,7 +13984,7 @@ "uws": { "version": "9.14.0", "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha1-+sg4a+/DOno3BcvVjcR7Qwyk3ZU=", + "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", "dev": true, "optional": true }, @@ -16918,7 +14227,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -17057,7 +14366,7 @@ "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { "async-limiter": "~1.0.0", @@ -17093,7 +14402,7 @@ }, "yargs": { "version": "3.10.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html index 4d9b332fcb..3a445b1a85 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html @@ -41,11 +41,11 @@

- +
From faec132f8201d4dfedce4896ccff93d5d2efa4f6 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 10:28:36 +0200 Subject: [PATCH 019/337] TEMP - removes inline mode adds stub code to have a fixed toolbar dom item --- .../src/common/services/tinymce.service.js | 3 ++- src/Umbraco.Web.UI.Client/src/less/rte.less | 3 +++ .../src/views/propertyeditors/rte/rte.html | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 266b50fdcb..246d5c297a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -186,9 +186,10 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //create a baseline Config to exten upon var config = { + //fixed_toolbar_container: "#blah", selector: "#" + args.htmlId, theme: args.theme ? args.theme : "modern", - inline: true, + //inline: true, plugins: plugins, valid_elements: tinyMceConfig.validElements, invalid_elements: tinyMceConfig.inValidElements, diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index e0296f63c0..a6d1779a5e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -35,6 +35,9 @@ background-position-x: 99%; } +.umb-rte .mce-container { + white-space: inherit; +} /* This used to be in place but I'm not sure its needed ... */ diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html index c3add7694a..3aa342b1ce 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.html @@ -2,6 +2,8 @@
Loading...
+
+
From 93075a82dee38b705538127fa5ce06e7a96ab673 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 10:42:11 +0200 Subject: [PATCH 020/337] menu now wraps in classic mode --- src/Umbraco.Web.UI.Client/src/less/rte.less | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index a6d1779a5e..4fdc8e9629 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -36,18 +36,21 @@ } .umb-rte .mce-container { - white-space: inherit; + box-sizing: border-box; } -/* This used to be in place but I'm not sure its needed ... */ - -/* TINYMCE IMAGE RESIZING LIMITS */ -/*#mceResizeHandlen, #mceResizeHandles, #mceResizeHandlee, #mceResizeHandlew { +/* make sure the menu wraps */ +.umb-rte .mce-top-part.mce-container div { + white-space: normal; +} + + /* This used to be in place but I'm not sure its needed ... */ + /* TINYMCE IMAGE RESIZING LIMITS */ + /*#mceResizeHandlen, #mceResizeHandles, #mceResizeHandlee, #mceResizeHandlew { display: none !important; visibility: hidden !important; }*/ - -/*body.mce-content-body { + /*body.mce-content-body { background: transparent !important; overflow-x: hidden !important; padding-bottom: 10px !important; From ffc0ec45561a23acf158d5b0dd1d7216d564bdb0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 12 Oct 2018 10:51:43 +0200 Subject: [PATCH 021/337] removes dimensions pre-values from rte --- .../src/common/services/tinymce.service.js | 5 +---- src/Umbraco.Web.UI.Client/src/less/rte.less | 2 +- .../src/views/propertyeditors/rte/rte.controller.js | 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 246d5c297a..b6448231fc 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -189,7 +189,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //fixed_toolbar_container: "#blah", selector: "#" + args.htmlId, theme: args.theme ? args.theme : "modern", - //inline: true, + inline: true, plugins: plugins, valid_elements: tinyMceConfig.validElements, invalid_elements: tinyMceConfig.inValidElements, @@ -288,9 +288,6 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh var cfg = {}; cfg.toolbar = ["code", "bold", "italic", "styleselect", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "outdent", "indent", "link", "image", "umbmediapicker", "umbembeddialog", "umbmacro"]; cfg.stylesheets = []; - cfg.dimensions = { - height: 500 - }; cfg.maxImageSize = 500; return cfg; }, diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index 4fdc8e9629..0dd8a0573e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -11,7 +11,7 @@ } .umb-rte .mce-content-body { - padding:10px; + padding: 10px; background-color: #fff; font-size: 14px; line-height: 1.5em; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index c10fd989e8..355e765f5c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -85,8 +85,6 @@ angular.module("umbraco") //create a baseline Config to exten upon var baseLineConfigObj = { - height: editorConfig.dimensions.height, - width: editorConfig.dimensions.width, maxImageSize: editorConfig.maxImageSize }; From 1cb4df2750ab222cfd57289e0ae3ce2fa83e61fb Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 12:29:34 +0100 Subject: [PATCH 022/337] WIP Ace editor for the HTML source code --- .../src/common/services/tinymce.service.js | 15 +++++ .../rte/codeeditor.controller.js | 65 +++++++++++++++++++ .../views/propertyeditors/rte/codeeditor.html | 41 ++++++++++++ .../propertyeditors/rte/rte.controller.js | 28 ++++++++ .../config/tinyMceConfig.Release.config | 1 + .../config/tinyMceConfig.config | 1 + 6 files changed, 151 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.html diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 246d5c297a..07ad0f9c6d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -324,6 +324,21 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh editor.insertContent(preview); }, + + createAceCodeEditor: function(editor, $scope, callback){ + + editor.addButton("ace", { + icon: "code", + text: "Code WARREN", + title: "Code WARREN", + tooltip: "Code WARREN", + onclick: function(){ + callback(); + } + }); + + }, + /** * @ngdoc method * @name umbraco.services.tinyMceService#createMediaPicker diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js new file mode 100644 index 0000000000..4c22913774 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js @@ -0,0 +1,65 @@ +(function () { + "use strict"; + + function CodeEditorController($scope, localizationService) { + + var vm = this; + vm.loading = false; + + vm.submit = submit; + vm.close = close; + + vm.aceOption = {}; + vm.aceOption = { + mode: "razor", + theme: "chrome", + showPrintMargin: false, + advanced: { + fontSize: '14px', + enableSnippets: false, //The Razor mode snippets are awful (Need a way to override these) + enableBasicAutocompletion: true, + enableLiveAutocompletion: false + } + } + + vm.template = {}; + vm.template.content = $scope.model.content; + + ////////// + + function onInit() { + + vm.loading = true; + + // set default title + if(!$scope.model.title) { + // TODO change to a new key to get 'source code' or similar + localizationService.localize("defaultdialogs_selectUsers").then(function(value){ + $scope.model.title = value; + }); + } + + //GO + + + } + + function submit(model) { + if($scope.model.submit) { + $scope.model.submit(model); + } + } + + function close() { + if($scope.model.close) { + $scope.model.close(); + } + } + + onInit(); + + } + + angular.module("umbraco").controller("Umbraco.PropertyEditors.RTECodeEditorController", CodeEditorController); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.html new file mode 100644 index 0000000000..11d77d4dd4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.html @@ -0,0 +1,41 @@ +
+ + + + + + + +
+
+
+ + + + + + + + + + +
+ +
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index c10fd989e8..c6ddf350e9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -191,6 +191,34 @@ angular.module("umbraco") editorService.macroPicker(macroPicker); }); + tinyMceService.createAceCodeEditor(tinyMceEditor, $scope, function () { + + //TODO: CHECK TO SEE WHAT WE NEED TO DO WIT MACROS (See code block?) + /* + var html = editor.getContent({source_view: true}); + html = html.replace(/]*)>([^<]*)<\/span>/gm, String.fromCharCode(chr)); + editor.dom.remove(editor.dom.select('.CmCaReT')); + html = html.replace(/(
*)[\s\S]*?(<\/ins> *<\/div>)/ig, "$1Macro alias: $2$3"); + */ + + var aceEditor = { + content: tinyMceEditor.getContent(), + view: 'views/propertyeditors/rte/codeeditor.html', + size: 'small', + submit: function (model) { + console.log('HTML update', model.content); + + tinyMceEditor.setContent(model.content); + editorService.close(); + }, + close: function () { + editorService.close(); + } + }; + + editorService.open(aceEditor); + }); + startWatch(editor); }; diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config index 649be9723f..8243ddfcc0 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config @@ -3,6 +3,7 @@ + diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.config b/src/Umbraco.Web.UI/config/tinyMceConfig.config index 649be9723f..8243ddfcc0 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.config @@ -3,6 +3,7 @@ + From e805305352d8d32336c49b1e59c2b0fe098d82ad Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 12 Oct 2018 13:55:57 +0200 Subject: [PATCH 023/337] refresh model on save --- .../src/views/propertyeditors/rte/codeeditor.controller.js | 7 +++++++ .../src/views/propertyeditors/rte/rte.controller.js | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js index 4c22913774..f799dce03a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js @@ -19,6 +19,9 @@ enableSnippets: false, //The Razor mode snippets are awful (Need a way to override these) enableBasicAutocompletion: true, enableLiveAutocompletion: false + }, + onLoad: function(aceEditor) { + vm.aceEditor = aceEditor; } } @@ -45,6 +48,10 @@ } function submit(model) { + + // refresh the model + model.content = vm.aceEditor.getValue(); + if($scope.model.submit) { $scope.model.submit(model); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 37080378a7..66df2a787b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -205,7 +205,7 @@ angular.module("umbraco") size: 'small', submit: function (model) { console.log('HTML update', model.content); - + console.log(tinyMceEditor); tinyMceEditor.setContent(model.content); editorService.close(); }, From 6a4e9f5368d73fe3bcf9b0ba232e02e0384e2edd Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 13:59:39 +0100 Subject: [PATCH 024/337] Bye bye codemirror TinyMce Wrapper Plugin --- .../tinymce/plugins/codemirror/langs/da.js | 8 - .../tinymce/plugins/codemirror/langs/de.js | 8 - .../tinymce/plugins/codemirror/langs/en.js | 8 - .../tinymce/plugins/codemirror/langs/en_us.js | 8 - .../tinymce/plugins/codemirror/langs/fi.js | 8 - .../tinymce/plugins/codemirror/langs/fr.js | 8 - .../tinymce/plugins/codemirror/langs/he.js | 8 - .../tinymce/plugins/codemirror/langs/it.js | 8 - .../tinymce/plugins/codemirror/langs/ja.js | 8 - .../tinymce/plugins/codemirror/langs/nl.js | 8 - .../tinymce/plugins/codemirror/langs/no.js | 8 - .../tinymce/plugins/codemirror/langs/pl.js | 8 - .../tinymce/plugins/codemirror/langs/pt.js | 8 - .../tinymce/plugins/codemirror/langs/ru.js | 8 - .../tinymce/plugins/codemirror/langs/sv.js | 8 - .../tinymce/plugins/codemirror/langs/zh.js | 8 - .../tinymce/plugins/codemirror/plugin.min.js | 24 -- .../tinymce/plugins/codemirror/source.html | 255 ------------------ 18 files changed, 407 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/da.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/de.js delete mode 100755 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en_us.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fi.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fr.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/he.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/it.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ja.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/nl.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/no.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pl.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pt.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ru.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/sv.js delete mode 100644 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/zh.js delete mode 100755 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/plugin.min.js delete mode 100755 src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/source.html diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/da.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/da.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/da.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/de.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/de.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/de.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en.js deleted file mode 100755 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en_us.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en_us.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/en_us.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fi.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fi.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fi.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fr.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fr.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/fr.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/he.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/he.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/he.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/it.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/it.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/it.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ja.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ja.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ja.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/nl.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/nl.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/nl.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/no.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/no.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/no.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pl.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pl.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pl.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pt.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pt.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/pt.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ru.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ru.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/ru.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/sv.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/sv.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/sv.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/zh.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/zh.js deleted file mode 100644 index d5e0bbde43..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/langs/zh.js +++ /dev/null @@ -1,8 +0,0 @@ -tinymce.addI18n('en',{ - 'HTML source code': 'HTML source code', - 'Start search': 'Start search', - 'Find next': 'Find next', - 'Find previous': 'Find previous', - 'Replace': 'Replace', - 'Replace all': 'Replace all' -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/plugin.min.js b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/plugin.min.js deleted file mode 100755 index 43938f52c9..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/plugin.min.js +++ /dev/null @@ -1,24 +0,0 @@ -tinymce.PluginManager.requireLangPack("codemirror"); -tinymce.PluginManager.add("codemirror", function(a, c) { - function b() { - a.focus(); - a.selection.collapse(!0); - a.selection.setContent(''); - var b = a.windowManager.open({ - title: "Source code", url: c + "/source.html", width: a.getParam("code_dialog_width", 600), height: a.getParam("code_dialog_height", Math.min(tinymce.DOM.getViewPort().h - 200, 500)), resizable: !0, maximizable: !0, - buttons: [ - { - text: "Ok", subtype: "primary", - onclick: function() { - document.querySelectorAll(".mce-container-body>iframe")[0].contentWindow.submit(); - b.close() - } - }, { text: "Cancel", onclick: "close" } - ] - }) - } - - a.addButton("codemirror", - { title: "Source code", icon: "code", onclick: b }); - a.addMenuItem("codemirror", { icon: "code", text: "Source code", context: "tools", onclick: b }) -}); diff --git a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/source.html b/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/source.html deleted file mode 100755 index 70cecb77e0..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/tinymce/plugins/codemirror/source.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - From 9dcabd24d243bee52bb5d2f266aea56f09e938bc Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 14:00:15 +0100 Subject: [PATCH 025/337] Cleanup of console.log, remove unused code and name button better than 'Warrens button' --- .../src/common/services/tinymce.service.js | 26 +++++++++---------- .../rte/codeeditor.controller.js | 11 +------- .../propertyeditors/rte/rte.controller.js | 2 -- .../config/tinyMceConfig.Release.config | 3 +-- .../config/tinyMceConfig.config | 3 +-- 5 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 79623de215..f80f80ebf7 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -2,7 +2,7 @@ * @ngdoc service * @name umbraco.services.tinyMceService * - * + * * @description * A service containing all logic for all of the Umbraco TinyMCE plugins */ @@ -160,7 +160,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh /** * Returns a promise of the configuration object to initialize the TinyMCE editor * @param {} args - * @returns {} + * @returns {} */ getTinyMceEditorConfig: function (args) { @@ -252,7 +252,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh return $q.when(config); }); - + }, /** @@ -300,7 +300,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh * @description * Creates the umbrco insert embedded media tinymce plugin * - * @param {Object} editor the TinyMCE editor instance + * @param {Object} editor the TinyMCE editor instance * @param {Object} $scope the current controller scope */ createInsertEmbeddedMedia: function (editor, $scope, callback) { @@ -326,9 +326,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh editor.addButton("ace", { icon: "code", - text: "Code WARREN", - title: "Code WARREN", - tooltip: "Code WARREN", + tooltip: "View Source Code", onclick: function(){ callback(); } @@ -344,7 +342,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh * @description * Creates the umbrco insert media tinymce plugin * - * @param {Object} editor the TinyMCE editor instance + * @param {Object} editor the TinyMCE editor instance * @param {Object} $scope the current controller scope */ createMediaPicker: function (editor, $scope, callback) { @@ -436,7 +434,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh * @description * Creates the insert umbrco macro tinymce plugin * - * @param {Object} editor the TinyMCE editor instance + * @param {Object} editor the TinyMCE editor instance * @param {Object} $scope the current controller scope */ createInsertMacro: function (editor, $scope, callback) { @@ -460,7 +458,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh }); /** - * Because the macro gets wrapped in a P tag because of the way 'enter' works, this + * Because the macro gets wrapped in a P tag because of the way 'enter' works, this * method will return the macro element if not wrapped in a p, or the p if the macro * element is the only one inside of it even if we are deep inside an element inside the macro */ @@ -468,7 +466,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh var e = $(element).closest(".umb-macro-holder"); if (e.length > 0) { if (e.get(0).parentNode.nodeName === "P") { - //now check if we're the only element + //now check if we're the only element if (element.parentNode.childNodes.length === 1) { return e.get(0).parentNode; } @@ -502,7 +500,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //if the end selection is a macro then move the cursor //NOTE: we don't have to handle when the selection comes from a previous parent because - // that is automatically taken care of with the normal onNodeChanged logic since the + // that is automatically taken care of with the normal onNodeChanged logic since the // evt.element will be the macro once it becomes part of the selection. var $testForMacro = $(endSelection).closest(".umb-macro-holder"); if ($testForMacro.length > 0) { @@ -622,7 +620,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh //set onNodeChanged event listener editor.on('NodeChange', onNodeChanged); - /** + /** * Listen for the keydown in the editor, we'll check if we are currently on a macro element, if so * we'll check if the key down is a supported key which requires an action, otherwise we ignore the request * so the macro cannot be edited. @@ -1035,7 +1033,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh * From the given string, generates a string array where each item is the id attribute value from a named anchor * 'some string with a named anchor' returns ['anchor'] * - * @param {string} input the string to parse + * @param {string} input the string to parse */ getAnchorNames: function (input) { var anchors = []; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js index f799dce03a..97f00023bb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js @@ -4,8 +4,6 @@ function CodeEditorController($scope, localizationService) { var vm = this; - vm.loading = false; - vm.submit = submit; vm.close = close; @@ -15,7 +13,7 @@ theme: "chrome", showPrintMargin: false, advanced: { - fontSize: '14px', + fontSize: "14px", enableSnippets: false, //The Razor mode snippets are awful (Need a way to override these) enableBasicAutocompletion: true, enableLiveAutocompletion: false @@ -32,8 +30,6 @@ function onInit() { - vm.loading = true; - // set default title if(!$scope.model.title) { // TODO change to a new key to get 'source code' or similar @@ -41,10 +37,6 @@ $scope.model.title = value; }); } - - //GO - - } function submit(model) { @@ -64,7 +56,6 @@ } onInit(); - } angular.module("umbraco").controller("Umbraco.PropertyEditors.RTECodeEditorController", CodeEditorController); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 66df2a787b..758f138d4a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -204,8 +204,6 @@ angular.module("umbraco") view: 'views/propertyeditors/rte/codeeditor.html', size: 'small', submit: function (model) { - console.log('HTML update', model.content); - console.log(tinyMceEditor); tinyMceEditor.setContent(model.content); editorService.close(); }, diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config index 8243ddfcc0..dafbbe8bb5 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config @@ -2,8 +2,7 @@ - - + diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.config b/src/Umbraco.Web.UI/config/tinyMceConfig.config index 8243ddfcc0..dafbbe8bb5 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.config @@ -2,8 +2,7 @@ - - + From 66d4541fc5d6b9fff909f3b80fcbd0a41d745493 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 14:20:21 +0100 Subject: [PATCH 026/337] Remove codemirror files --- src/Umbraco.Web.UI.Client/gulpfile.js | 18 - .../lib/codemirror/mode/razor/LICENSE | 22 - .../lib/codemirror/mode/razor/index.html | 727 ------------------ .../lib/codemirror/mode/razor/razor.js | 254 ------ src/Umbraco.Web.UI.Client/package.json | 1 - 5 files changed, 1022 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/LICENSE delete mode 100644 src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/index.html delete mode 100644 src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/razor.js diff --git a/src/Umbraco.Web.UI.Client/gulpfile.js b/src/Umbraco.Web.UI.Client/gulpfile.js index 9bfb0af875..f614f24b53 100644 --- a/src/Umbraco.Web.UI.Client/gulpfile.js +++ b/src/Umbraco.Web.UI.Client/gulpfile.js @@ -249,24 +249,6 @@ gulp.task('dependencies', function () { "src": ["./node_modules/clipboard/dist/clipboard.min.js"], "base": "./node_modules/clipboard/dist" }, - { - "name": "codemirror", - "src": [ - "./node_modules/codemirror/lib/codemirror.js", - "./node_modules/codemirror/lib/codemirror.css", - - "./node_modules/codemirror/mode/css/css.js", - "./node_modules/codemirror/mode/javascript/javascript.js", - "./node_modules/codemirror/mode/xml/xml.js", - "./node_modules/codemirror/mode/htmlmixed/htmlmixed.js", - - "./node_modules/codemirror/addon/search/*", - "./node_modules/codemirror/addon/edit/*", - "./node_modules/codemirror/addon/selection/*", - "./node_modules/codemirror/addon/dialog/*" - ], - "base": "./node_modules/codemirror" - }, { "name": "jsdiff", "src": ["./node_modules/diff/dist/diff.min.js"], diff --git a/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/LICENSE b/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/LICENSE deleted file mode 100644 index 977e284e0f..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License - -Copyright (c) 2011 Jeff Pickhardt -Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/index.html b/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/index.html deleted file mode 100644 index 6e2b71d7a6..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/index.html +++ /dev/null @@ -1,727 +0,0 @@ - - - - CodeMirror: Razor mode - - - - - - - -

CodeMirror: Razor mode

-
- - -

MIME types defined: text/x-coffeescript.

- -

The CoffeeScript mode was written by Jeff Pickhardt (license).

- - - diff --git a/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/razor.js b/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/razor.js deleted file mode 100644 index 3907b97dd9..0000000000 --- a/src/Umbraco.Web.UI.Client/lib/codemirror/mode/razor/razor.js +++ /dev/null @@ -1,254 +0,0 @@ -CodeMirror.defineMode("razor", function(config, parserConfig) { - var indentUnit = config.indentUnit, - keywords = words("abstract as base break case catch checked class const continue" + - " default delegate do else enum event explicit extern finally fixed for" + - " foreach goto if implicit in interface internal is lock namespace new" + - " operator out override params private protected public readonly ref return sealed" + - " sizeof stackalloc static struct switch this throw try typeof unchecked" + - " unsafe using virtual void volatile while add alias ascending descending dynamic from get" + - " global group into join let orderby partial remove select set value var yield"), - - builtin = words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" + - " Guid Int16 Int32 Int64 Library Model Object SByte Single String TimeSpan UInt16 UInt32" + - " UInt64 bool byte char decimal double short int long object" + - " sbyte float string ushort uint ulong"), - blockKeywords = words("catch class do else finally for foreach if struct switch try while"), - atoms = words("true false null"), - hooks = parserConfig.hooks || {}, - multiLineStrings = parserConfig.multiLineStrings; - var isOperatorChar = /[+\-*&%=<>!?|\/]/; - - var curPunc; - - function tokenBase(stream, state) { - var ch = stream.next(); - if (hooks[ch]) { - var result = hooks[ch](stream, state); - if (result !== false) return result; - } - if (ch == '"' || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } - if (/[\[\]{}\(\),;\:\.]/.test(ch)) { - curPunc = ch; - return null; - } - if (/\d/.test(ch)) { - stream.eatWhile(/[\w\.]/); - return "number"; - } - if (ch == "@") { - if (stream.eat("*")) { - state.tokenize = tokenComment; - return tokenComment(stream, state); - } - if (stream.eat("/")) { - stream.skipToEnd(); - return "comment"; - } - - return "at"; - } - - if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return "operator"; - } - stream.eatWhile(/[\w\$_]/); - var cur = stream.current(); - if (keywords.propertyIsEnumerable(cur)) { - if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; - return "keyword"; - } - if (builtin.propertyIsEnumerable(cur)) { - if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement"; - return "builtin"; - } - if (atoms.propertyIsEnumerable(cur)) return "atom"; - return "variable"; - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next, end = false; - while ((next = stream.next()) != null) { - if (next == quote && !escaped) {end = true; break;} - escaped = !escaped && next == "\\"; - } - if (end || !(escaped || multiLineStrings)) - state.tokenize = null; - return "string"; - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "@" && maybeEnd) { - state.tokenize = null; - break; - } - maybeEnd = (ch == "*"); - } - return "comment"; - } - - function Context(indented, column, type, align, prev) { - this.indented = indented; - this.column = column; - this.type = type; - this.align = align; - this.prev = prev; - } - function pushContext(state, col, type) { - return state.context = new Context(state.indented, col, type, null, state.context); - } - function popContext(state) { - var t = state.context.type; - if (t == ")" || t == "]" || t == "}") - state.indented = state.context.indented; - return state.context = state.context.prev; - } - - function words(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: null, - context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), - indented: 0, - startOfLine: true - }; - }, - - token: function(stream, state) { - var ctx = state.context; - if (stream.sol()) { - if (ctx.align == null) ctx.align = false; - state.indented = stream.indentation(); - state.startOfLine = true; - } - if (stream.eatSpace()) return null; - curPunc = null; - var style = (state.tokenize || tokenBase)(stream, state); - if (style == "comment" || style == "meta") return style; - if (ctx.align == null) ctx.align = true; - - if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state); - else if (curPunc == "{") pushContext(state, stream.column(), "}"); - else if (curPunc == "[") pushContext(state, stream.column(), "]"); - else if (curPunc == "(") pushContext(state, stream.column(), ")"); - else if (curPunc == "}") { - while (ctx.type == "statement") ctx = popContext(state); - if (ctx.type == "}") ctx = popContext(state); - while (ctx.type == "statement") ctx = popContext(state); - } - else if (curPunc == ctx.type) popContext(state); - else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement")) - pushContext(state, stream.column(), "statement"); - state.startOfLine = false; - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize != tokenBase && state.tokenize != null) return 0; - var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); - if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; - var closing = firstChar == ctx.type; - if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit); - else if (ctx.align) return ctx.column + (closing ? 0 : 1); - else return ctx.indented + (closing ? 0 : indentUnit); - }, - - electricChars: "{}" - }; -}); - -(function() { - function words(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - var cKeywords = "auto if break int case long char register continue return default short do sizeof " + - "double static else struct entry switch extern typedef float union for unsigned " + - "goto while enum void const signed volatile"; - - function cppHook(stream, state) { - if (!state.startOfLine) return false; - stream.skipToEnd(); - return "meta"; - } - - // C#-style strings where "" escapes a quote. - function tokenAtString(stream, state) { - var next; - while ((next = stream.next()) != null) { - if (next == '"' && !stream.eat('"')) { - state.tokenize = null; - break; - } - } - return "string"; - } - - function mimes(ms, mode) { - for (var i = 0; i < ms.length; ++i) CodeMirror.defineMIME(ms[i], mode); - } - -/* - mimes(["text/x-csrc", "text/x-c", "text/x-chdr"], { - name: "clike", - keywords: words(cKeywords), - blockKeywords: words("case do else for if switch while struct"), - atoms: words("null"), - hooks: {"#": cppHook} - }); - - mimes(["text/x-c++src", "text/x-c++hdr"], { - name: "clike", - keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " + - "static_cast typeid catch operator template typename class friend private " + - "this using const_cast inline public throw virtual delete mutable protected " + - "wchar_t"), - blockKeywords: words("catch class do else finally for if struct switch try while"), - atoms: words("true false null"), - hooks: {"#": cppHook} - });*/ - - CodeMirror.defineMIME("text/x-razor", { - name: "razor", - keywords: words("abstract as base break case catch checked class const continue" + - " default delegate do else enum event explicit extern finally fixed for" + - " foreach goto if implicit in interface internal is lock namespace new" + - " operator out override params private protected public readonly ref return sealed" + - " sizeof stackalloc static struct switch this throw try typeof unchecked" + - " unsafe using virtual void volatile while add alias ascending descending dynamic from get" + - " global group into join let orderby partial remove select set value var yield"), - blockKeywords: words("catch class do else finally for foreach if struct switch try while"), - builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" + - " Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" + - " UInt64 bool byte char decimal double short int long object" + - " sbyte float string ushort uint ulong"), - atoms: words("true false null"), - hooks: { - "@": function(stream, state) { - if (stream.eat('"')) { - state.tokenize = tokenAtString; - return tokenAtString(stream, state); - } - stream.eatWhile(/[\w\$_]/); - return "meta"; - } - } - }); - -}()); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 02fa88cfbc..974a0b017e 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -21,7 +21,6 @@ "animejs": "2.2.0", "bootstrap-social": "4.8.0", "clipboard": "2.0.0", - "codemirror": "5.3.0", "diff": "3.4.0", "flatpickr": "4.5.2", "font-awesome": "4.2.0", From 9495feb94d87aa6b3f5f23beef722901c51c6e7b Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 14:21:08 +0100 Subject: [PATCH 027/337] Updates the tinymce plugin alias to use the code icon for when configuring which toolbar buttons to add in the prevalue editor view --- .../views/propertyeditors/rte/rte.prevalues.controller.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js index 2ffc40db68..4ca1bbc3f9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js @@ -59,7 +59,7 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", }; $scope.selectStylesheet = function (css) { - + var index = $scope.model.value.stylesheets.indexOf(css.name); if(css.selected && index === -1){ @@ -68,13 +68,13 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", $scope.model.value.stylesheets.splice(index, 1); } }; - + // map properties for specific commands function getFontIcon(alias) { var icon = { name: alias, isCustom: false }; switch (alias) { - case "codemirror": + case "ace": icon.name = "code"; icon.isCustom = false; break; @@ -111,7 +111,7 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", var commands = _.where($scope.tinyMceConfig.commands, {selected: true}); $scope.model.value.toolbar = _.pluck(commands, "alias"); - + }); // when the scope is destroyed we need to unsubscribe From 996c48cc7fcadd6c1c11405c6f3f4071d725b671 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 14:35:47 +0100 Subject: [PATCH 028/337] Package lock without codemirror --- src/Umbraco.Web.UI.Client/package-lock.json | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 2d6c56ffba..5441f259e1 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -2365,11 +2365,6 @@ "q": "^1.1.2" } }, - "codemirror": { - "version": "5.3.0", - "resolved": "http://registry.npmjs.org/codemirror/-/codemirror-5.3.0.tgz", - "integrity": "sha1-JDyyaN1hynjdsn6C8uws74j7lGE=" - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -5485,12 +5480,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5511,7 +5508,8 @@ "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", @@ -5662,6 +5660,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5669,12 +5668,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -5693,6 +5694,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5786,6 +5788,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5907,6 +5910,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", From 69d1fea8f76b41fd41e773ddc717f3b688e2d51b Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 14:36:57 +0100 Subject: [PATCH 029/337] Thought I updated these already?! --- src/Umbraco.Web.UI/Umbraco/Install/Views/Index.cshtml | 2 +- src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml | 2 +- src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco/Install/Views/Index.cshtml b/src/Umbraco.Web.UI/Umbraco/Install/Views/Index.cshtml index 67adeaf84a..79968939ec 100644 --- a/src/Umbraco.Web.UI/Umbraco/Install/Views/Index.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Install/Views/Index.cshtml @@ -70,7 +70,7 @@ "umbracoBaseUrl": "@ViewBag.UmbracoBaseFolder" }; - + diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 549954bfc1..3c79d5458c 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -72,7 +72,7 @@ @*And finally we can load in our angular app*@ - + diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml index 4924985689..38b178fcfa 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml @@ -54,7 +54,7 @@
- + From cb0b1ef73d632883b171316ae03173d5512b469f Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Fri, 12 Oct 2018 14:47:23 +0100 Subject: [PATCH 030/337] More CodeMirror stuff gone --- .../config/tinyMceConfig.Release.config | 14 -------------- src/Umbraco.Web.UI/config/tinyMceConfig.config | 16 +--------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config index dafbbe8bb5..3501714977 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config @@ -38,7 +38,6 @@ code - codemirror paste anchor charmap @@ -71,18 +70,5 @@ param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|cla raw - - - - diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.config b/src/Umbraco.Web.UI/config/tinyMceConfig.config index dafbbe8bb5..386c081333 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.config @@ -38,7 +38,6 @@ code - codemirror paste anchor charmap @@ -70,19 +69,6 @@ param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|cla - raw - - - - + raw From 9c5a30f36c2b9f6027af60f65d81ba2abc579b9b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 15 Oct 2018 13:00:35 +0200 Subject: [PATCH 031/337] remove build in source code editor from tinymce --- src/Umbraco.Web.UI/config/tinyMceConfig.Release.config | 4 +--- src/Umbraco.Web.UI/config/tinyMceConfig.config | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config index 3501714977..40630b7eb6 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.Release.config @@ -1,8 +1,7 @@  - - + @@ -37,7 +36,6 @@ - code paste anchor charmap diff --git a/src/Umbraco.Web.UI/config/tinyMceConfig.config b/src/Umbraco.Web.UI/config/tinyMceConfig.config index 386c081333..d01c0ca7aa 100644 --- a/src/Umbraco.Web.UI/config/tinyMceConfig.config +++ b/src/Umbraco.Web.UI/config/tinyMceConfig.config @@ -1,8 +1,7 @@  - - + @@ -37,7 +36,6 @@ - code paste anchor charmap From 30436eb72d320cc9adbd6b9567abcec5c410e8eb Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 15 Oct 2018 13:19:00 +0200 Subject: [PATCH 032/337] fix styles --- src/Umbraco.Web.UI.Client/src/less/rte.less | 27 +++------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index 0dd8a0573e..d0b0ef4fae 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -10,7 +10,7 @@ min-height:25px; } -.umb-rte .mce-content-body { +.umb-rte.mce-content-body { padding: 10px; background-color: #fff; font-size: 14px; @@ -26,7 +26,7 @@ } /* loader for macro loading in tinymce*/ -.umb-rte .mce-content-body .umb-macro-holder.loading { +.umb-rte.mce-content-body .umb-macro-holder.loading { background: url(img/loader.gif) right no-repeat; -moz-background-size: 18px; -o-background-size: 18px; @@ -42,25 +42,4 @@ /* make sure the menu wraps */ .umb-rte .mce-top-part.mce-container div { white-space: normal; -} - - /* This used to be in place but I'm not sure its needed ... */ - /* TINYMCE IMAGE RESIZING LIMITS */ - /*#mceResizeHandlen, #mceResizeHandles, #mceResizeHandlee, #mceResizeHandlew { - display: none !important; - visibility: hidden !important; -}*/ - /*body.mce-content-body { - background: transparent !important; - overflow-x: hidden !important; - padding-bottom: 10px !important; -} - -p { - margin: 0 0 10px; -} - -.button { - display: inline-block; - border-radius: 4px; -}*/ +} \ No newline at end of file From 9fa94b53665830b27bba3b16d24720ff5ea39e48 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 15 Oct 2018 12:33:11 +0100 Subject: [PATCH 033/337] Update dropdown to be mode & match the same terminology as TinyMCE Modes (Classic, Inline & Distraction Free) --- .../src/views/propertyeditors/rte/rte.prevalues.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html index 3a445b1a85..95f8966c08 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html @@ -41,11 +41,12 @@
- +
From 47596af680b7d01a789dd5f78a69f58ef2df2a48 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 15 Oct 2018 13:04:37 +0100 Subject: [PATCH 034/337] Changes theme prevalue to mode & toggles the various views TinyMCE ships with --- .../src/common/services/tinymce.service.js | 37 ++++++++++++++++++- .../propertyeditors/rte/rte.controller.js | 2 +- .../rte/rte.prevalues.controller.js | 4 +- .../propertyeditors/rte/rte.prevalues.html | 8 ++-- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index f80f80ebf7..4906ed2c9c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -184,12 +184,45 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh plugins.push("autoresize"); plugins.push("noneditable"); + var modeTheme = ''; + var modeInline = false; + + + //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 "inline": + modeTheme = "modern"; + modeInline = true; + break; + + case "distraction-free": + modeTheme = "inlite"; + modeInline = true; + break; + + default: + //Will default to 'classic' + modeTheme = "modern"; + modeInline = false; + break; + } + + + //create a baseline Config to exten upon var config = { //fixed_toolbar_container: "#blah", selector: "#" + args.htmlId, - theme: args.theme ? args.theme : "modern", - inline: true, + theme: modeTheme, + inline: modeInline, plugins: plugins, valid_elements: tinyMceConfig.validElements, invalid_elements: tinyMceConfig.inValidElements, diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 758f138d4a..0b1f9c167c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -75,7 +75,7 @@ angular.module("umbraco") htmlId: $scope.textAreaHtmlId, stylesheets: editorConfig.stylesheets, toolbar: editorConfig.toolbar, - theme: editorConfig.theme + mode: editorConfig.mode })); //wait for queue to end diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js index 4ca1bbc3f9..81d20a105c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js @@ -19,8 +19,8 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", if (!$scope.model.value.maxImageSize && $scope.model.value.maxImageSize != 0) { $scope.model.value.maxImageSize = cfg.maxImageSize; } - if (!$scope.model.value.theme) { - $scope.model.value.theme = "modern"; + if (!$scope.model.value.mode) { + $scope.model.value.mode = "classic"; } tinyMceService.configuration().then(function(config){ diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html index 95f8966c08..47cfd5a31e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html @@ -43,10 +43,10 @@
- + + +
From b92978c7d38032816a090de12ae4e2f41deffe15 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 15 Oct 2018 15:23:56 +0200 Subject: [PATCH 035/337] fix resize + scrolling issues --- .../src/common/services/tinymce.service.js | 8 +------ src/Umbraco.Web.UI.Client/src/less/rte.less | 21 ++++--------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 4906ed2c9c..9884d9abd7 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -44,12 +44,6 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh var styleFormats = []; var promises = [$q.when(true)]; //a collection of promises, the first one is an empty promise - //get the umbraco stylesheet loaded and use that href to inject into tinymce. - //strip off the query string since tiny will append our cache buster itself. - stylesheets.push(_.find(document.styleSheets, function (s) { - return s.href && s.href.indexOf("assets/css/umbraco.css") !== -1 - }).href.split("?")[0]); - //queue rules loading if (configuredStylesheets) { angular.forEach(configuredStylesheets, function (val, key) { @@ -230,7 +224,7 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh menubar: false, statusbar: false, relative_urls: false, - autoresize_bottom_margin: 0, + autoresize_bottom_margin: 10, content_css: styles.stylesheets, style_formats: styles.styleFormats, language: getLanguage(), diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index d0b0ef4fae..f4545ca7db 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -1,36 +1,23 @@ // Styles for the RTE, the whole stylesheet is used in Tiny and these are specific to it's content // ------------------------- -.umb-rte { - overflow: hidden; +.umb-rte .mce-tinymce { + box-shadow: none; } .umb-rte .umb-rte-editor{ border:1px solid @gray-8; - min-height:25px; + min-height: 100px; } .umb-rte.mce-content-body { - padding: 10px; - background-color: #fff; - font-size: 14px; + background-color: @white; line-height: 1.5em; - scrollbar-3dlight-color: #f0f0ee; - scrollbar-arrow-color: #676662; - scrollbar-base-color: #f0f0ee; - scrollbar-darkshadow-color: #ddd; - scrollbar-face-color: #e0e0dd; - scrollbar-highlight-color: #f0f0ee; - scrollbar-shadow-color: #f0f0ee; - scrollbar-track-color: #f5f5f5; } /* loader for macro loading in tinymce*/ .umb-rte.mce-content-body .umb-macro-holder.loading { background: url(img/loader.gif) right no-repeat; - -moz-background-size: 18px; - -o-background-size: 18px; - -webkit-background-size: 18px; background-size: 18px; background-position-x: 99%; } From 7c1fae7462cf0277ea65c21b0213c4c6609d8f37 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 15 Oct 2018 15:54:54 +0200 Subject: [PATCH 036/337] add toolbar pinning back in --- .../components/grid/grid.rte.directive.js | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index 5d2d763ca3..f5af74ed6a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -70,54 +70,54 @@ angular.module("umbraco.directives") }); - //// pin toolbar to top of screen if we have focus and it scrolls off the screen - //var pinToolbar = function () { + // pin toolbar to top of screen if we have focus and it scrolls off the screen + var pinToolbar = function () { - // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - // var toolbarHeight = _toolbar.height(); + var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); + var toolbarHeight = _toolbar.height(); - // var _tinyMce = $(editor.editorContainer); - // var tinyMceRect = _tinyMce[0].getBoundingClientRect(); - // var tinyMceTop = tinyMceRect.top; - // var tinyMceBottom = tinyMceRect.bottom; - // var tinyMceWidth = tinyMceRect.width; + var _tinyMce = $(editor.editorContainer); + var tinyMceRect = _tinyMce[0].getBoundingClientRect(); + var tinyMceTop = tinyMceRect.top; + var tinyMceBottom = tinyMceRect.bottom; + var tinyMceWidth = tinyMceRect.width; - // var _tinyMceEditArea = _tinyMce.find(".mce-edit-area"); + 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); + // set padding in top of mce so the content does not "jump" up + _tinyMceEditArea.css("padding-top", toolbarHeight); - // if (tinyMceTop < 160 && ((160 + toolbarHeight) < tinyMceBottom)) { - // _toolbar - // .css("visibility", "visible") - // .css("position", "fixed") - // .css("top", "160px") - // .css("margin-top", "0") - // .css("width", tinyMceWidth); - // } else { - // _toolbar - // .css("visibility", "visible") - // .css("position", "absolute") - // .css("top", "auto") - // .css("margin-top", "0") - // .css("width", tinyMceWidth); - // } + if (tinyMceTop < 177 && ((177 + toolbarHeight) < tinyMceBottom)) { + _toolbar + .css("visibility", "visible") + .css("position", "fixed") + .css("top", "177px") + .css("margin-top", "0") + .css("width", tinyMceWidth); + } else { + _toolbar + .css("visibility", "visible") + .css("position", "absolute") + .css("top", "auto") + .css("margin-top", "0") + .css("width", tinyMceWidth); + } - //}; + }; - //// unpin toolbar to top of screen - //var unpinToolbar = function() { + // unpin toolbar to top of screen + var unpinToolbar = function() { - // var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - // var _tinyMce = $(editor.editorContainer); - // var _tinyMceEditArea = _tinyMce.find(".mce-edit-area"); + var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); + var _tinyMce = $(editor.editorContainer); + 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"); + // reset padding in top of mce so the content does not "jump" up + _tinyMceEditArea.css("padding-top", "0"); - // _toolbar.css("position", "static"); + _toolbar.css("position", "static"); - //}; + }; //when we leave the editor (maybe) editor.on('blur', function (e) { @@ -131,8 +131,8 @@ angular.module("umbraco.directives") scope.onBlur(); } - //unpinToolbar(); - //$('.umb-panel-body').off('scroll', pinToolbar); + unpinToolbar(); + $('.umb-panel-body').off('scroll', pinToolbar); }); }); @@ -145,8 +145,8 @@ angular.module("umbraco.directives") scope.onFocus(); } - //pinToolbar(); - //$('.umb-panel-body').on('scroll', pinToolbar); + pinToolbar(); + $('.umb-panel-body').on('scroll', pinToolbar); }); }); @@ -159,8 +159,8 @@ angular.module("umbraco.directives") scope.onClick(); } - //pinToolbar(); - //$('.umb-panel-body').on('scroll', pinToolbar); + pinToolbar(); + $('.umb-panel-body').on('scroll', pinToolbar); }); }); From bebc3b5f742f62ac97720575b59c2f1ff4eb8fe8 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Mon, 15 Oct 2018 14:57:31 +0100 Subject: [PATCH 037/337] Remove inline mode - too many issues for now --- .../src/common/services/tinymce.service.js | 5 ----- .../src/views/propertyeditors/rte/rte.prevalues.html | 1 - 2 files changed, 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 9884d9abd7..66e2ce8e88 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -192,11 +192,6 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh modeInline = false; break; - case "inline": - modeTheme = "modern"; - modeInline = true; - break; - case "distraction-free": modeTheme = "inlite"; modeInline = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html index 47cfd5a31e..bba5e22877 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.html @@ -45,7 +45,6 @@
From 02eb1aef918993154b1547bb5b588f86974441db Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 16 Oct 2018 12:15:48 +1100 Subject: [PATCH 038/337] Updates some styles so we get the button state back, cleans up some js --- src/Umbraco.Web.UI.Client/package-lock.json | 28 +++------ .../components/grid/grid.rte.directive.js | 60 +++---------------- .../src/common/services/tinymce.service.js | 43 +++++++++++++ .../src/less/property-editors.less | 28 --------- src/Umbraco.Web.UI.Client/src/less/rte.less | 39 ++++++++++-- .../rte/codeeditor.controller.js | 6 +- 6 files changed, 96 insertions(+), 108 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 5441f259e1..7d914ec558 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -5480,14 +5480,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5502,20 +5500,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5632,8 +5627,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5645,7 +5639,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5660,7 +5653,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5668,14 +5660,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -5694,7 +5684,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5775,8 +5764,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5788,7 +5776,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5910,7 +5897,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index f5af74ed6a..882a808ae4 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -1,5 +1,5 @@ angular.module("umbraco.directives") - .directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout) { + .directive('gridRte', function (tinyMceService, angularHelper, assetsService, $q, $timeout) { return { scope: { uniqueId: '=', @@ -71,69 +71,26 @@ angular.module("umbraco.directives") }); // pin toolbar to top of screen if we have focus and it scrolls off the screen - var pinToolbar = function () { - - var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - var toolbarHeight = _toolbar.height(); - - var _tinyMce = $(editor.editorContainer); - var tinyMceRect = _tinyMce[0].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("visibility", "visible") - .css("position", "fixed") - .css("top", "177px") - .css("margin-top", "0") - .css("width", tinyMceWidth); - } else { - _toolbar - .css("visibility", "visible") - .css("position", "absolute") - .css("top", "auto") - .css("margin-top", "0") - .css("width", tinyMceWidth); - } - - }; + function pinToolbar() { + tinyMceService.pinToolbar(editor); + } // unpin toolbar to top of screen - var unpinToolbar = function() { - - var _toolbar = $(editor.editorContainer).find(".mce-toolbar"); - var _tinyMce = $(editor.editorContainer); - 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"); - - }; + function unpinToolbar() { + tinyMceService.unpinToolbar(editor); + } //when we leave the editor (maybe) editor.on('blur', function (e) { angularHelper.safeApply(scope, function () { scope.value = editor.getContent(); - var _toolbar = $(editor.editorContainer) - .find(".mce-toolbar"); - if (scope.onBlur) { scope.onBlur(); } unpinToolbar(); $('.umb-panel-body').off('scroll', pinToolbar); - }); }); @@ -147,7 +104,6 @@ angular.module("umbraco.directives") pinToolbar(); $('.umb-panel-body').on('scroll', pinToolbar); - }); }); @@ -244,6 +200,8 @@ angular.module("umbraco.directives") // element might still be there even after the modal has been hidden. scope.$on('$destroy', function () { unsubscribe(); + //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() } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 66e2ce8e88..fd82b663d5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -1166,6 +1166,49 @@ function tinyMceService($log, $q, imageHelper, $locale, $http, $timeout, stylesh insertLink(); + }, + + pinToolbar : function (editor) { + + var tinyMce = $(editor.editorContainer); + var toolbar = tinyMce.find(".mce-toolbar"); + var toolbarHeight = toolbar.height(); + var tinyMceRect = tinyMce[0].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("visibility", "visible") + .css("position", "fixed") + .css("top", "177px") + .css("margin-top", "0") + .css("width", tinyMceWidth); + } else { + toolbar + .css("visibility", "visible") + .css("position", "absolute") + .css("top", "auto") + .css("margin-top", "0") + .css("width", tinyMceWidth); + } + + }, + + 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"); } }; diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 43f5aa5a9a..c94db10d06 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -97,34 +97,6 @@ } } -/* CODEMIRROR DATATYPE */ -div.umb-codeeditor { - border: 1px solid @gray-8; -} -div.umb-codeeditor .umb-el-wrap { - padding: 0px; -} -div.umb-codeeditor .umb-btn-toolbar { - padding: 0px; - margin: 0px; - border-bottom: @gray-8 1px solid; - background: @gray-10; -} - - -// -// RTE -// -------------------------------------------------- -.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0px !important;} -.mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;} -.mce-btn-group, .mce-btn{border: none !important; background: none !important;} -.mce-ico{font-size: 12px !important; color: @gray-1 !important;} -/* Special case to support helviticons for the tiny mce button controls */ -.mce-ico.mce-i-custom[class^="icon-"], -.mce-ico.mce-i-custom[class*=" icon-"] { - font-family: icomoon; - font-size:16px !important; -} /* pre-value editor */ .rte-editor-preval .control-group .controls > div > label .mce-ico { line-height: 20px; } diff --git a/src/Umbraco.Web.UI.Client/src/less/rte.less b/src/Umbraco.Web.UI.Client/src/less/rte.less index f4545ca7db..51c4a3ebd5 100644 --- a/src/Umbraco.Web.UI.Client/src/less/rte.less +++ b/src/Umbraco.Web.UI.Client/src/less/rte.less @@ -3,20 +3,22 @@ .umb-rte .mce-tinymce { box-shadow: none; + } .umb-rte .umb-rte-editor{ - border:1px solid @gray-8; min-height: 100px; } -.umb-rte.mce-content-body { +.umb-rte .mce-content-body { background-color: @white; line-height: 1.5em; + border: 1px solid @gray-8; + padding:10px; } /* loader for macro loading in tinymce*/ -.umb-rte.mce-content-body .umb-macro-holder.loading { +.umb-rte .mce-content-body .umb-macro-holder.loading { background: url(img/loader.gif) right no-repeat; background-size: 18px; background-position-x: 99%; @@ -29,4 +31,33 @@ /* make sure the menu wraps */ .umb-rte .mce-top-part.mce-container div { white-space: normal; -} \ No newline at end of file +} + +.umb-rte .mce-tinymce .mce-edit-area { + border: 1px solid @gray-8 !important; + border-radius: 0px !important; +} + +/* +.mce-panel { + background: @gray-10 !important; + border-color: @gray-8 !important; +} + +.mce-btn-group, .mce-btn { + border: none !important; + background: none !important; +} +*/ + +.mce-ico { + font-size: 12px !important; + /*color: @gray-1 !important;*/ +} + +/* Special case to support helviticons for the tiny mce button controls */ +.mce-ico.mce-i-custom[class^="icon-"], +.mce-ico.mce-i-custom[class*=" icon-"] { + font-family: icomoon; + font-size: 16px !important; +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js index 97f00023bb..b795c49855 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/codeeditor.controller.js @@ -32,10 +32,8 @@ // set default title if(!$scope.model.title) { - // TODO change to a new key to get 'source code' or similar - localizationService.localize("defaultdialogs_selectUsers").then(function(value){ - $scope.model.title = value; - }); + // TODO localize + $scope.model.title = "Edit source code"; } } From 4a49817322bdbfd97f9d7888098b590250d1e6a7 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 22 Oct 2018 08:31:10 +0200 Subject: [PATCH 039/337] Fixes a few oversights in image cropper --- .../directives/components/imaging/umbimagegravity.directive.js | 2 +- .../src/views/components/imaging/umb-image-gravity.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js index d0ccc4647e..bb364b79ee 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js @@ -110,7 +110,7 @@ angular.module("umbraco.directives") scope.isCroppable = true; scope.hasDimensions = true; - if (scope.src !== "undefined") { + if (scope.src) { if (scope.src.endsWith(".svg")) { scope.isCroppable = false; scope.hasDimensions = false; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html index ddb5ed2af1..620efb9e3f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/imaging/umb-image-gravity.html @@ -5,7 +5,7 @@ -
+
From 21cb0f79c34d48b13f66c8a426a50c3191fba858 Mon Sep 17 00:00:00 2001 From: emmaburstow <37150989+emmaburstow@users.noreply.github.com> Date: Mon, 22 Oct 2018 17:19:59 +0100 Subject: [PATCH 040/337] Added dictionary item for member group save message (#3379) --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index ff234c71da..6f17bb4e8a 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1400,6 +1400,7 @@ To manage your website, simply open the Umbraco back office and start adding con Sent For Approval Changes have been sent for approval Media saved + Member group saved Media saved without any errors Member saved Stylesheet Property Saved diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index ed3a261979..ba32e7f7d1 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -1400,6 +1400,7 @@ To manage your website, simply open the Umbraco back office and start adding con Media saved Media saved without any errors Member saved + Member group saved Stylesheet Property Saved Stylesheet saved Template saved From b539cc2a7ad21e0126091c6610459ab097209bfb Mon Sep 17 00:00:00 2001 From: GwanYeong Kim Date: Tue, 23 Oct 2018 13:39:23 +0900 Subject: [PATCH 041/337] Remove this commented out code --- .../Persistence/SqlSyntax/MySqlSyntaxProvider.cs | 7 +------ src/Umbraco.Web/Controllers/UmbLoginController.cs | 1 - src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs | 3 +-- src/umbraco.cms/Actions/Action.cs | 1 - 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index c3ad8f48c4..3e17294b3f 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -333,14 +333,9 @@ ORDER BY TABLE_NAME, INDEX_NAME", switch (systemMethod) { case SystemMethods.NewGuid: - return null; // NOT SUPPORTED! - //return "NEWID()"; + return null; // NOT SUPPORTED! case SystemMethods.CurrentDateTime: return "CURRENT_TIMESTAMP"; - //case SystemMethods.NewSequentialId: - // return "NEWSEQUENTIALID()"; - //case SystemMethods.CurrentUTCDateTime: - // return "GETUTCDATE()"; } return null; diff --git a/src/Umbraco.Web/Controllers/UmbLoginController.cs b/src/Umbraco.Web/Controllers/UmbLoginController.cs index d446df5683..df67be72ce 100644 --- a/src/Umbraco.Web/Controllers/UmbLoginController.cs +++ b/src/Umbraco.Web/Controllers/UmbLoginController.cs @@ -45,7 +45,6 @@ namespace Umbraco.Web.Controllers //redirect to current page by default return RedirectToCurrentUmbracoPage(); - //return RedirectToCurrentUmbracoUrl(); } } } diff --git a/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs index 36593736d3..348655d2ba 100644 --- a/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs +++ b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs @@ -51,7 +51,6 @@ break; } - // constraintValue = condition.Property.Type == "string" ? string.Format("\"{0}\"", condition.ConstraintValue) : condition.ConstraintValue; } switch (condition.Term.Operathor) @@ -95,4 +94,4 @@ } } -} \ No newline at end of file +} diff --git a/src/umbraco.cms/Actions/Action.cs b/src/umbraco.cms/Actions/Action.cs index c7a9a6242b..7f65145412 100644 --- a/src/umbraco.cms/Actions/Action.cs +++ b/src/umbraco.cms/Actions/Action.cs @@ -62,7 +62,6 @@ namespace umbraco.BusinessLogic.Actions return ActionsResolver.Current.Actions .Where(x => !string.IsNullOrWhiteSpace(x.JsSource)) .Select(x => x.JsSource).ToList(); - //return ActionJsReference; } /// From 1080d983396905aa995f6fdb2ea7a03d6bca1a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Kottal?= Date: Mon, 22 Oct 2018 20:17:48 +0200 Subject: [PATCH 042/337] Fixes incorrect swedish translation --- src/Umbraco.Web.UI/umbraco/config/lang/sv.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml index 0795752fad..d011f7dadb 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml @@ -1,4 +1,4 @@ - + The Umbraco community @@ -437,7 +437,7 @@ nuvarande Inbäddning Hämta - valgt + valda Bakgrundsfärg From 7df6b661c5ff38ebc77e22a5130ec07c6ba932d3 Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Tue, 23 Oct 2018 10:23:09 +0200 Subject: [PATCH 043/337] Mediatyperesource localized (#3378) --- .../common/resources/mediatype.resource.js | 536 +++++++++--------- .../src/views/mediatypes/create.controller.js | 3 +- .../src/views/mediatypes/create.html | 7 + src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 4 + src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 4 + .../umbraco/config/lang/en_us.xml | 4 + 6 files changed, 292 insertions(+), 266 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js index 140995cd57..2d74676d9c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js @@ -1,264 +1,272 @@ -/** - * @ngdoc service - * @name umbraco.resources.mediaTypeResource - * @description Loads in data for media types - **/ -function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { - - return { - - getCount: function () { - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "GetCount")), - 'Failed to retrieve count'); - }, - - getAvailableCompositeContentTypes: function (contentTypeId, filterContentTypes, filterPropertyTypes) { - if (!filterContentTypes) { - filterContentTypes = []; - } - if (!filterPropertyTypes) { - filterPropertyTypes = []; - } - - var query = { - contentTypeId: contentTypeId, - filterContentTypes: filterContentTypes, - filterPropertyTypes: filterPropertyTypes - }; - - return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "GetAvailableCompositeMediaTypes"), - query), - 'Failed to retrieve data for content type id ' + contentTypeId); - }, - /** - * @ngdoc method - * @name umbraco.resources.mediaTypeResource#getWhereCompositionIsUsedInContentTypes - * @methodOf umbraco.resources.mediaTypeResource - * - * @description - * Returns a list of media types which use a specific composition with a given id - * - * ##usage - *
-         * mediaTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
-         *    .then(function(mediaTypeList) {
-         *        console.log(mediaTypeList);
-         *    });
-         * 
- * @param {Int} contentTypeId id of the composition content type to retrieve the list of the media types where it has been used - * @returns {Promise} resourcePromise object. - * - */ - getWhereCompositionIsUsedInContentTypes: function (contentTypeId) { - var query = { - contentTypeId: contentTypeId - }; - - return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "GetWhereCompositionIsUsedInContentTypes"), - query), - 'Failed to retrieve data for content type id ' + contentTypeId); - }, - /** - * @ngdoc method - * @name umbraco.resources.mediaTypeResource#getAllowedTypes - * @methodOf umbraco.resources.mediaTypeResource - * - * @description - * Returns a list of allowed media types underneath a media item with a given ID - * - * ##usage - *
-         * mediaTypeResource.getAllowedTypes(1234)
-         *    .then(function(array) {
-         *        $scope.type = type;
-         *    });
-         * 
- * @param {Int} mediaId id of the media item to retrive allowed child types for - * @returns {Promise} resourcePromise object. - * - */ - getAllowedTypes: function (mediaId) { - - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "GetAllowedChildren", - [{ contentId: mediaId }])), - 'Failed to retrieve allowed types for media id ' + mediaId); - }, - - getById: function (id) { - - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "GetById", - [{ id: id }])), - 'Failed to retrieve content type'); - }, - - getAll: function () { - - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "GetAll")), - 'Failed to retrieve all content types'); - }, - - getScaffold: function (parentId) { - - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "GetEmpty", { parentId: parentId })), - 'Failed to retrieve content type scaffold'); - }, - - deleteById: function (id) { - - return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "DeleteById", - [{ id: id }])), - 'Failed to retrieve content type'); - }, - - deleteContainerById: function (id) { - - return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "DeleteContainer", - [{ id: id }])), - 'Failed to delete content type contaier'); - }, - - /** - * @ngdoc method - * @name umbraco.resources.mediaTypeResource#save - * @methodOf umbraco.resources.mediaTypeResource - * - * @description - * Saves or update a media type - * - * @param {Object} content data type object to create/update - * @returns {Promise} resourcePromise object. - * - */ - save: function (contentType) { - - var saveModel = umbDataFormatter.formatContentTypePostData(contentType); - - return umbRequestHelper.resourcePromise( - $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostSave"), saveModel), - 'Failed to save data for content type id ' + contentType.id); - }, - - /** - * @ngdoc method - * @name umbraco.resources.mediaTypeResource#move - * @methodOf umbraco.resources.mediaTypeResource - * - * @description - * Moves a node underneath a new parentId - * - * ##usage - *
-         * mediaTypeResource.move({ parentId: 1244, id: 123 })
-         *    .then(function() {
-         *        alert("node was moved");
-         *    }, function(err){
-         *      alert("node didnt move:" + err.data.Message);
-         *    });
-         * 
- * @param {Object} args arguments object - * @param {Int} args.idd the ID of the node to move - * @param {Int} args.parentId the ID of the parent node to move to - * @returns {Promise} resourcePromise object. - * - */ - move: function (args) { - if (!args) { - throw "args cannot be null"; - } - if (!args.parentId) { - throw "args.parentId cannot be null"; - } - if (!args.id) { - throw "args.id cannot be null"; - } - - return umbRequestHelper.resourcePromise( - $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostMove"), - { - parentId: args.parentId, - id: args.id - }), - 'Failed to move content'); - }, - - copy: function (args) { - if (!args) { - throw "args cannot be null"; - } - if (!args.parentId) { - throw "args.parentId cannot be null"; - } - if (!args.id) { - throw "args.id cannot be null"; - } - - return umbRequestHelper.resourcePromise( - $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostCopy"), - { - parentId: args.parentId, - id: args.id - }), - 'Failed to copy content'); - }, - - createContainer: function(parentId, name) { - - return umbRequestHelper.resourcePromise( - $http.post( - umbRequestHelper.getApiUrl( - "mediaTypeApiBaseUrl", - "PostCreateContainer", - { parentId: parentId, name: encodeURIComponent(name) })), - 'Failed to create a folder under parent id ' + parentId); - }, - - renameContainer: function (id, name) { - - return umbRequestHelper.resourcePromise( - $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", - "PostRenameContainer", - { id: id, name: name })), - "Failed to rename the folder with id " + id - ); - - } - - }; -} -angular.module('umbraco.resources').factory('mediaTypeResource', mediaTypeResource); +/** + * @ngdoc service + * @name umbraco.resources.mediaTypeResource + * @description Loads in data for media types + **/ +function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter, localizationService) { + + return { + + getCount: function () { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetCount")), + 'Failed to retrieve count'); + }, + + getAvailableCompositeContentTypes: function (contentTypeId, filterContentTypes, filterPropertyTypes) { + if (!filterContentTypes) { + filterContentTypes = []; + } + if (!filterPropertyTypes) { + filterPropertyTypes = []; + } + + var query = { + contentTypeId: contentTypeId, + filterContentTypes: filterContentTypes, + filterPropertyTypes: filterPropertyTypes + }; + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetAvailableCompositeMediaTypes"), + query), + 'Failed to retrieve data for content type id ' + contentTypeId); + }, + /** + * @ngdoc method + * @name umbraco.resources.mediaTypeResource#getWhereCompositionIsUsedInContentTypes + * @methodOf umbraco.resources.mediaTypeResource + * + * @description + * Returns a list of media types which use a specific composition with a given id + * + * ##usage + *
+         * mediaTypeResource.getWhereCompositionIsUsedInContentTypes(1234)
+         *    .then(function(mediaTypeList) {
+         *        console.log(mediaTypeList);
+         *    });
+         * 
+ * @param {Int} contentTypeId id of the composition content type to retrieve the list of the media types where it has been used + * @returns {Promise} resourcePromise object. + * + */ + getWhereCompositionIsUsedInContentTypes: function (contentTypeId) { + var query = { + contentTypeId: contentTypeId + }; + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetWhereCompositionIsUsedInContentTypes"), + query), + 'Failed to retrieve data for content type id ' + contentTypeId); + }, + /** + * @ngdoc method + * @name umbraco.resources.mediaTypeResource#getAllowedTypes + * @methodOf umbraco.resources.mediaTypeResource + * + * @description + * Returns a list of allowed media types underneath a media item with a given ID + * + * ##usage + *
+         * mediaTypeResource.getAllowedTypes(1234)
+         *    .then(function(array) {
+         *        $scope.type = type;
+         *    });
+         * 
+ * @param {Int} mediaId id of the media item to retrive allowed child types for + * @returns {Promise} resourcePromise object. + * + */ + getAllowedTypes: function (mediaId) { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetAllowedChildren", + [{ contentId: mediaId }])), + 'Failed to retrieve allowed types for media id ' + mediaId); + }, + + getById: function (id) { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetById", + [{ id: id }])), + 'Failed to retrieve content type'); + }, + + getAll: function () { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetAll")), + 'Failed to retrieve all content types'); + }, + + getScaffold: function (parentId) { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetEmpty", { parentId: parentId })), + 'Failed to retrieve content type scaffold'); + }, + + deleteById: function (id) { + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "DeleteById", + [{ id: id }])), + 'Failed to retrieve content type'); + }, + + deleteContainerById: function (id) { + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "DeleteContainer", + [{ id: id }])), + 'Failed to delete content type contaier'); + }, + + /** + * @ngdoc method + * @name umbraco.resources.mediaTypeResource#save + * @methodOf umbraco.resources.mediaTypeResource + * + * @description + * Saves or update a media type + * + * @param {Object} content data type object to create/update + * @returns {Promise} resourcePromise object. + * + */ + save: function (contentType) { + + var saveModel = umbDataFormatter.formatContentTypePostData(contentType); + + return umbRequestHelper.resourcePromise( + $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostSave"), saveModel), + 'Failed to save data for content type id ' + contentType.id); + }, + + /** + * @ngdoc method + * @name umbraco.resources.mediaTypeResource#move + * @methodOf umbraco.resources.mediaTypeResource + * + * @description + * Moves a node underneath a new parentId + * + * ##usage + *
+         * mediaTypeResource.move({ parentId: 1244, id: 123 })
+         *    .then(function() {
+         *        alert("node was moved");
+         *    }, function(err){
+         *      alert("node didnt move:" + err.data.Message);
+         *    });
+         * 
+ * @param {Object} args arguments object + * @param {Int} args.idd the ID of the node to move + * @param {Int} args.parentId the ID of the parent node to move to + * @returns {Promise} resourcePromise object. + * + */ + move: function (args) { + if (!args) { + throw "args cannot be null"; + } + if (!args.parentId) { + throw "args.parentId cannot be null"; + } + if (!args.id) { + throw "args.id cannot be null"; + } + + var promise = localizationService.localize("media_moveFailed"); + + return umbRequestHelper.resourcePromise( + $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostMove"), + { + parentId: args.parentId, + id: args.id + }), + promise); + }, + + copy: function (args) { + if (!args) { + throw "args cannot be null"; + } + if (!args.parentId) { + throw "args.parentId cannot be null"; + } + if (!args.id) { + throw "args.id cannot be null"; + } + + var promise = localizationService.localize("media_copyFailed"); + + return umbRequestHelper.resourcePromise( + $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", "PostCopy"), + { + parentId: args.parentId, + id: args.id + }), + promise); + }, + + createContainer: function(parentId, name) { + + var promise = localizationService.localize("media_createFolderFailed", [parentId]); + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "PostCreateContainer", + { parentId: parentId, name: encodeURIComponent(name) })), + promise); + }, + + renameContainer: function (id, name) { + + var promise = localizationService.localize("media_renameFolderFailed", [id]); + + return umbRequestHelper.resourcePromise( + $http.post(umbRequestHelper.getApiUrl("mediaTypeApiBaseUrl", + "PostRenameContainer", + { id: id, name: name })), + promise + ); + + } + + }; +} +angular.module('umbraco.resources').factory('mediaTypeResource', mediaTypeResource); diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js index bc0cf854c6..4fa96b8585 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.controller.js @@ -37,8 +37,7 @@ function MediaTypesCreateController($scope, $location, navigationService, mediaT var section = appState.getSectionState("currentSection"); }, function(err) { - - //TODO: Handle errors + $scope.error = err; }); }; } diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html index afcb1ef787..9f8b2e033f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/create.html @@ -27,6 +27,13 @@ ng-submit="createContainer()" val-form-manager> +
+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
+
+ diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index 886662d17f..271144c7ec 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -266,6 +266,10 @@ Kan ikke uploade denne fil, den har ikke en godkendt filtype Maks filstørrelse er Medie rod + Flytning af mediet fejlede + Kopiering af mediet fejlede + Oprettelse af mappen under parent med id %0% fejlede + Omdøbning af mappen med id %0% fejlede Opret et nyt medlem diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 6f17bb4e8a..af8c302aff 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -274,6 +274,10 @@ Cannot upload this file, it does not have an approved file type Max file size is Media root + Failed to move media + Failed to copy media + Failed to create a folder under parent id %0% + Failed to rename the folder with id %0% Create a new member diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index ba32e7f7d1..5355928f17 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -275,6 +275,10 @@ Cannot upload this file, it does not have an approved file type Max file size is Media root + Failed to move media + Failed to copy media + Failed to create a folder under parent id %0% + Failed to rename the folder with id %0% Create a new member From de42eaea44c24d0de01007aa9dff69da1b60cc94 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Mon, 22 Oct 2018 09:11:07 +0200 Subject: [PATCH 044/337] Move some padding around to fix unaligned labels and values --- src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx index 77deab2709..4358715836 100644 --- a/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx +++ b/src/Umbraco.Web.UI/umbraco/dialogs/ChangeDocType.aspx @@ -19,7 +19,7 @@ .umb-dialog .umb-control-group .umb-el-wrap { overflow: hidden; } .umb-dialog .umb-control-group .umb-el-wrap label { float: left; width: 140px; font-weight: bold; } .umb-dialog .umb-control-group .umb-el-wrap label:after { content:":"; } - .umb-dialog .umb-control-group .umb-el-wrap .controls-row { float: left; width: 280px; padding-top: 8px; } + .umb-dialog .umb-control-group .umb-el-wrap .controls-row { float: left; width: 280px; padding-bottom: 8px; } .umb-dialog .umb-control-group .umb-el-wrap .controls-row select { width: auto; } @@ -118,4 +118,3 @@
- \ No newline at end of file From a0eba5a9d82f565e8f087853898da11b80c1e65d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 23 Oct 2018 15:02:56 +0200 Subject: [PATCH 045/337] wip testing ideas --- .../content/umbtabbedcontent.directive.js | 8 ++++++++ .../property/umbpropertyeditor.directive.js | 2 +- .../content/umb-tabbed-content.html | 19 ++++++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js index 015255c577..e00b333a2f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js @@ -13,6 +13,14 @@ //expose the property/methods for other directives to use this.content = $scope.content; + $scope.activeVariant = _.find(this.content.variants, variant => { + return variant.active; + }); + + $scope.unlockInvariantValue = function(property) { + property.unlockInvariantValue = !property.unlockInvariantValue; + }; + $scope.$watch("tabbedContentForm.$dirty", function (newValue, oldValue) { if (newValue === true) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js index 0aa2dc02c3..32cbbb31ec 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbpropertyeditor.directive.js @@ -12,7 +12,7 @@ function umbPropEditor(umbPropEditorHelper) { scope: { model: "=", isPreValue: "@", - preview: "@" + preview: "<" }, require: "^^form", diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html index b125457ab0..68d5d3d41c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html @@ -9,7 +9,24 @@
- + +
+ +
+
Unlock to change on all languages
+
Changes to {{property.label}} will be copied to all languages
+
+ +
+ Changes to {{property.label}} will be copied to all languages +
+
+ + + +
From 60b575825d8a464a636e75155945457b5000cd1a Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 23 Oct 2018 14:22:17 +0100 Subject: [PATCH 046/337] Adds new WIP attribute only based directive disable-tabindex - which sets all child input elements to use a tabindex of -1 --- .../util/disabletabindex.directive.js | 28 +++++++++++++++++++ .../views/components/umb-groups-builder.html | 13 +++++---- 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js new file mode 100644 index 0000000000..7f9a0fd2b3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -0,0 +1,28 @@ +angular.module("umbraco.directives") + .directive('disableTabindex', function ($window, $timeout, windowResizeListener) { + + return { + restrict: 'A', //Can only be used as an attribute + link: function (scope, element, attrs) { + + //When the current element DOM subtree is modified + element.on('DOMSubtreeModified', function(e){ + //Check if any child items in e.target contain an input + var jqLiteEl = angular.element(e.target); + var childInputs = jqLiteEl.find('input'); + + console.log('jQLite childInputs', childInputs); + + //For each item in childInputs - override or set HTML attribute tabindex="-1" + angular.forEach(childInputs, function(element){ + console.log('item in loop', element); + + //TODO: Note we updating way too many times from the DOMSubtreeModified event - is this expensive? + angular.element(element).attr('tabindex', '-1'); + }); + + }); + + } + }; +}); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html index 2a5bc4a572..8732da91e7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html @@ -157,7 +157,7 @@
{{propertyTypeForm.groupName.errorMsg}}
- +
@@ -229,11 +229,12 @@
- - + + From e0b44c90ff79f4e667b0c5f8d3098fe4fb87b38d Mon Sep 17 00:00:00 2001 From: angie1015 <42840450+angie1015@users.noreply.github.com> Date: Tue, 23 Oct 2018 06:55:31 -0700 Subject: [PATCH 047/337] Fixed minor typos --- .github/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/README.md b/.github/README.md index e8a9889916..6c3476ac77 100644 --- a/.github/README.md +++ b/.github/README.md @@ -19,7 +19,7 @@ Umbraco is a free open source Content Management System built on the ASP.NET pla For the first time on the Microsoft platform, there is a free user and developer friendly CMS that makes it quick and easy to create websites - or a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, out of the box. -Umbraco is not only loved by developers, but is a content editors dream. Enjoy intuitive editing tools, media management, responsive views and approval workflows to send your content live. +Umbraco is not only loved by developers, but is a content editor's dream. Enjoy intuitive editing tools, media management, responsive views and approval workflows to send your content live. Used by more than 443,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scales. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 220,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay. @@ -30,7 +30,7 @@ As an Open Source platform, Umbraco is more than just a CMS. We are transparent ## Trying out Umbraco CMS -[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and intergrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed. +[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and integrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed. If you want to DIY you can [download Umbraco](https://our.umbraco.com/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host yourself and handling deployments and upgrades is all down to you. From 515f183b28f3e935250f879ca131290ee909d276 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 23 Oct 2018 16:00:53 +0200 Subject: [PATCH 048/337] make default language bold in selectors --- src/Umbraco.Web.UI.Client/src/less/components/editor.less | 1 - .../src/views/components/application/umb-navigation.html | 2 +- .../src/views/components/editor/umb-editor-content-header.html | 2 +- src/Umbraco.Web.UI.Client/src/views/languages/overview.html | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/editor.less b/src/Umbraco.Web.UI.Client/src/less/components/editor.less index f045b0adca..d699193c24 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/editor.less @@ -201,7 +201,6 @@ a.umb-variant-switcher__toggle { .umb-variant-switcher__name { display: block; - font-weight: bold; } .umb-variant-switcher__state { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html index 570ea3990b..ddb0396f34 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html @@ -11,7 +11,7 @@   diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html index 149fccd00a..999176f608 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html @@ -41,7 +41,7 @@ - {{variant.language.name}} + {{variant.language.name}}
Open in split view
diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/overview.html b/src/Umbraco.Web.UI.Client/src/views/languages/overview.html index dfec56fbc0..c55ce83417 100644 --- a/src/Umbraco.Web.UI.Client/src/views/languages/overview.html +++ b/src/Umbraco.Web.UI.Client/src/views/languages/overview.html @@ -41,7 +41,7 @@ - {{ language.name }} + {{ language.name }} {{ language.culture }} From c0b713d0e4c6a8779933791709d883b79cf0e37d Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Tue, 23 Oct 2018 16:06:06 +0200 Subject: [PATCH 049/337] 3381 - Media picker: Trashed media warning looks weird (#3382) --- .../src/less/property-editors.less | 14 ++++++- .../mediapicker/mediapicker.controller.js | 12 +++--- .../mediapicker/mediapicker.html | 38 ++++++++++--------- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 412a87d909..e9f4acd120 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -235,6 +235,18 @@ div.umb-codeeditor .umb-btn-toolbar { } } +.umb-mediapicker .label{ + &__trashed{ + background-color: @red; + position: absolute; + top: 50%; + left: 50%; + z-index: 1; + transform: translate3d(-50%,-50%,0); + margin: 0; + } +} + .umb-mediapicker .picked-image { position: absolute; bottom: 10px; @@ -333,7 +345,7 @@ div.umb-codeeditor .umb-btn-toolbar { background-image: url(../img/checkered-background.png); } -.umb-sortable-thumbnails li img.trashed { +.umb-sortable-thumbnails li .trashed { opacity:0.3; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index bf7462942a..7b8445a4dc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -16,7 +16,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl } function setupViewModel() { - $scope.images = []; + $scope.mediaItems = []; $scope.ids = []; $scope.isMultiPicker = multiPicker; @@ -41,7 +41,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl // on whether it is simply resaved or not. // This is done by remapping the int/guid ids into a new array of items, where we create "Deleted item" placeholders // when there is no match for a selected id. This will ensure that the values being set on save, are the same as before. - + medias = _.map(ids, function(id) { var found = _.find(medias, @@ -72,7 +72,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); } - $scope.images.push(media); + $scope.mediaItems.push(media); if ($scope.model.config.idType === "udi") { $scope.ids.push(media.udi); @@ -89,7 +89,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl setupViewModel(); $scope.remove = function(index) { - $scope.images.splice(index, 1); + $scope.mediaItems.splice(index, 1); $scope.ids.splice(index, 1); $scope.sync(); }; @@ -117,7 +117,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); } - $scope.images.push(media); + $scope.mediaItems.push(media); if ($scope.model.config.idType === "udi") { $scope.ids.push(media.udi); @@ -145,7 +145,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl // content picker. Then we don't have to worry about setting ids, render models, models, we just set one and let the // watch do all the rest. $timeout(function(){ - angular.forEach($scope.images, function(value, key) { + angular.forEach($scope.mediaItems, function(value, key) { r.push($scope.model.config.idType === "udi" ? value.udi : value.id); }); $scope.ids = r; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html index 2efed8b3e8..7e9568bdd2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html @@ -1,31 +1,35 @@
-

-

- -
-
    -
  • +

    +

    + +
    +
      +
    • + +

      + + +

      - - + - - + + - +
      - - .{{image.extension}} + + .{{media.metaData.umbracoExtension.Value}} - {{image.name}} - + {{media.name}} +
    • - +
    • From a8ac9cf8f28f99f0ebf76e5676b5e1697876e06e Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 23 Oct 2018 15:13:35 +0100 Subject: [PATCH 050/337] MDN JS Docs suggested to use MutationObsorver as oppsoed to deprecated DOMSubtreeModified event --- .../util/disabletabindex.directive.js | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js index 7f9a0fd2b3..64edcf5955 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -5,22 +5,52 @@ angular.module("umbraco.directives") restrict: 'A', //Can only be used as an attribute link: function (scope, element, attrs) { - //When the current element DOM subtree is modified - element.on('DOMSubtreeModified', function(e){ - //Check if any child items in e.target contain an input - var jqLiteEl = angular.element(e.target); - var childInputs = jqLiteEl.find('input'); + //Use DOM Mutation Observer + //Select the node that will be observed for mutations (native DOM element not jQLite version) + var targetNode = element[0]; - console.log('jQLite childInputs', childInputs); + // Options for the observer (which mutations to observe) + var config = { attributes: false, childList: true, subtree: false }; - //For each item in childInputs - override or set HTML attribute tabindex="-1" - angular.forEach(childInputs, function(element){ - console.log('item in loop', element); + // Callback function to execute when mutations are observed + var callback = function(mutationsList, observer) { + for(var mutation of mutationsList) { - //TODO: Note we updating way too many times from the DOMSubtreeModified event - is this expensive? - angular.element(element).attr('tabindex', '-1'); - }); + console.log('mutation', mutation); + //DOM items have been added or removed + if (mutation.type == 'childList') { + + //Check if any child items in mutation.target contain an input + var jqLiteEl = angular.element(mutation.target); + var childInputs = jqLiteEl.find('input'); + + //For each item in childInputs - override or set HTML attribute tabindex="-1" + angular.forEach(childInputs, function(element){ + console.log('item in loop', element); + + //TODO: Note we updating way too many times from the DOMSubtreeModified event - is this expensive? + angular.element(element).attr('tabindex', '-1'); + }); + } + } + }; + + // Create an observer instance linked to the callback function + var observer = new MutationObserver(callback); + + // Start observing the target node for configured mutations + //GO GO GO + observer.observe(targetNode, config); + + + //TODO: Unsure if we need to do this - to ensure the browser not trying to notify us still + //When we browse away from the page + element.on('$destroy', function(e){ + console.log('element with disable-tabindex attribute is destoryed'); + + //Remove/stop the observer + observer.disconnect(); }); } From b20acebe6a4e48f5d7c96b2c833d28442d47aa2e Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 23 Oct 2018 15:23:36 +0100 Subject: [PATCH 051/337] Cleanup unused DI stuff in this directive --- .../src/common/directives/util/disabletabindex.directive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js index 64edcf5955..624404c641 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -1,5 +1,5 @@ angular.module("umbraco.directives") - .directive('disableTabindex', function ($window, $timeout, windowResizeListener) { + .directive('disableTabindex', function () { return { restrict: 'A', //Can only be used as an attribute From 39045b1edc2cfbdb7bfda2d85349d6ddb39d479d Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Tue, 23 Oct 2018 16:32:07 +0200 Subject: [PATCH 052/337] 3324 - Suggestion: Align image cropper property editor UI with color picker and checkbox lists (#3325) --- .../components/prevalues/multivalues.less | 4 + src/Umbraco.Web.UI.Client/src/less/main.less | 21 +++- .../src/less/property-editors.less | 115 ++++++++++++++++-- .../imagecropper.prevalues.controller.js | 50 ++++++-- .../imagecropper/imagecropper.prevalues.html | 105 ++++++++++------ src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 - .../umbraco/config/lang/en_us.xml | 2 - src/Umbraco.Web.UI/umbraco/config/lang/es.xml | 2 - src/Umbraco.Web.UI/umbraco/config/lang/fr.xml | 1 - src/Umbraco.Web.UI/umbraco/config/lang/pl.xml | 2 - src/Umbraco.Web.UI/umbraco/config/lang/ru.xml | 2 - src/Umbraco.Web.UI/umbraco/config/lang/sv.xml | 2 - src/Umbraco.Web.UI/umbraco/config/lang/zh.xml | 2 - .../ImageCropperPropertyEditor.cs | 2 +- 14 files changed, 229 insertions(+), 83 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less b/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less index 43f6697eb1..0dbc4c381c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/prevalues/multivalues.less @@ -5,6 +5,10 @@ .umb-overlay & { width: 500px; } + + p{ + margin: 7px 0; + } } .umb-prevalues-multivalues__left { diff --git a/src/Umbraco.Web.UI.Client/src/less/main.less b/src/Umbraco.Web.UI.Client/src/less/main.less index b16e437cc2..46f0f86d8d 100644 --- a/src/Umbraco.Web.UI.Client/src/less/main.less +++ b/src/Umbraco.Web.UI.Client/src/less/main.less @@ -23,7 +23,7 @@ margin-top: 0px; margin-bottom: 15px; font-size: 14px; - color: @gray-7; + color: @gray-7; } h5{ @@ -134,7 +134,7 @@ h5.-black { padding-bottom: 0; } -.block-form .umb-control-group label .help-block, +.block-form .umb-control-group label .help-block, .block-form .umb-control-group label small { font-size: 13px; padding-top: 2px; @@ -243,9 +243,9 @@ label:not([for]) { } .umb-version { - color: @gray-7; - position: absolute; - bottom: 5px; + color: @gray-7; + position: absolute; + bottom: 5px; right: 20px; } @@ -653,3 +653,14 @@ input[type=checkbox]:checked + .input-label--small { .bootstrap-datetimepicker-widget td span { border-radius: 0 !important; } + +.visuallyhidden{ + position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + padding:0 !important; + border:0 !important; + height: 1px !important; + width: 1px !important; + overflow: hidden; +} diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index e9f4acd120..0a3807e7e6 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -102,11 +102,11 @@ div.umb-codeeditor { border: 1px solid @gray-8; } div.umb-codeeditor .umb-el-wrap { - padding: 0px; + padding: 0; } div.umb-codeeditor .umb-btn-toolbar { - padding: 0px; - margin: 0px; + padding: 0; + margin: 0; border-bottom: @gray-8 1px solid; background: @gray-10; } @@ -122,7 +122,7 @@ div.umb-codeeditor .umb-btn-toolbar { position: absolute; } } -.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0px !important;} +.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0 !important;} .mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;} .mce-btn-group, .mce-btn{border: none !important; background: none !important;} .mce-ico{font-size: 12px !important; color: @gray-1 !important;} @@ -203,7 +203,7 @@ div.umb-codeeditor .umb-btn-toolbar { } label { - border: 1px solid #fff; + border: 1px solid @white; padding: 6px 10px; font-family: monospace; border: 1px solid #dfdfe1; @@ -213,6 +213,99 @@ div.umb-codeeditor .umb-btn-toolbar { } } +// +// Image Cropper +// -------------------------------------------------- + +.umb-prevalues-multivalues.umb-cropsizes{ + max-width: none; + width: 100%; + + .umb-overlay__form &{ + width: 100%; + } +} + +.umb-cropsizes{ + float: left; + + .control-group{ + label{ + display: block; + } + } + + &__add{ + display: flex; + align-items: center; + flex-wrap: wrap; + } + + &__sortable{ + max-width: 500px; + width: 100%; + min-width: 66.6%; + + @media (min-width: 1101px) and (max-width: 1300px), (max-width: 930px){ + max-width: none; + } + } + + &__controls{ + margin: 24px 0 0; + } + + &__input{ + margin: 0 15px 0 0; + width: ~"calc(100% - 15px)"; + + @media (min-width: 1101px) and (max-width: 1300px), (max-width: 930px){ + margin: 0; + width: 100%; + max-width: 220px; + } + + &--narrow{ + max-width: 95px; + width: 100%; + } + + &-wrap{ + position: relative; + max-width: 206px; + width: 100%; + + @media (min-width: 1101px) and (max-width: 1300px), (max-width: 930px){ + max-width: none; + flex: 1 1 100%; + margin: 0 0 20px; + } + + &--narrow{ + margin: 0 15px 0 0; + max-width: 95px; + width: 100%; + } + + &--icon{ + padding: 0 15px 0 0; + width: ~"calc(100% + 15px)"; // Use an escape string in order to make use of CSS native calc function instead of the one built into less + + &:after{ + content:"\00D7"; + position: absolute; + bottom: -9px; + top: 0; + margin: auto; + right: 0; + width: 5px; + height: 5px; + } + } + } + } +} + // // Media picker @@ -719,8 +812,8 @@ div.umb-codeeditor .umb-btn-toolbar { .umb-photo-folder .picrow div, .umb-photo-preview{ - margin: 0px; - padding: 0px; + margin: 0; + padding: 0; border: none; display: inline-block; vertical-align: top; @@ -757,9 +850,9 @@ div.umb-codeeditor .umb-btn-toolbar { //this is a temp hack, to provide selectors in the dialog: .umb-photo-folder .pic:hover .selector-overlay { position: absolute; - bottom: 0px; - left: 0px; - right: 0px; + bottom: 0; + left: 0; + right: 0; padding: 5px; background: @black; z-index: 100; @@ -839,7 +932,7 @@ div.umb-codeeditor .umb-btn-toolbar { .umb-fileupload ul { list-style: none; vertical-align: middle; - margin-bottom: 0px; + margin-bottom: 0; } .umb-fileupload label { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js index 3a99c90a50..5a0b43d105 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.controller.js @@ -1,10 +1,13 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesController", - function ($scope, $timeout) { + function ($scope) { if (!$scope.model.value) { $scope.model.value = []; } + $scope.editMode = false; + $scope.setFocus = false; + $scope.remove = function (item, evt) { evt.preventDefault(); $scope.model.value = _.reject($scope.model.value, function (x) { @@ -13,32 +16,57 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesControlle }; $scope.edit = function (item, evt) { - evt.preventDefault(); + evt.preventDefault(); + $scope.editMode = true; + $scope.setFocus = false; + $scope.newItem = item; }; $scope.cancel = function (evt) { - evt.preventDefault(); + evt.preventDefault(); + $scope.editMode = false; + $scope.setFocus = true; + $scope.newItem = null; }; - $scope.add = function (evt) { - evt.preventDefault(); + $scope.change = function () { + // Listen to the change event and set focus 2 false + if($scope.setFocus){ + $scope.setFocus = false; + return; + } + } - if ($scope.newItem && $scope.newItem.alias && + $scope.add = function (evt) { + evt.preventDefault(); + + $scope.editMode = false; + + $scope.setFocus = true; + + if ($scope.newItem && $scope.newItem.alias && angular.isNumber($scope.newItem.width) && angular.isNumber($scope.newItem.height) && $scope.newItem.width > 0 && $scope.newItem.height > 0) { - var exists = _.find($scope.model.value, function (item) { return $scope.newItem.alias === item.alias; }); + var exists = _.find($scope.model.value, function (item) { return $scope.newItem.alias === item.alias; }); + if (!exists) { $scope.model.value.push($scope.newItem); $scope.newItem = {}; - $scope.hasError = false; + $scope.hasError = false; + $scope.cropAdded = false; return; - } + } + else{ + $scope.newItem = null; + $scope.hasError = false; + return; + } } //there was an error, do the highlight (will be set back by the directive) $scope.hasError = true; - }; - }); \ No newline at end of file + }; + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html index 62a5565d95..0be82ff52f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.prevalues.html @@ -1,49 +1,74 @@ -
      +
      +
      -
      -
        -
      • - - +
        + + +
        + +
        + + +
        + +
        + + +
        + +
        + + + Cancel +
        - {{node.alias}} -
        {{node.width}}px × {{node.height}}px -
      • -
      -
      -

      Define crop

      -

      - Give the crop an alias and it's default width and height. -

      - -
      - - +
      +
      + +
      +

      {{item.alias}} ({{item.width}}px × {{item.height}}px)

      +
      +
      + Edit + Remove +
      - -
      - - - × - -
      - -
      - - Cancel -
      -
      - -
      -
      diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index af8c302aff..5b14e03fae 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1304,8 +1304,6 @@ To manage your website, simply open the Umbraco back office and start adding con Reset crop - Define crop - Give the crop an alias and its default width and height Save crop Add new crop Done diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 5355928f17..791fc315ee 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -1302,8 +1302,6 @@ To manage your website, simply open the Umbraco back office and start adding con Reset crop - Define crop - Give the crop an alias and its default width and height Save crop Add new crop Done diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/es.xml b/src/Umbraco.Web.UI/umbraco/config/lang/es.xml index fed40e2d79..a41d17604b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/es.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/es.xml @@ -1039,8 +1039,6 @@ Reiniciar - Definir corte - Da al corte un alias y su anchura y altura por defecto Guardar corte Añadir nuevo corte diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml index b3d5edf512..7d20714ab6 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml @@ -1286,7 +1286,6 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Réinitialiser Définir le recadrage - Donnez un alias au recadrage ainsi que sa largeur et sa hauteur par défaut Sauvegarder le recadrage Ajouter un nouveau recadrage diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml index 98759d5851..9affa43727 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml @@ -1022,8 +1022,6 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Resetuj - Zdefiniuj przycięcie - Ustaw alias dla przycięcia, a także jego domyślną szerokość i długość Zapisz przycięcie Dodaj nowe przycięcie diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml index 8ebe8c0ef7..8e98566687 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml @@ -879,8 +879,6 @@ Сбросить - Задать рамку - Задайте рамке имя (алиас), а также ширину и высоту по-умолчанию Сохранить рамку Добавить новую рамку diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml index d011f7dadb..982f31e383 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml @@ -645,8 +645,6 @@ Återställ - Definiera beskräning - Ge beskärningen ett alias och dess standardbredd och -höjd spara beskärning Lägg till ny beskärning diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml index c2189ca928..a918b78f95 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml @@ -999,8 +999,6 @@ Reset - Define crop - Give the crop an alias and its default width and height Save crop Add new crop diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index 5196fda0ee..3d6a1727e4 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -229,7 +229,7 @@ namespace Umbraco.Web.PropertyEditors internal class ImageCropperPreValueEditor : PreValueEditor { - [PreValueField("crops", "Crop sizes", "views/propertyeditors/imagecropper/imagecropper.prevalues.html")] + [PreValueField("crops", "Define crops", "views/propertyeditors/imagecropper/imagecropper.prevalues.html", Description = "Give the crop an alias and it's default width and height")] public string Crops { get; set; } } From 1053a349f6ea2ebcd7421dbd37af9cbdc8f715f6 Mon Sep 17 00:00:00 2001 From: agrath Date: Wed, 24 Oct 2018 03:48:19 +1300 Subject: [PATCH 053/337] #3231 RTE editor in grid collapsed on tab shown (#3232) --- .../components/grid/grid.rte.directive.js | 15 ++++++++++++--- .../directives/validation/valtab.directive.js | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js index e18137085b..5a68d36bc1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js @@ -1,5 +1,5 @@ angular.module("umbraco.directives") - .directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout) { + .directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout, eventsService) { return { scope: { uniqueId: '=', @@ -362,8 +362,16 @@ angular.module("umbraco.directives") // tinyMceEditor.fire('LoadContent', null); //}; + + var tabShownListener = eventsService.on("valTab.tabShown", function (e, args) { + //the tab has been shown, trigger the mceAutoResize (as it could have timed out before the tab was shown) + if (tinyMceEditor !== undefined && tinyMceEditor != null) { + tinyMceEditor.execCommand('mceAutoResize', false, null, null); + } + }); + //listen for formSubmitting event (the result is callback used to remove the event subscription) - var unsubscribe = scope.$on("formSubmitting", function () { + var formSubmittingListener = scope.$on("formSubmitting", function () { //TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer // we do parse it out on the server side but would be nice to do that on the client side before as well. scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null; @@ -373,7 +381,8 @@ angular.module("umbraco.directives") // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom // element might still be there even after the modal has been hidden. scope.$on('$destroy', function () { - unsubscribe(); + formSubmittingListener(); + eventsService.unsubscribe(tabShownListener); if (tinyMceEditor !== undefined && tinyMceEditor != null) { tinyMceEditor.destroy() } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js index 8d1fc60083..c5d7cb6e58 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtab.directive.js @@ -6,15 +6,15 @@ * @description Used to show validation warnings for a tab to indicate that the tab content has validations errors in its data. * In order for this directive to work, the valFormManager directive must be placed on the containing form. **/ -function valTab() { +function valTab(eventsService) { return { require: ['^form', '^valFormManager'], restrict: "A", link: function (scope, element, attr, ctrs) { var valFormManager = ctrs[1]; - var tabId = "tab" + scope.tab.id; - scope.tabHasError = false; + var tabId = "tab" + scope.tab.id; + scope.tabHasError = false; //listen for form validation changes valFormManager.onValidationStatusChanged(function (evt, args) { @@ -31,8 +31,17 @@ function valTab() { scope.tabHasError = false; } }); + var tabShownFunc = function (e) { + var tabContent = element.closest(".umb-panel").find("#" + tabId); + eventsService.emit('valTab.tabShown', { originalEvent: e, tab: scope.tab, content: tabContent }); + }; + var anchorElement = element.find("a[data-toggle='tab']"); + anchorElement.on('shown.bs.tab', tabShownFunc); + scope.$on('$destroy', function () { + anchorElement.off('shown.bs.tab', tabShownFunc); + }); } }; } -angular.module('umbraco.directives.validation').directive("valTab", valTab); \ No newline at end of file +angular.module('umbraco.directives.validation').directive("valTab", valTab); From 20c215ef8ca6831b94c1aae08f83e31e9fad7b30 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Tue, 23 Oct 2018 16:52:57 +0200 Subject: [PATCH 054/337] #3211 - Add colorpicker prevalue editor (#3212) --- .../less/components/umb-color-swatches.less | 14 ++-- .../views/components/umb-color-swatches.html | 2 +- .../prevalueeditors/colorpicker.controller.js | 64 +++++++++++++++++++ .../views/prevalueeditors/colorpicker.html | 18 ++++++ 4 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less index 43e62780a3..26a735508e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less @@ -42,8 +42,8 @@ &.with-labels { .umb-color-box { - width: 120px; - height: 100%; + width: 130px; + height: auto; display: flex; flex-flow: row wrap; @@ -53,15 +53,21 @@ flex: 0 0 100%; max-width: 100%; min-height: 80px; - padding-top: 10px; + padding: 0; + + .check_circle { + margin: 15px auto; + } .umb-color-box__label { background: @white; font-size: 14px; display: flex; flex-flow: column wrap; - flex: 0 0 100%; + flex: 1 0 100%; + justify-content: flex-end; padding: 1px 5px; + min-height: 45px; max-width: 100%; margin-top: auto; margin-bottom: -3px; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html index 2bc7ce9622..3e92f5c18c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html @@ -6,7 +6,7 @@
      -
      {{ color.label }}
      +
      {{ color.label || color.value }}
      #{{ color.value }}
      diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js new file mode 100644 index 0000000000..c588893d7c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js @@ -0,0 +1,64 @@ +angular.module("umbraco").controller("Umbraco.PrevalueEditors.ColorPickerController", + function ($scope) { + + //setup the default config + var config = { + useLabel: false + }; + + //map the user config + angular.extend(config, $scope.model.config); + + //map back to the model + $scope.model.config = config; + + $scope.isConfigured = $scope.model.prevalues && _.keys($scope.model.prevalues).length > 0; + + $scope.model.items = []; + + // Make an array from the dictionary + var items = []; + + if (angular.isArray($scope.model.prevalues)) { + + for (var i in $scope.model.prevalues) { + var oldValue = $scope.model.prevalues[i]; + + if (!isValidHex(oldValue.value || oldValue)) + continue; + + if (oldValue.hasOwnProperty("value")) { + var hexCode = toFullHex(oldValue.value); + items.push({ + value: hexCode.substr(1, hexCode.length), + label: oldValue.label, + id: i + }); + } else { + var hexCode = toFullHex(oldValue); + items.push({ + value: hexCode.substr(1, hexCode.length), + label: oldValue, + id: i + }); + } + } + + // Now make the editor model the array + $scope.model.items = items; + } + + function toFullHex(hex) { + if (hex.length === 4 && hex.charAt(0) === "#") { + hex = "#" + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2) + hex.charAt(3) + hex.charAt(3); + } + return hex.toLowerCase(); + } + + function isValidHex(str) { + console.log("str", str); + console.log("test", /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str)); + return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str); + } + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html new file mode 100644 index 0000000000..b5f77269b8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html @@ -0,0 +1,18 @@ +
      + +
      + You haven't defined any colors +
      + + + + + {{model.items | json}} +

      + {{model.value}} + + +
      From 79e3a35869fcc8bb591b9dd4b148e5a8c1d9e98d Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 23 Oct 2018 16:03:49 +0100 Subject: [PATCH 055/337] WIP - Ensures the default language variant is always first then the rest of the variants are organised by A-Z --- .../Mapping/ContentItemDisplayVariationResolver.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs index a627eab184..562797e3e3 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs @@ -52,6 +52,18 @@ namespace Umbraco.Web.Models.Mapping variant.Name = source.GetCultureName(x.IsoCode); } + //Put the default language first in the list & then sort rest by a-z + var defaultLang = variants.SingleOrDefault(x => x.Language.IsDefault); + + //Remove the default lang from the list for now + variants.Remove(defaultLang); + + //Sort the remaining languages a-z + variants.OrderBy(x => x.Language.Name); + + //Insert the default lang as the first item + variants.Insert(0, defaultLang); + return variants; } return result; From 9230de5383adc2c0bbd4af940d03abe887729c71 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Tue, 23 Oct 2018 17:06:10 +0200 Subject: [PATCH 056/337] 3225 - Suggestion: Style the default browser radio button as a custom one to provide a nicer UI experience (#3226) --- src/Umbraco.Web.UI.Client/src/less/belle.less | 1 + .../components/umb-radiobuttons-list.less | 80 +++++++++++++++++++ .../radiobuttons/radiobuttons.html | 13 ++- 3 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index 7f10c3d4d7..9b9be85053 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -101,6 +101,7 @@ @import "components/umb-confirm-action.less"; @import "components/umb-keyboard-shortcuts-overview.less"; @import "components/umb-checkbox-list.less"; +@import "components/umb-radiobuttons-list.less"; @import "components/umb-locked-field.less"; @import "components/umb-tabs.less"; @import "components/umb-load-indicator.less"; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less new file mode 100644 index 0000000000..2fe3487a8f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less @@ -0,0 +1,80 @@ +.umb-radiobuttons{ + &__label{ + position: relative; + padding: 0; + + &-text{ + margin: 0 0 0 32px; + position: relative; + top: 1px; + } + } + + &__input{ + position: absolute; + top: 0; + left: 0; + opacity: 0; + + &:focus ~ .umb-radiobuttons__state{ + box-shadow: 0 1px 3px fade(@black, 12%), 0 1px 2px fade(@black, 24%); + } + + &:focus:checked ~ .umb-radiobuttons__state{ + box-shadow: none; + } + + &:checked ~ .umb-radiobuttons__state{ + &:before{ + width: 100%; + height: 100%; + } + } + + &:checked ~ .umb-radiobuttons__state .umb-radiobuttons__icon{ + opacity: 1; + } + } + + &__state{ + display: flex; + flex-wrap: wrap; + border: 1px solid @gray-8; + border-radius: 100%; + width: 22px; + height: 22px; + position: relative; + + &:before{ + content: ""; + background: @green; + width: 0; + height: 0; + transition: .1s ease-out; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + border-radius: 100%; + } + } + + &__icon{ + color: @white; + text-align: center; + font-size: 15px; + opacity: 0; + transition: .3s ease-out; + + &:before{ + position: absolute; + top: 2px; + right: 0; + left: 0; + bottom: 0; + margin: auto; + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html index cdb5a37ac8..7af6491641 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html @@ -1,12 +1,17 @@ 
      • -
      -
      \ No newline at end of file +
      From 3e14da5e9db70b9fdf7c61209f71c94194874671 Mon Sep 17 00:00:00 2001 From: KimHolzmann Date: Tue, 23 Oct 2018 18:16:06 +0200 Subject: [PATCH 057/337] #2927 - Cannot use content templates in list views (#3173) --- .../listview/listview.controller.js | 44 +++++++++- .../propertyeditors/listview/listview.html | 82 +++++++++++++++---- 2 files changed, 109 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 272627dc7b..b335354bc4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -58,6 +58,11 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie items: [] }; + $scope.createAllowedButtonSingle = false; + $scope.createAllowedButtonSingleWithBlueprints = false; + $scope.createAllowedButtonMultiWithBlueprints = false; + + //when this is null, we don't check permissions $scope.currentNodePermissions = null; @@ -598,7 +603,28 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie id = -1; } - $scope.listViewAllowedTypes = getContentTypesCallback(id); + //$scope.listViewAllowedTypes = getContentTypesCallback(id); + getContentTypesCallback(id).then(function (listViewAllowedTypes) { + var blueprints = false; + $scope.listViewAllowedTypes = listViewAllowedTypes; + + angular.forEach(listViewAllowedTypes, function (allowedType) { + angular.forEach(allowedType.blueprints, function (value, key) { + blueprints = true; + }); + }); + + if (listViewAllowedTypes.length === 1 && blueprints === false) { + $scope.createAllowedButtonSingle = true; + } + if (listViewAllowedTypes.length === 1 && blueprints === true) { + $scope.createAllowedButtonSingleWithBlueprints = true; + } + if (listViewAllowedTypes.length > 1) { + $scope.createAllowedButtonMultiWithBlueprints = true; + } + }); + $scope.contentId = id; $scope.isTrashed = id === "-20" || id === "-21"; @@ -650,6 +676,22 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie } } + + function createBlank(entityType,docTypeAlias) { + $location + .path("/" + entityType + "/" + entityType + "/edit/" + $scope.contentId) + .search("doctype=" + docTypeAlias + "&create=true"); + } + + function createFromBlueprint(entityType,docTypeAlias, blueprintId) { + $location + .path("/" + entityType + "/" + entityType + "/edit/" + $scope.contentId) + .search("doctype=" + docTypeAlias + "&create=true&blueprintId=" + blueprintId); + } + + $scope.createBlank = createBlank; + $scope.createFromBlueprint = createFromBlueprint; + //GO! initView(); } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html index 2683317dc1..cdd7e9cab2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html @@ -11,35 +11,85 @@ -
      + + + + + + - + + + + + + + + - + From ee3cbf08a254dfb7111caf7d65b2b6ce68cb6663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Kottal?= Date: Tue, 23 Oct 2018 22:43:46 +0200 Subject: [PATCH 058/337] #3215 Adds ability to create template from doctype editor (#3366) ### Prerequisites - [x] I have [created an issue](https://github.com/umbraco/Umbraco-CMS/issues) for the proposed changes in this PR, the link is: #3215 - [x] I have added steps to test this contribution in the description below ### Description I added a button for creating a new template in the template view of the doctype editor. The button uses the template resource to fetch a template scaffold, and then save a new template. After saving, the template gets selected as allowed, and if there is no default template selected, the new template will also be the default. https://i.imgur.com/KQbmjGH.gifv --- .../views/templates/templates.controller.js | 45 +++++++++++++++---- .../views/templates/templates.html | 5 +++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js index fe1b0f0e7e..3ce795b01e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.controller.js @@ -9,7 +9,7 @@ (function() { 'use strict'; - function TemplatesController($scope, entityResource, contentTypeHelper, $routeParams) { + function TemplatesController($scope, entityResource, contentTypeHelper, templateResource, $routeParams) { /* ----------- SCOPE VARIABLES ----------- */ @@ -21,24 +21,53 @@ /* ---------- INIT ---------- */ - init(); + init(function () { - function init() { + // update placeholder template information on new doc types + if (!$routeParams.notemplate && $scope.model.id === 0) { + vm.updateTemplatePlaceholder = true; + vm.availableTemplates = contentTypeHelper.insertTemplatePlaceholder(vm.availableTemplates); + } + }); + + function init(callback) { entityResource.getAll("Template").then(function(templates){ vm.availableTemplates = templates; - // update placeholder template information on new doc types - if (!$routeParams.notemplate && $scope.model.id === 0) { - vm.updateTemplatePlaceholder = true; - vm.availableTemplates = contentTypeHelper.insertTemplatePlaceholder(vm.availableTemplates); - } + callback(); }); } + vm.createTemplate = function () { + templateResource.getScaffold(-1).then(function (template) { + + template.alias = $scope.model.alias; + template.name = $scope.model.name; + + templateResource.save(template).then(function (savedTemplate) { + + init(function () { + + var newTemplate = vm.availableTemplates.filter(function (t) { return t.id === savedTemplate.id }); + if (newTemplate.length > 0) { + $scope.model.allowedTemplates.push(newTemplate[0]); + + if ($scope.model.defaultTemplate === null) { + $scope.model.defaultTemplate = newTemplate[0]; + } + } + + }); + + }); + + }); + } + } angular.module("umbraco").controller("Umbraco.Editors.DocumentType.TemplatesController", TemplatesController); diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html index a1385102e4..c02bb78de7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html @@ -16,6 +16,11 @@ alias="model.alias" update-placeholder="vm.updateTemplatePlaceholder"> + +
      From 5f765967a6f9adf3b735c32fa8bac9f79558951d Mon Sep 17 00:00:00 2001 From: skoomasteve <43890114+skoomasteve@users.noreply.github.com> Date: Tue, 23 Oct 2018 15:47:14 -0500 Subject: [PATCH 059/337] Just a few spelling fixes. (#3405) --- build.bat | 2 +- src/umbraco.providers/members/UmbracoMembershipProvider.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.bat b/build.bat index 29a5e07a5a..3cab9283cf 100644 --- a/build.bat +++ b/build.bat @@ -9,6 +9,6 @@ IF ERRORLEVEL 1 ( :error ECHO. -ECHO Can not run build\build.ps1. +ECHO Cannot run build\build.ps1. ECHO If this is due to a SecurityError then please refer to BUILD.md for help! ECHO. diff --git a/src/umbraco.providers/members/UmbracoMembershipProvider.cs b/src/umbraco.providers/members/UmbracoMembershipProvider.cs index 648bf5a0d5..ff6895fe20 100644 --- a/src/umbraco.providers/members/UmbracoMembershipProvider.cs +++ b/src/umbraco.providers/members/UmbracoMembershipProvider.cs @@ -30,7 +30,7 @@ namespace umbraco.providers.members /// /// Custom Membership Provider for Umbraco Members (User authentication for Frontend applications NOT umbraco CMS) /// - [Obsolete("This has been superceded by Umbraco.Web.Security.Providers.MembersMembershipProvider")] + [Obsolete("This has been superseded by Umbraco.Web.Security.Providers.MembersMembershipProvider")] public class UmbracoMembershipProvider : UmbracoMembershipProviderBase, IUmbracoMemberTypeMembershipProvider { public UmbracoMembershipProvider() @@ -111,7 +111,7 @@ namespace umbraco.providers.members /// The name of the provider has a length of zero. public override void Initialize(string name, NameValueCollection config) { - // Intialize values from web.config + // Initialize values from web.config if (config == null) throw new ArgumentNullException("config"); if (string.IsNullOrEmpty(name)) name = Constants.Conventions.Member.UmbracoMemberProviderName; @@ -189,7 +189,7 @@ namespace umbraco.providers.members /// protected override bool PerformChangePassword(string username, string oldPassword, string newPassword) { - //NOTE: due to backwards compatibilty reasons, this provider doesn't care about the old password and + //NOTE: due to backwards compatibility reasons, this provider doesn't care about the old password and // allows simply setting the password manually so we don't really care about the old password. // This is allowed based on the overridden AllowManuallyChangingPassword option. From f69976852e6b8d19cfcfef44132004d7307b44df Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 23 Oct 2018 22:49:13 +0200 Subject: [PATCH 060/337] Disable move/copy button until a target node is selected (#3250) --- src/Umbraco.Web.UI.Client/src/views/content/copy.html | 4 ++-- src/Umbraco.Web.UI.Client/src/views/content/move.html | 6 +++--- src/Umbraco.Web.UI.Client/src/views/datatypes/move.html | 4 ++-- src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html | 4 ++-- src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html | 4 ++-- .../src/views/media/media.move.controller.js | 4 +++- src/Umbraco.Web.UI.Client/src/views/media/move.html | 4 ++-- src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html | 4 ++-- src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html | 4 ++-- 9 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/content/copy.html b/src/Umbraco.Web.UI.Client/src/views/content/copy.html index e02855ea8f..62116a3e6e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/copy.html @@ -83,10 +83,10 @@
    diff --git a/src/Umbraco.Web.UI.Client/src/views/content/move.html b/src/Umbraco.Web.UI.Client/src/views/content/move.html index f7978e01a5..09116a2a6d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/move.html @@ -73,11 +73,11 @@ -
\ No newline at end of file +
diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html index 0546cbff44..77746a5f42 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html @@ -44,10 +44,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html index 97de821909..c9c4962da7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html @@ -44,10 +44,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html index 0af4cbfda7..58d897e91c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html @@ -44,10 +44,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js index 02cb3a363a..77e59cbbfa 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js @@ -49,8 +49,10 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); $scope.move = function () { + $scope.busy = true; mediaResource.move({ parentId: $scope.target.id, id: node.id }) .then(function (path) { + $scope.busy = false; $scope.error = false; $scope.success = true; @@ -97,4 +99,4 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.miniListView = node; } - }); \ No newline at end of file + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/media/move.html b/src/Umbraco.Web.UI.Client/src/views/media/move.html index b37b71b639..88c64f1992 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/move.html @@ -49,7 +49,7 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html index 77f50358c3..ddb2559ba2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html @@ -44,10 +44,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html index c240925a7d..5dbac09147 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html @@ -44,10 +44,10 @@ From 9704c124eda16a4c2ffff869007c54b1ec498802 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 15:20:28 +1100 Subject: [PATCH 061/337] Removes all old deprecated drop down editors, we only have one drop down editor now and it doesn't store IDs either in the db or in the cache, it just stores what is selected --- src/Umbraco.Core/Constants-PropertyEditors.cs | 20 --- .../Migrations/Install/DatabaseDataCreator.cs | 2 +- .../Migrations/Upgrade/UmbracoPlan.cs | 2 + .../Upgrade/V_8_0_0/DataTypeMigration.cs | 7 +- .../DropDownPropertyEditorsMigration.cs | 145 ++++++++++++++++++ .../Upgrade/V_8_0_0/DropPreValueTable.cs | 15 ++ .../DropdownListMultipleValueConverter.cs | 33 ---- ...pdownListMultipleWithKeysValueConverter.cs | 34 ---- .../DropdownListValueConverter.cs | 23 --- .../DropdownListWithKeysValueConverter.cs | 27 ---- src/Umbraco.Core/Umbraco.Core.csproj | 6 +- .../MultiValuePropertyEditorTests.cs | 27 +--- .../PropertyEditorValueConverterTests.cs | 41 ++--- .../Entities/MockedContentTypes.cs | 11 +- .../CheckBoxListPropertyEditor.cs | 2 +- .../DropDownFlexiblePropertyEditor.cs | 2 +- .../DropDownMultipleConfigurationEditor.cs | 73 --------- .../DropDownMultiplePropertyEditor.cs | 30 ---- .../DropDownMultipleWithKeysPropertyEditor.cs | 37 ----- .../PropertyEditors/DropDownPropertyEditor.cs | 37 ----- .../DropDownWithKeysPropertyEditor.cs | 36 ----- .../PublishValueValueEditor.cs | 57 ------- .../PublishValuesMultipleValueEditor.cs | 55 +------ .../RadioButtonsPropertyEditor.cs | 21 ++- .../FlexibleDropdownPropertyValueConverter.cs | 4 +- src/Umbraco.Web/Umbraco.Web.csproj | 6 - 26 files changed, 225 insertions(+), 528 deletions(-) create mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs create mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs index 126613cdb3..b09987ad90 100644 --- a/src/Umbraco.Core/Constants-PropertyEditors.cs +++ b/src/Umbraco.Core/Constants-PropertyEditors.cs @@ -44,26 +44,6 @@ namespace Umbraco.Core /// public const string DateTime = "Umbraco.DateTime"; - /// - /// DropDown List. - /// - public const string DropDownList = "Umbraco.DropDown"; - - /// - /// DropDown List, Publish Keys. - /// - public const string DropdownlistPublishKeys = "Umbraco.DropdownlistPublishingKeys"; - - /// - /// DropDown List Multiple. - /// - public const string DropDownListMultiple = "Umbraco.DropDownMultiple"; - - /// - /// DropDown List Multiple, Publish Keys. - /// - public const string DropdownlistMultiplePublishKeys = "Umbraco.DropdownlistMultiplePublishKeys"; - /// /// DropDown List. /// diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index c4ebfb664b..eb7cafcb01 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -117,7 +117,7 @@ namespace Umbraco.Core.Migrations.Install _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = new Guid("bb5f57c9-ce2b-4bb9-b697-4caca783a805"), Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -39, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-39", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index 5b0838573e..9ad7ccb48e 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -138,6 +138,8 @@ namespace Umbraco.Core.Migrations.Upgrade Chain("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}"); Chain("{77874C77-93E5-4488-A404-A630907CEEF0}"); + Chain("{23275462-446E-44C7-8C2C-3B8C1127B07D}"); + Chain("{6B251841-3069-4AD5-8AE9-861F9523E8DA}"); //FINAL diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs index eb39f37112..d7180385f0 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs @@ -7,10 +7,11 @@ using NPoco; using Umbraco.Core.Migrations.Install; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 { + public class DataTypeMigration : MigrationBase { public DataTypeMigration(IMigrationContext context) @@ -79,10 +80,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 Database.Update(dataType); } - - // drop preValues table - // FIXME keep it around for now - //Delete.Table("cmsDataTypePreValues"); } [TableName("cmsDataTypePreValues")] diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs new file mode 100644 index 0000000000..c9eba205e8 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Dtos; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Logging; + +namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 +{ + public class DropDownPropertyEditorsMigration : MigrationBase + { + public DropDownPropertyEditorsMigration(IMigrationContext context) : base(context) + { + } + + public override void Migrate() + { + //need to convert the old drop down data types to use the new one + var oldDropDowns = Database.Fetch(Sql().Select().Where(x => x.EditorAlias.Contains(".DropDown"))); + foreach(var dd in oldDropDowns) + { + //nothing to change if there is no config + if (dd.Configuration.IsNullOrWhiteSpace()) continue; + + ValueListConfiguration config; + try + { + config = JsonConvert.DeserializeObject(dd.Configuration); + } + catch (Exception ex) + { + Logger.Error(ex, $"Invalid drop down configuration detected: \"{dd.Configuration}\", cannot convert editor, values will be cleared"); + dd.Configuration = null; + Database.Update(dd); + continue; + } + + var propDataSql = Sql().Select("*").From() + .InnerJoin().On(x => x.Id, x => x.PropertyTypeId) + .InnerJoin().On(x => x.NodeId, x => x.DataTypeId) + .Where(x => x.EditorAlias == dd.EditorAlias); + + var propDatas = Database.Query(propDataSql); + var toUpdate = new List(); + foreach (var propData in propDatas) + { + if (UpdatePropertyDataDto(propData, config)) + { + //update later, we are iterating all values right now so no SQL can be run inside of this iteration (i.e. Query) + toUpdate.Add(propData); + } + } + + //run the property data updates + foreach(var propData in toUpdate) + { + Database.Update(propData); + } + + var requiresCacheRebuild = false; + switch (dd.EditorAlias) + { + case "Umbraco.DropDown": + UpdateDataType(dd, config, false); + break; + case "Umbraco.DropdownlistPublishingKeys": + UpdateDataType(dd, config, false); + requiresCacheRebuild = true; + break; + case "Umbraco.DropDownMultiple": + UpdateDataType(dd, config, false); + break; + case "Umbraco.DropdownlistMultiplePublishKeys": + UpdateDataType(dd, config, true); + requiresCacheRebuild = true; + break; + } + + if (requiresCacheRebuild) + { + //TODO: How to force rebuild the cache? + } + } + } + + private void UpdateDataType(DataTypeDto dataType, ValueListConfiguration config, bool isMultiple) + { + dataType.EditorAlias = Constants.PropertyEditors.Aliases.DropDownListFlexible; + var flexConfig = new + { + multiple = isMultiple, + items = config.Items + }; + dataType.Configuration = JsonConvert.SerializeObject(flexConfig); + } + + private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config) + { + //Get the INT ids stored for this property/drop down + IEnumerable ids = null; + if (!propData.VarcharValue.IsNullOrWhiteSpace()) + { + ids = ConvertStringValues(propData.VarcharValue); + } + else if (!propData.TextValue.IsNullOrWhiteSpace()) + { + ids = ConvertStringValues(propData.TextValue); + } + else if (propData.IntegerValue.HasValue) + { + ids = new[] { propData.IntegerValue.Value }; + } + + //if there are INT ids, convert them to values based on the configured pre-values + if (ids != null) + { + //map the ids to values + var vals = new List(); + foreach (var id in ids) + { + var val = config.Items.FirstOrDefault(x => x.Id == id); + if (val != null) + vals.Add(val.Value); + } + + propData.VarcharValue = string.Join(",", vals); + propData.TextValue = null; + propData.IntegerValue = null; + return true; + } + + return false; + } + + private IEnumerable ConvertStringValues(string val) + { + return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(x => int.TryParse(x, out var i) ? i : int.MinValue) + .Where(x => x != int.MinValue); + } + + } +} diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs new file mode 100644 index 0000000000..26402cc477 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs @@ -0,0 +1,15 @@ +namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 +{ + public class DropPreValueTable : MigrationBase + { + public DropPreValueTable(IMigrationContext context) : base(context) + { + } + + public override void Migrate() + { + // drop preValues table + Delete.Table("cmsDataTypePreValues").Do(); + } + } +} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs deleted file mode 100644 index d91f45292c..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListMultipleValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropDownListMultiple); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (IEnumerable); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel cacheLevel, object source, bool preview) - { - var sourceString = (source ?? "").ToString(); - - if (string.IsNullOrEmpty(sourceString)) - return Enumerable.Empty(); - - var values = - sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()); - - return values; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs deleted file mode 100644 index bceebc232b..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListMultipleWithKeysValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropdownlistMultiplePublishKeys); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (IEnumerable); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) - { - if (source == null) - return new int[] { }; - - var prevalueIds = source.ToString() - .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) - .Select(p => p.Trim()) - .Select(int.Parse) - .ToArray(); - - return prevalueIds; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs deleted file mode 100644 index 5fe1967f32..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropDownList); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (string); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) - { - return source?.ToString() ?? string.Empty; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs deleted file mode 100644 index 960cd4afa6..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListWithKeysValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropdownlistPublishKeys); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (int); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) - { - var intAttempt = source.TryConvertTo(); - if (intAttempt.Success) - return intAttempt.Result; - - return null; - } - } -} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 6951a9e17a..4d4bbb32e2 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -356,6 +356,8 @@ + + @@ -1239,10 +1241,6 @@ - - - - diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index 9ba5ccf6f2..129116bf61 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -21,28 +21,15 @@ namespace Umbraco.Tests.PropertyEditors /// Tests for the base classes of ValueEditors and PreValueEditors that are used for Property Editors that edit /// multiple values such as the drop down list, check box list, color picker, etc.... /// + /// + /// Mostly this used to test the we'd store INT Ids in the Db but publish STRING values or sometimes the INT values + /// to cache. Now we always just deal with strings and we'll keep the tests that show that. + /// [TestFixture] public class MultiValuePropertyEditorTests { - //TODO: Test the other formatting methods for the drop down classes - [Test] - public void DropDownMultipleValueEditor_With_Keys_Format_Data_For_Cache() - { - var dataTypeServiceMock = new Mock(); - var editor = new PublishValuesMultipleValueEditor(true, Mock.Of(), new DataEditorAttribute("key", "nam", "view")); - - var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())); - var prop = new Property(1, new PropertyType(dataType)); - prop.SetValue("1234,4567,8910"); - - var result = editor.ConvertDbToString(prop.PropertyType, prop.GetValue(), new Mock().Object); - - Assert.AreEqual("1234,4567,8910", result); - } - - [Test] - public void DropDownMultipleValueEditor_No_Keys_Format_Data_For_Cache() + public void DropDownMultipleValueEditor_Format_Data_For_Cache() { var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())) { @@ -61,7 +48,7 @@ namespace Umbraco.Tests.PropertyEditors var dataTypeService = new TestObjects.TestDataTypeService(dataType); var prop = new Property(1, new PropertyType(dataType)); - prop.SetValue("1234,4567,8910"); + prop.SetValue("Value 1,Value 2,Value 3"); var valueEditor = dataType.Editor.GetValueEditor(); ((DataValueEditor) valueEditor).Configuration = dataType.Configuration; @@ -90,7 +77,7 @@ namespace Umbraco.Tests.PropertyEditors var dataTypeService = new TestObjects.TestDataTypeService(dataType); var prop = new Property(1, new PropertyType(dataType)); - prop.SetValue("1234"); + prop.SetValue("Value 2"); var result = dataType.Editor.GetValueEditor().ConvertDbToString(prop.PropertyType, prop.GetValue(), dataTypeService); diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs index 2c3a2d1583..7ec23158f6 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs @@ -1,8 +1,14 @@ using System; using System.Collections.Generic; +using System.Linq; +using Moq; using NUnit.Framework; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; +using Umbraco.Web.PropertyEditors; +using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Tests.PropertyEditors { @@ -79,27 +85,26 @@ namespace Umbraco.Tests.PropertyEditors [TestCase(null, new string[] { })] public void CanConvertDropdownListMultiplePropertyEditor(object value, IEnumerable expected) { - var converter = new DropdownListMultipleValueConverter(); - var inter = converter.ConvertSourceToIntermediate(null, null, value, false); - var result = converter.ConvertIntermediateToObject(null, null, PropertyCacheLevel.Unknown, inter, false); + var mockPublishedContentTypeFactory = new Mock(); + mockPublishedContentTypeFactory.Setup(x => x.GetDataType(123)) + .Returns(new PublishedDataType(123, "test", new Lazy(() => new DropDownFlexibleConfiguration + { + Multiple = true + }))); + + var publishedPropType = new PublishedPropertyType( + new PublishedContentType(1234, "test", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing), + new PropertyType("test", ValueStorageType.Nvarchar) { DataTypeId = 123 }, + new PropertyValueConverterCollection(Enumerable.Empty()), + Mock.Of(), mockPublishedContentTypeFactory.Object); + + var converter = new FlexibleDropdownPropertyValueConverter(); + var inter = converter.ConvertSourceToIntermediate(null, publishedPropType, value, false); + var result = converter.ConvertIntermediateToObject(null, publishedPropType, PropertyCacheLevel.Unknown, inter, false); Assert.AreEqual(expected, result); } - - [TestCase("100", new[] { 100 })] - [TestCase("100,200", new[] { 100, 200 })] - [TestCase("100 , 200, 300 ", new[] { 100, 200, 300 })] - [TestCase("", new int[] { })] - [TestCase(null, new int[] { })] - public void CanConvertDropdownListMultipleWithKeysPropertyEditor(object value, IEnumerable expected) - { - var converter = new DropdownListMultipleWithKeysValueConverter(); - var inter = converter.ConvertSourceToIntermediate(null, null, value, false); - var result = converter.ConvertIntermediateToObject(null, null, PropertyCacheLevel.Unknown, inter, false); - - Assert.AreEqual(expected, result); - } - + [TestCase("1", 1)] [TestCase("1", 1)] [TestCase("0", 0)] diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index 752d0ac97e..42beea7df3 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -362,12 +362,10 @@ namespace Umbraco.Tests.TestHelpers.Entities contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.NoEdit, ValueStorageType.Nvarchar) { Alias = "label", Name = "Label", Mandatory = false, SortOrder = 7, DataTypeId = -92 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DateTime, ValueStorageType.Date) { Alias = "dateTime", Name = "Date Time", Mandatory = false, SortOrder = 8, DataTypeId = -36 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ColorPicker, ValueStorageType.Nvarchar) { Alias = "colorPicker", Name = "Color Picker", Mandatory = false, SortOrder = 9, DataTypeId = -37 }); - //that one is gone in 7.4 - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.FolderBrowserAlias, DataTypeDatabaseType.Nvarchar) { Alias = "folderBrowser", Name = "Folder Browser", Mandatory = false, SortOrder = 10, DataTypeDefinitionId = -38 }); - contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListMultiple, ValueStorageType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeId = -39 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListFlexible, ValueStorageType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeId = -39 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.RadioButtonList, ValueStorageType.Nvarchar) { Alias = "rbList", Name = "Radio Button List", Mandatory = false, SortOrder = 12, DataTypeId = -40 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Date, ValueStorageType.Date) { Alias = "date", Name = "Date", Mandatory = false, SortOrder = 13, DataTypeId = -41 }); - contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownList, ValueStorageType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeId = -42 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListFlexible, ValueStorageType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeId = -42 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.CheckBoxList, ValueStorageType.Nvarchar) { Alias = "chklist", Name = "Checkbox List", Mandatory = false, SortOrder = 15, DataTypeId = -43 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ContentPicker, ValueStorageType.Integer) { Alias = "contentPicker", Name = "Content Picker", Mandatory = false, SortOrder = 16, DataTypeId = 1046 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MediaPicker, ValueStorageType.Integer) { Alias = "mediaPicker", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeId = 1048 }); @@ -375,11 +373,6 @@ namespace Umbraco.Tests.TestHelpers.Entities contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.RelatedLinks, ValueStorageType.Ntext) { Alias = "relatedLinks", Name = "Related Links", Mandatory = false, SortOrder = 21, DataTypeId = 1050 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Tags, ValueStorageType.Ntext) { Alias = "tags", Name = "Tags", Mandatory = false, SortOrder = 22, DataTypeId = 1041 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.UltraSimpleEditorAlias, DataTypeDatabaseType.Ntext) { Alias = "simpleEditor", Name = "Ultra Simple Editor", Mandatory = false, SortOrder = 19, DataTypeDefinitionId = 1038 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.UltimatePickerAlias, DataTypeDatabaseType.Ntext) { Alias = "ultimatePicker", Name = "Ultimate Picker", Mandatory = false, SortOrder = 20, DataTypeDefinitionId = 1039 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.MacroContainerAlias, DataTypeDatabaseType.Ntext) { Alias = "macroContainer", Name = "Macro Container", Mandatory = false, SortOrder = 23, DataTypeDefinitionId = 1042 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.ImageCropperAlias, DataTypeDatabaseType.Ntext) { Alias = "imgCropper", Name = "Image Cropper", Mandatory = false, SortOrder = 24, DataTypeDefinitionId = 1043 }); - contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); return contentType; diff --git a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs index 53de8460f2..7f8dc3f03a 100644 --- a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs @@ -31,6 +31,6 @@ namespace Umbraco.Web.PropertyEditors protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute); + protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(Logger, Attribute); } } diff --git a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs index 6acbedef63..4424e1d245 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors protected override IDataValueEditor CreateValueEditor() { - return new PublishValuesMultipleValueEditor(false, Attribute); + return new PublishValuesMultipleValueEditor(Logger, Attribute); } protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownFlexibleConfigurationEditor(_textService); diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs deleted file mode 100644 index a8956f9c4f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// Represents a configuration editor for the "drop down list multiple" property editor. - /// - /// - /// Ensures that 'multiple' is saved for the config in the db but is not a configuration field. - /// This is mostly to maintain backwards compatibility with old property editors. Devs can now simply - /// use the "drop down" property editor and check the "multiple" configuration checkbox - /// fixme what is multiple exactly?! - /// - internal class DropDownMultipleConfigurationEditor : ValueListConfigurationEditor - { - public DropDownMultipleConfigurationEditor(ILocalizedTextService textService) - : base(textService) - { - Fields.Add(new ConfigurationField - { - Key = "multiple", - Name = "multiple", - View = "hidden", // so it does not show in the configuration editor - HideLabel = true - }); - } - - // editor... - // - // receives: - // "preValues":[ - // { - // "label":"Add prevalue", - // "description":"Add and remove values for the list", - // "hideLabel":false, - // "view":"multivalues", - // "config":{}, - // "key":"items", - // "value":{"169":{"value":"a","sortOrder":1},"170":{"value":"b","sortOrder":2},"171":{"value":"c","sortOrder":3}} - // }, - // { - // "label":"multiple", - // "description":null, - // "hideLabel":true, - // "view":"hidden", - // "config":{}, - // "key":"multiple", - // "value":"1" - // }] - // - // posts ('d' being a new value): - // [{key: "items", value: [{value: "a", sortOrder: 1, id: "169"}, {value: "c", sortOrder: 3, id: "171"}, {value: "d"}]}, {key: "multiple", value: "1"}] - // - // the 'multiple' thing never goes to DB - // values go to DB with alias 0, 1, 2 + their ID + value - // the sort order that comes back makes no sense - // - // FromEditor can totally ignore 'multiple' - - /// - public override Dictionary ToConfigurationEditor(ValueListConfiguration configuration) - { - var dictionary = base.ToConfigurationEditor(configuration); - - // always add the multiple field, as 'true' - dictionary["multiple"] = 1; - - return dictionary; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs deleted file mode 100644 index 5992090a62..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A property editor to allow multiple selection of pre-defined items - /// - /// - /// Due to maintaining backwards compatibility this data type stores the value as a string which is a comma separated value of the - /// ids of the individual items so we have logic in here to deal with that. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropDownListMultiple, "Dropdown list multiple", "dropdown", Group = "lists", Icon="icon-bulleted-list", IsDeprecated = true)] - public class DropDownMultiplePropertyEditor : DropDownMultipleWithKeysPropertyEditor - { - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownMultiplePropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } - - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs deleted file mode 100644 index 0b882c6b8d..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// Represents a property editor that allows multiple selection of pre-defined items. - /// - /// - /// Due to backwards compatibility, this editor stores the value as a CSV string listing - /// the ids of individual items. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropdownlistMultiplePublishKeys, "Dropdown list multiple, publish keys", "dropdown", Group = "lists", Icon = "icon-bulleted-list", IsDeprecated = true)] - public class DropDownMultipleWithKeysPropertyEditor : DropDownPropertyEditor - { - private readonly ILocalizedTextService _textService; - - /// - /// Initializes a new instance of the class. - /// - public DropDownMultipleWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { - _textService = textService; - } - - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(true, Attribute); - - /// - protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownMultipleConfigurationEditor(_textService); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs deleted file mode 100644 index f4736ab63f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.PropertyEditors; -using umbraco; -using ClientDependency.Core; -using Umbraco.Core.Services; -using Constants = Umbraco.Core.Constants; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A property editor to allow the individual selection of pre-defined items. - /// - /// - /// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked - /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the string value is published - /// in cache and not the int ID. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropDownList, "Dropdown list", "dropdown", ValueType = ValueTypes.String, Group = "lists", Icon = "icon-indent", IsDeprecated = true)] - public class DropDownPropertyEditor : DropDownWithKeysPropertyEditor - { - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } - - /// - /// We need to override the value editor so that we can ensure the string value is published in cache and not the integer ID value. - /// - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValueValueEditor(Attribute, Logger); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs deleted file mode 100644 index 72d4b8c95f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A property editor to allow the individual selection of pre-defined items. - /// - /// - /// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked - /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published - /// in cache and not the string value. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropdownlistPublishKeys, "Dropdown list, publishing keys", "dropdown", ValueType = ValueTypes.Integer, Group = "lists", Icon = "icon-indent", IsDeprecated = true)] - public class DropDownWithKeysPropertyEditor : DataEditor - { - private readonly ILocalizedTextService _textService; - - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger) - { - _textService = textService; - } - - /// - /// Return a custom pre-value editor - /// - /// - protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs deleted file mode 100644 index 49ed34ffef..0000000000 --- a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; -using Umbraco.Web.Composing; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A custom value editor for any property editor that stores a pre-value int id so that we can ensure that the 'value' not the ID get's put into cache - /// - /// - /// This is required for legacy/backwards compatibility, otherwise we'd just store the string version and cache the string version without - /// needing additional lookups. - /// - internal class PublishValueValueEditor : DataValueEditor - { - private readonly ILogger _logger; - - internal PublishValueValueEditor(DataEditorAttribute attribute, ILogger logger) - : base(attribute) - { - _logger = logger; - } - - /// - public override string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService) - { - if (value == null) - return null; - - // get the configuration items - // if none, fallback to base - var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); - if (configuration == null) - return base.ConvertDbToString(propertyType, value, dataTypeService); - - var items = configuration.Items; - - var idAttempt = value.TryConvertTo(); - if (idAttempt.Success) - { - var itemId = idAttempt.Result; - var item = items.FirstOrDefault(x => x.Id == itemId); - if (item != null) return item.Value; - - _logger.Warn("Could not find a configuration item with ID " + itemId + " for property alias " + propertyType.Alias); - } - - // fallback to default - return base.ConvertDbToString(propertyType, value, dataTypeService); - } - } -} diff --git a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs index 0276bdc0a4..6aea6edba5 100644 --- a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs @@ -11,60 +11,21 @@ using Umbraco.Web.Composing; namespace Umbraco.Web.PropertyEditors { /// - /// Custom value editor to handle posted json data and to return json data for the multiple selected items as well as ensuring - /// that the multiple selected int IDs are published to cache as a delimited string (values) + /// Custom value editor to handle posted json data and to return json data for the multiple selected items /// /// /// This is re-used by editors such as the multiple drop down list or check box list /// - internal class PublishValuesMultipleValueEditor : PublishValueValueEditor + internal class PublishValuesMultipleValueEditor : DataValueEditor { - private readonly bool _publishIds; + private readonly ILogger _logger; - internal PublishValuesMultipleValueEditor(bool publishIds, ILogger logger, DataEditorAttribute attribute) - : base(attribute, logger) + internal PublishValuesMultipleValueEditor(ILogger logger, DataEditorAttribute attribute) + : base(attribute) { - _publishIds = publishIds; + _logger = logger; } - - public PublishValuesMultipleValueEditor(bool publishIds, DataEditorAttribute attribute) - : this(publishIds, Current.Logger, attribute) - { } - - /// - /// If publishing ids, we don't need to do anything, otherwise we need to look up the pre-values and get the string values - /// - /// - /// - /// - /// - public override string ConvertDbToString(PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) - { - if (propertyValue == null) - return null; - - //publishing ids, so just need to return the value as-is - if (_publishIds) - { - return propertyValue.ToString(); - } - - // get the multiple ids - // if none, fallback to base - var selectedIds = propertyValue.ToString().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); - if (selectedIds.Any() == false) - return base.ConvertDbToString(propertyType, propertyValue, dataTypeService); - - // get the configuration items - // if none, fallback to base - var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); - if (configuration == null) - return base.ConvertDbToString(propertyType, propertyValue, dataTypeService); - - var items = configuration.Items.Where(x => selectedIds.Contains(x.Id.ToInvariantString())).Select(x => x.Value); - return string.Join(",", items); - } - + /// /// Override so that we can return a json array to the editor for multi-select values /// @@ -81,7 +42,7 @@ namespace Umbraco.Web.PropertyEditors /// /// When multiple values are selected a json array will be posted back so we need to format for storage in - /// the database which is a comma separated ID value + /// the database which is a comma separated string value /// /// /// diff --git a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs index e5d9e4d4e8..46069fec79 100644 --- a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs @@ -8,19 +8,24 @@ namespace Umbraco.Web.PropertyEditors /// /// A property editor to allow the individual selection of pre-defined items. /// - /// - /// Due to remaining backwards compatible, this stores the id of the item in the database which is why it is marked - /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published - /// in cache and not the string value. - /// [DataEditor(Constants.PropertyEditors.Aliases.RadioButtonList, "Radio button list", "radiobuttons", ValueType = ValueTypes.Integer, Group="lists", Icon="icon-target")] - public class RadioButtonsPropertyEditor : DropDownWithKeysPropertyEditor + public class RadioButtonsPropertyEditor : DataEditor { + private readonly ILocalizedTextService _textService; + /// /// The constructor will setup the property editor based on the attribute if one is found /// public RadioButtonsPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } + : base(logger) + { + _textService = textService; + } + + /// + /// Return a custom pre-value editor + /// + /// + protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs index 521817a7de..d470f54662 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; @@ -16,7 +17,8 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) { - return source?.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + return source?.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToArray() + ?? Enumerable.Empty(); } public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 6f122719d0..313b82de29 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -360,7 +360,6 @@ - @@ -814,11 +813,9 @@ - - @@ -828,9 +825,6 @@ - - - From f332e9a07e13b9a27cb4516cc5efefadb1909a74 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 15:45:24 +1100 Subject: [PATCH 062/337] Fix sql and table check --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 7 +++++-- .../Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index c9eba205e8..2f50b9cd72 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -18,7 +18,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 public override void Migrate() { //need to convert the old drop down data types to use the new one - var oldDropDowns = Database.Fetch(Sql().Select().Where(x => x.EditorAlias.Contains(".DropDown"))); + var oldDropDowns = Database.Fetch(Sql() + .Select() + .From() + .Where(x => x.EditorAlias.Contains(".DropDown"))); foreach(var dd in oldDropDowns) { //nothing to change if there is no config @@ -37,7 +40,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 continue; } - var propDataSql = Sql().Select("*").From() + var propDataSql = Sql().Select().From() .InnerJoin().On(x => x.Id, x => x.PropertyTypeId) .InnerJoin().On(x => x.NodeId, x => x.DataTypeId) .Where(x => x.EditorAlias == dd.EditorAlias); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs index 26402cc477..fa6e47fac7 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs @@ -9,7 +9,8 @@ public override void Migrate() { // drop preValues table - Delete.Table("cmsDataTypePreValues").Do(); + if (TableExists("cmsDataTypePreValues")) + Delete.Table("cmsDataTypePreValues").Do(); } } } From df7623e6a7be9d6dfa5056b1b29c81b07ff3cd7c Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 16:32:13 +1100 Subject: [PATCH 063/337] Fixes migration, ensure's that if it runs again it won't corrupt data, fixes flexible drop down angular editor to post string vals, not the int ids, removes old angular drop down prop editor --- .../DropDownPropertyEditorsMigration.cs | 49 +++++++++---- .../dropdown/dropdown.controller.js | 70 ------------------- .../propertyeditors/dropdown/dropdown.html | 20 ------ .../dropdownFlexible.controller.js | 2 +- .../dropdownFlexible/dropdownFlexible.html | 4 +- .../PublishValuesMultipleValueEditor.cs | 2 +- 6 files changed, 38 insertions(+), 109 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js delete mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 2f50b9cd72..accb755020 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 .Select() .From() .Where(x => x.EditorAlias.Contains(".DropDown"))); - foreach(var dd in oldDropDowns) + foreach (var dd in oldDropDowns) { //nothing to change if there is no config if (dd.Configuration.IsNullOrWhiteSpace()) continue; @@ -30,7 +30,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 ValueListConfiguration config; try { - config = JsonConvert.DeserializeObject(dd.Configuration); + config = JsonConvert.DeserializeObject(dd.Configuration); } catch (Exception ex) { @@ -43,7 +43,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 var propDataSql = Sql().Select().From() .InnerJoin().On(x => x.Id, x => x.PropertyTypeId) .InnerJoin().On(x => x.NodeId, x => x.DataTypeId) - .Where(x => x.EditorAlias == dd.EditorAlias); + .Where(x => x.DataTypeId == dd.NodeId); var propDatas = Database.Query(propDataSql); var toUpdate = new List(); @@ -57,7 +57,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 } //run the property data updates - foreach(var propData in toUpdate) + foreach (var propData in toUpdate) { Database.Update(propData); } @@ -97,12 +97,13 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 items = config.Items }; dataType.Configuration = JsonConvert.SerializeObject(flexConfig); + Database.Update(dataType); } private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config) { //Get the INT ids stored for this property/drop down - IEnumerable ids = null; + int[] ids = null; if (!propData.VarcharValue.IsNullOrWhiteSpace()) { ids = ConvertStringValues(propData.VarcharValue); @@ -117,31 +118,49 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 } //if there are INT ids, convert them to values based on the configured pre-values - if (ids != null) + if (ids != null && ids.Length > 0) { //map the ids to values var vals = new List(); + var canConvert = true; foreach (var id in ids) { var val = config.Items.FirstOrDefault(x => x.Id == id); if (val != null) vals.Add(val.Value); + else + { + Logger.Warn($"Could not find associated data type configuration for stored Id {id}"); + canConvert = false; + } } - - propData.VarcharValue = string.Join(",", vals); - propData.TextValue = null; - propData.IntegerValue = null; - return true; + if (canConvert) + { + propData.VarcharValue = string.Join(",", vals); + propData.TextValue = null; + propData.IntegerValue = null; + return true; + } + } return false; } - private IEnumerable ConvertStringValues(string val) + private int[] ConvertStringValues(string val) { - return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) - .Select(x => int.TryParse(x, out var i) ? i : int.MinValue) - .Where(x => x != int.MinValue); + var splitVals = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + var intVals = splitVals + .Select(x => int.TryParse(x, out var i) ? i : int.MinValue) + .Where(x => x != int.MinValue) + .ToArray(); + + //only return if the number of values are the same (i.e. All INTs) + if (splitVals.Length == intVals.Length) + return intVals; + + return null; } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js deleted file mode 100644 index bcbd13f860..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js +++ /dev/null @@ -1,70 +0,0 @@ -angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownController", - function($scope) { - - //setup the default config - var config = { - items: [], - multiple: false - }; - - //map the user config - angular.extend(config, $scope.model.config); - - //map back to the model - $scope.model.config = config; - - function convertArrayToDictionaryArray(model){ - //now we need to format the items in the dictionary because we always want to have an array - var newItems = []; - for (var i = 0; i < model.length; i++) { - newItems.push({ id: model[i], sortOrder: 0, value: model[i] }); - } - - return newItems; - } - - - function convertObjectToDictionaryArray(model){ - //now we need to format the items in the dictionary because we always want to have an array - var newItems = []; - var vals = _.values($scope.model.config.items); - var keys = _.keys($scope.model.config.items); - - for (var i = 0; i < vals.length; i++) { - var label = vals[i].value ? vals[i].value : vals[i]; - newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label }); - } - - return newItems; - } - - if (angular.isArray($scope.model.config.items)) { - //PP: I dont think this will happen, but we have tests that expect it to happen.. - //if array is simple values, convert to array of objects - if(!angular.isObject($scope.model.config.items[0])){ - $scope.model.config.items = convertArrayToDictionaryArray($scope.model.config.items); - } - } - else if (angular.isObject($scope.model.config.items)) { - $scope.model.config.items = convertObjectToDictionaryArray($scope.model.config.items); - } - else { - throw "The items property must be either an array or a dictionary"; - } - - - //sort the values - $scope.model.config.items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); }); - - //now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set - // to "" gets selected by default - if ($scope.model.value === null || $scope.model.value === undefined) { - if ($scope.model.config.multiple) { - $scope.model.value = []; - } - else { - $scope.model.value = ""; - } - } - - }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html deleted file mode 100644 index 663373c8eb..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html +++ /dev/null @@ -1,20 +0,0 @@ -
- - - - - - -
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index c7a472d80e..1ea77ee035 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -74,7 +74,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo // if we run in single mode we'll store the value in a local variable // so we can pass an array as the model as our PropertyValueEditor expects that $scope.model.singleDropdownValue = ""; - if ($scope.model.config.multiple === "0") { + if (Object.toBoolean($scope.model.config.multiple)) { $scope.model.singleDropdownValue = Array.isArray($scope.model.value) ? $scope.model.value[0] : $scope.model.value; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html index 5edbab4f30..7c55f0bda9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html @@ -5,7 +5,7 @@ ng-switch-default ng-change="updateSingleDropdownValue()" ng-model="model.singleDropdownValue" - ng-options="item.id as item.value for item in model.config.items"> + ng-options="item.value as item.value for item in model.config.items"> @@ -15,5 +15,5 @@ ng-switch-when="1" multiple ng-model="model.value" - ng-options="item.id as item.value for item in model.config.items"> + ng-options="item.value as item.value for item in model.config.items"> diff --git a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs index 6aea6edba5..8e0737dedd 100644 --- a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs @@ -25,7 +25,7 @@ namespace Umbraco.Web.PropertyEditors { _logger = logger; } - + /// /// Override so that we can return a json array to the editor for multi-select values /// From b199b7346b107c77ad180c691cfed7ffe52d15e0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 16:35:30 +1100 Subject: [PATCH 064/337] Fixes multiple selection with drop down --- .../dropdownFlexible/dropdownFlexible.controller.js | 5 ++++- .../propertyeditors/dropdownFlexible/dropdownFlexible.html | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index 1ea77ee035..23bd2c9a42 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -12,7 +12,10 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo //map back to the model $scope.model.config = config; - + + //ensure this is a bool, old data could store zeros/ones or string versions + $scope.model.config.multiple = Object.toBoolean($scope.model.config.multiple); + function convertArrayToDictionaryArray(model){ //now we need to format the items in the dictionary because we always want to have an array var newItems = []; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html index 7c55f0bda9..3239e64acc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html @@ -12,7 +12,7 @@ From 9347e6205fe5be3a8d1638d5a9626db5555dc416 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 16:36:13 +1100 Subject: [PATCH 065/337] fixes test --- src/Umbraco.Tests/Composing/TypeLoaderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index 9b23ec3d6b..1199b37cdb 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -279,7 +279,7 @@ AnotherContentFinder public void GetDataEditors() { var types = _typeLoader.GetDataEditors(); - Assert.AreEqual(43, types.Count()); + Assert.AreEqual(39, types.Count()); } /// From b95a994f94339a22701867565f8855d9fae1f262 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 24 Oct 2018 09:12:09 +0200 Subject: [PATCH 066/337] set opacity and disabled cursor when property is locked --- src/Umbraco.Web.UI.Client/src/less/belle.less | 1 + .../src/less/utilities/theme/_opacity.less | 19 +++++++++++++++++++ .../content/umb-tabbed-content.html | 10 ++++++---- 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/less/utilities/theme/_opacity.less diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index ac8279e3ab..f5a05c20ee 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -168,6 +168,7 @@ // Utilities @import "utilities/layout/_display.less"; +@import "utilities/theme/_opacity.less"; @import "utilities/typography/_text-decoration.less"; @import "utilities/typography/_white-space.less"; @import "utilities/_flexbox.less"; diff --git a/src/Umbraco.Web.UI.Client/src/less/utilities/theme/_opacity.less b/src/Umbraco.Web.UI.Client/src/less/utilities/theme/_opacity.less new file mode 100644 index 0000000000..4550827cdc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/utilities/theme/_opacity.less @@ -0,0 +1,19 @@ +/* + + Opacity + +*/ + +.o-100 { opacity: 1; } +.o-90 { opacity: 0.9; } +.o-80 { opacity: 0.8; } +.o-70 { opacity: 0.7; } +.o-60 { opacity: 0.6; } +.o-50 { opacity: 0.5; } +.o-40 { opacity: 0.4; } +.o-30 { opacity: 0.3; } +.o-20 { opacity: 0.2; } +.o-10 { opacity: 0.1; } +.o-05 { opacity: 0.05; } +.o-025 { opacity: 0.025; } +.o-0 { opacity: 0; } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html index 68d5d3d41c..9ab8c509fd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html @@ -22,10 +22,12 @@ - - +
+ + +
From adae4325c9735c0b10c3b40f916ea2f42b7a574e Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 19:07:35 +1100 Subject: [PATCH 067/337] Removes old legacy files --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 5 - .../Umbraco/webservices/CheckForUpgrade.asmx | 1 - .../Umbraco/webservices/Developer.asmx | 1 - .../Umbraco/webservices/ajax.js | 805 ------------------ .../Umbraco/webservices/codeEditorSave.asmx | 1 - .../Umbraco/webservices/legacyAjaxCalls.asmx | 1 - .../Umbraco/webservices/nodeSorter.asmx | 1 - .../Umbraco/webservices/templates.asmx | 1 - src/Umbraco.Web/Umbraco.Web.csproj | 19 - .../umbraco/webservices/CheckForUpgrade.asmx | 1 - .../webservices/CheckForUpgrade.asmx.cs | 109 --- .../UmbracoAuthorizedWebService.cs | 97 --- .../umbraco/webservices/ajaxHelpers.cs | 25 - .../umbraco/webservices/legacyAjaxCalls.asmx | 1 - .../webservices/legacyAjaxCalls.asmx.cs | 141 --- .../umbraco/webservices/nodeSorter.asmx | 1 - .../umbraco/webservices/nodeSorter.asmx.cs | 262 ------ 17 files changed, 1472 deletions(-) delete mode 100644 src/Umbraco.Web.UI/Umbraco/webservices/CheckForUpgrade.asmx delete mode 100644 src/Umbraco.Web.UI/Umbraco/webservices/Developer.asmx delete mode 100644 src/Umbraco.Web.UI/Umbraco/webservices/ajax.js delete mode 100644 src/Umbraco.Web.UI/Umbraco/webservices/codeEditorSave.asmx delete mode 100644 src/Umbraco.Web.UI/Umbraco/webservices/legacyAjaxCalls.asmx delete mode 100644 src/Umbraco.Web.UI/Umbraco/webservices/nodeSorter.asmx delete mode 100644 src/Umbraco.Web.UI/Umbraco/webservices/templates.asmx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/UmbracoAuthorizedWebService.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/ajaxHelpers.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index de52021220..d95d8ca664 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -424,7 +424,6 @@ - @@ -434,10 +433,6 @@ Form - - - - Designer diff --git a/src/Umbraco.Web.UI/Umbraco/webservices/CheckForUpgrade.asmx b/src/Umbraco.Web.UI/Umbraco/webservices/CheckForUpgrade.asmx deleted file mode 100644 index 226022e0fd..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/webservices/CheckForUpgrade.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="CheckForUpgrade.asmx.cs" Class="umbraco.presentation.webservices.CheckForUpgrade" %> diff --git a/src/Umbraco.Web.UI/Umbraco/webservices/Developer.asmx b/src/Umbraco.Web.UI/Umbraco/webservices/Developer.asmx deleted file mode 100644 index b98e33ef54..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/webservices/Developer.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="c#" Codebehind="Developer.asmx.cs" Class="umbraco.webservices.Developer" %> diff --git a/src/Umbraco.Web.UI/Umbraco/webservices/ajax.js b/src/Umbraco.Web.UI/Umbraco/webservices/ajax.js deleted file mode 100644 index 868ccf6650..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/webservices/ajax.js +++ /dev/null @@ -1,805 +0,0 @@ -// ajax.js -// Common Javascript methods and global objects -// Ajax framework for Internet Explorer (6.0, ...) and Firefox (1.0, ...) -// Copyright by Matthias Hertel, http://www.mathertel.de -// This work is licensed under a Creative Commons Attribution 2.0 Germany License. -// See http://creativecommons.org/licenses/by/2.0/de/ -// More information on: http://ajaxaspects.blogspot.com/ and http://ajaxaspekte.blogspot.com/ -// ----- -// 05.06.2005 created by Matthias Hertel. -// 19.06.2005 minor corrections to webservices. -// 25.06.2005 ajax action queue and timing. -// 02.07.2005 queue up actions fixed. -// 10.07.2005 ajax.timeout -// 10.07.2005 a option object that is passed from ajax.Start() to prepare() is also queued. -// 10.07.2005 a option object that is passed from ajax.Start() to prepare(), finish() -// and onException() is also queued. -// 12.07.2005 correct xml encoding when CallSoap() -// 20.07.2005 more datatypes and XML Documents -// 20.07.2005 more datatypes and XML Documents fixed -// 06.08.2005 caching implemented. -// 07.08.2005 bugs fixed, when queuing without a delay time. -// 04.09.2005 bugs fixed, when entering non-multiple actions. -// 07.09.2005 proxies.IsActive added -// 27.09.2005 fixed error in handling bool as a datatype -// 13.12.2005 WebServices with arrays on strings, ints, floats and booleans - still undocumented -// 27.12.2005 fixed: empty string return values enabled. -// 27.12.2005 enable the late binding of proxy methods. -// 21.01.2006 void return bug fixed. -// 18.02.2006 typo: Finsh -> Finish. -// 25.02.2006 better xmlhttp request object retrieval, see http://blogs.msdn.com/ie/archive/2006/01/23/516393.aspx -// 22.04.2006 progress indicator added. -// 28.01.2006 void return bug fixed again? -// 09.03.2006 enable late binding of prepare and finish methods by using an expression. -// 14.07.2006 Safari Browser Version 2.03/Mac OS X 10.4. compatibility: xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue -// 10.08.2006 date to xml format fixed by Kars Veling -// 16.09.2006 .postUrl - -// ----- global variable for the proxies to webservices. ----- - -/// The root object for the proxies to webservices. -var proxies = new Object(); - -proxies.current = null; // the current active webservice call. -proxies.xmlhttp = null; // The current active xmlhttp object. - - -// ----- global variable for the ajax engine. ----- - -/// The root object for the ajax engine. -var ajax = new Object(); - -ajax.current = null; /// The current active AJAX action. -ajax.option = null; /// The options for the current active AJAX action. - -ajax.queue = new Array(); /// The pending AJAX actions. -ajax.options = new Array(); /// The options for the pending AJAX actions. - -ajax.timer = null; /// The timer for delayed actions. - -ajax.progress = false; /// show a progress indicator -ajax.progressTimer = null; /// a timer-object that help displaying the progress indicator not too often. - -// ----- AJAX engine and actions implementation ----- - -///Start an AJAX action by entering it into the queue -ajax.Start = function (action, options) { - ajax.Add(action, options); - // check if the action should start - if ((ajax.current == null) && (ajax.timer == null)) - ajax._next(false); -} // ajax.Start - - -///Start an AJAX action by entering it into the queue -ajax.Add = function (action, options) { - if (action == null) { - alert("ajax.Start: Argument action must be set."); - return; - } // if - - // enable the late binding of the methods by using a string that is evaluated. - if (typeof(action.call) == "string") action.call = eval(action.call); - if (typeof(action.prepare) == "string") action.prepare = eval(action.prepare); - if (typeof(action.finish) == "string") action.finish = eval(action.finish); - - if ((action.queueClear != null) && (action.queueClear == true)) { - ajax.queue = new Array(); - ajax.options = new Array(); - - } else if ((ajax.queue.length > 0) && ((action.queueMultiple == null) || (action.queueMultiple == false))) { - // remove existing action entries from the queue and clear a running timer - if ((ajax.timer != null) && (ajax.queue[0] == action)) { - window.clearTimeout(ajax.timer); - ajax.timer = null; - } // if - - var n = 0; - while (n < ajax.queue.length) { - if (ajax.queue[n] == action) { - ajax.queue.splice(n, 1); - ajax.options.splice(n, 1); - } else { - n++; - } // if - } // while - } // if - - if ((action.queueTop == null) || (action.queueTop == false)) { - // to the end. - ajax.queue.push(action); - ajax.options.push(options); - - } else { - // to the top - ajax.queue.unshift(action); - ajax.options.unshift(options); - } // if -} // ajax.Add - - -///Check, if the next AJAX action can start. -///This is an internal method that should not be called from external. -///for private use only. -ajax._next = function (forceStart) { - var ca = null // current action - var co = null // current opptions - var data = null; - - if (ajax.current != null) - return; // a call is active: wait more time - - if (ajax.timer != null) - return; // a call is pendig: wait more time - - if (ajax.queue.length == 0) - return; // nothing to do. - - ca = ajax.queue[0]; - co = ajax.options[0]; - if ((forceStart == true) || (ca.delay == null) || (ca.delay == 0)) { - // start top action - ajax.current = ca; - ajax.queue.shift(); - ajax.option = co; - ajax.options.shift(); - - // get the data - if (ca.prepare != null) - try { - data = ca.prepare(co); - } catch (ex) { } - - if (ca.call != null) { - ajax.StartProgress(); - - // start the call - ca.call.func = ajax.Finish; - ca.call.onException = ajax.Exception; - ca.call(data); - // start timeout timer - if (ca.timeout != null) - ajax.timer = window.setTimeout(ajax.Cancel, ca.timeout * 1000); - - } else if (ca.postUrl != null) { - // post raw data to URL - - } else { - // no call - ajax.Finish(data); - } // if - - } else { - // start a timer and wait - ajax.timer = window.setTimeout(ajax.EndWait, ca.delay); - } // if -} // ajax._next - - -///The delay time of an action is over. -ajax.EndWait = function() { - ajax.timer = null; - ajax._next(true); -} // ajax.EndWait - - -///The current action timed out. -ajax.Cancel = function() { - proxies.cancel(false); // cancel the current webservice call. - ajax.timer = null; - ajax.current = null; - ajax.option = null; - ajax.EndProgress(); - window.setTimeout(ajax._next, 200); // give some to time to cancel the http connection. -} // ajax.Cancel - - -///Finish an AJAX Action the normal way -ajax.Finish = function (data) { - // clear timeout timer if set - if (ajax.timer != null) { - window.clearTimeout(ajax.timer); - ajax.timer = null; - } // if - - // use the data - try { - if ((ajax.current != null) && (ajax.current.finish != null)) - ajax.current.finish(data, ajax.option); - } catch (ex) { } - // reset the running action - ajax.current = null; - ajax.option = null; - ajax.EndProgress(); - ajax._next(false) -} // ajax.Finish - - -///Finish an AJAX Action with an exception -ajax.Exception = function (ex) { - // use the data - if (ajax.current.onException != null) - ajax.current.onException(ex, ajax.option); - - // reset the running action - ajax.current = null; - ajax.option = null; - ajax.EndProgress(); -} // ajax.Exception - - -///Clear the current and all pending AJAX actions. -ajax.CancelAll = function () { - ajax.Cancel(); - // clear all pending AJAX actions in the queue. - ajax.queue = new Array(); - ajax.options = new Array(); -} // ajax.CancelAll - - -// ----- show or hide a progress indicator ----- - -// show a progress indicator if it takes longer... -ajax.StartProgress = function() { - ajax.progress = true; - if (ajax.progressTimer != null) - window.clearTimeout(ajax.progressTimer); - ajax.progressTimer = window.setTimeout(ajax.ShowProgress, 220); -} // ajax.StartProgress - - -// hide any progress indicator soon. -ajax.EndProgress = function () { - ajax.progress = false; - if (ajax.progressTimer != null) - window.clearTimeout(ajax.progressTimer); - ajax.progressTimer = window.setTimeout(ajax.ShowProgress, 20); -} // ajax.EndProgress - - -// this function is called by a timer to show or hide a progress indicator -ajax.ShowProgress = function() { - ajax.progressTimer = null; - var a = document.getElementById("AjaxProgressIndicator"); - - if (ajax.progress && (a != null)) { - // just display the existing object - a.style.top = document.documentElement.scrollTop + 2 + "px"; - a.style.display = ""; - - } else if (ajax.progress) { - - // find a relative link to the ajaxcore folder containing ajax.js - var path = "../ajaxcore/" - for (var n in document.scripts) { - s = document.scripts[n].src; - if ((s != null) && (s.length >= 7) && (s.substr(s.length -7).toLowerCase() == "ajax.js")) - path = s.substr(0,s.length -7); - } // for - - // create new standard progress object - a = document.createElement("div"); - a.id = "AjaxProgressIndicator"; - a.style.position = "absolute"; - a.style.right = "2px"; - a.style.top = document.documentElement.scrollTop + 2 + "px"; - a.style.width = "98px"; - a.style.height = "16px" - a.style.padding = "2px"; - a.style.verticalAlign = "bottom"; - a.style.backgroundColor="#51c77d"; - - a.innerHTML = " please wait..."; - document.body.appendChild(a); - - } else if (a) { - a.style.display="none"; - } // if -} // ajax.ShowProgress - - -// ----- simple http-POST server call ----- - -ajax.postData = function (url, data, func) { - var x = proxies._getXHR(); - - // enable cookieless sessions: - var cs = document.location.href.match(/\/\(.*\)\//); - if (cs != null) { - url = url.split('/'); - url[3] += cs[0].substr(0, cs[0].length-1); - url = url.join('/'); - } // if - - x.open("POST", url, (func != null)); - - if (func != null) { - // async call with xmlhttp-object as parameter - x.onreadystatechange = func; - x.send(data); - - } else { - // sync call - x.send(soap); - return(x.responseText); - } // if -} // ajax.postData - - -///Execute a soap call. -///Build the xml for the call of a soap method of a webservice -///and post it to the server. -proxies.callSoap = function (args) { - var p = args.callee; - var x = null; - - // check for existing cache-entry - if (p._cache != null) { - if ((p.params.length == 1) && (args.length == 1) && (p._cache[args[0]] != null)) { - if (p.func != null) { - p.func(p._cache[args[0]]); - return(null); - } else { - return(p._cache[args[0]]); - } // if - } else { - p._cachekey = args[0]; - }// if - } // if - - proxies.current = p; - x = proxies._getXHR(); - proxies.xmlhttp = x; - - // envelope start - var soap = "" - + "" - + "" - + "<" + p.fname + " xmlns='" + p.service.ns + "'>"; - - // parameters - for (n = 0; (n < p.params.length) && (n < args.length); n++) { - var val = args[n]; - var typ = p.params[n].split(':'); - - if ((typ.length == 1) || (typ[1] == "string")) { - val = String(args[n]).replace(/&/g, "&").replace(//g, ">"); - - } else if (typ[1] == "int") { - val = parseInt(args[n]); - } else if (typ[1] == "float") { - val = parseFloat(args[n]); - - } else if ((typ[1] == "x") && (typeof(args[n]) == "string")) { - val = args[n]; - - } else if ((typ[1] == "x") && (typeof(XMLSerializer) != "undefined")) { - val = (new XMLSerializer()).serializeToString(args[n].firstChild); - - } else if (typ[1] == "x") { - val = args[n].xml; - - } else if ((typ[1] == "bool") && (typeof(args[n]) == "string")) { - val = args[n].toLowerCase(); - - } else if (typ[1] == "bool") { - val = String(args[n]).toLowerCase(); - - } else if (typ[1] == "date") { - // calculate the xml format for datetime objects from a javascript date object - var s, ret; - ret = String(val.getFullYear()); - ret += "-"; - s = String(val.getMonth() + 1); - ret += (s.length == 1 ? "0" + s : s); - ret += "-"; - s = String(val.getDate()); - ret += (s.length == 1 ? "0" + s : s); - ret += "T"; - s = String(val.getHours()); - ret += (s.length == 1 ? "0" + s : s); - ret += ":"; - s = String(val.getMinutes()); - ret += (s.length == 1 ? "0" + s : s); - ret += ":"; - s = String(val.getSeconds()); - ret += (s.length == 1 ? "0" + s : s); - val = ret; - - } else if (typ[1] == "s[]") { - val = "" + args[n].join("") + ""; - - } else if (typ[1] == "int[]") { - val = "" + args[n].join("") + ""; - - } else if (typ[1] == "float[]") { - val = "" + args[n].join("") + ""; - - } else if (typ[1] == "bool[]") { - val = "" + args[n].join("") + ""; - - } // if - soap += "<" + typ[0] + ">" + val + "" - } // for - - // envelope end - soap += "" - + "" - + ""; - - // enable cookieless sessions: - var u = p.service.url; - var cs = document.location.href.match(/\/\(.*\)\//); - if (cs != null) { - u = p.service.url.split('/'); - u[3] += cs[0].substr(0, cs[0].length-1); - u = u.join('/'); - } // if - - x.open("POST", u, (p.func != null)); - x.setRequestHeader("SOAPAction", p.action); - x.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); - - if (p.corefunc != null) { - // async call with xmlhttp-object as parameter - x.onreadystatechange = p.corefunc; - x.send(soap); - - } else if (p.func != null) { - // async call - x.onreadystatechange = proxies._response; - x.send(soap); - - } else { - // sync call - x.send(soap); - return(proxies._response()); - } // if -} // proxies.callSoap - - -// cancel the running webservice call. -// raise: set raise to false to prevent raising an exception -proxies.cancel = function(raise) { - var cc = proxies.current; - var cx = proxies.xmlhttp; - - if (raise == null) raise == true; - - if (proxies.xmlhttp != null) { - proxies.xmlhttp.onreadystatechange = function() { }; - proxies.xmlhttp.abort(); - if (raise && (proxies.current.onException != null)) - proxies.current.onException("WebService call was canceled.") - proxies.current = null; - proxies.xmlhttp = null; - } // if -} // proxies.cancel - - -// px is a proxies.service.func object ! -proxies.EnableCache = function (px) { - // attach an empty _cache object. - px._cache = new Object(); -} // proxies.EnableCache - - -// check, if a call is currently waiting for a result -proxies.IsActive = function () { - return(proxies.xmlhttp != null); -} // proxies.IsActive - - -///Callback method for a webservice call that dispatches the response to servive.func or service.onException. -///for private use only. -proxies._response = function () { - var ret = null; - var x = proxies.xmlhttp; - var cc = proxies.current; - var rtype = null; - - if ((cc.rtype.length > 0) && (cc.rtype[0] != null)) - rtype = cc.rtype[0].split(':'); - - if ((x != null) && (x.readyState == 4)) { - if (x.status == 200) { - var xNode = null; - - if (rtype != null) - xNode = x.responseXML.getElementsByTagName(rtype[0])[0]; - - if (xNode == null) { - ret = null; - - } else if (xNode.firstChild == null) { // 27.12.2005: empty string return values - ret = ((rtype.length == 1) || (rtype[1] == "string") ? "" : null); - - } else if ((rtype.length == 1) || (rtype[1] == "string")) { - ret = xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue; - - } else if (rtype[1] == "bool") { - ret = xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue; - ret = (ret == "true"); - - } else if (rtype[1] == "int") { - ret = xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue; - ret = parseInt(ret); - - } else if (rtype[1] == "float") { - ret = xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue; - ret = parseFloat(ret); - - } else if ((rtype[1] == "x") && (typeof(XMLSerializer) != "undefined")) { - ret = (new XMLSerializer()).serializeToString(xNode.firstChild); - ret = ajax._getXMLDOM(ret); - - } else if ((rtype[1] == "ds") && (typeof(XMLSerializer) != "undefined")) { - // ret = (new XMLSerializer()).serializeToString(xNode.firstChild.nextSibling.firstChild); - ret = (new XMLSerializer()).serializeToString(xNode); - ret = ajax._getXMLDOM(ret); - - } else if (rtype[1] == "x") { - ret = xNode.firstChild.xml; - ret = ajax._getXMLDOM(ret); - - } else if (rtype[1] == "ds") { -// ret = xNode.firstChild.nextSibling.firstChild.xml; - ret = xNode.xml; - ret = ajax._getXMLDOM(ret); - - } else if (rtype[1] == "s[]") { - // Array of strings - ret = new Array(); - xNode = xNode.firstChild; - while (xNode != null) { - ret.push(xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue); - xNode = xNode.nextSibling; - } // while - - } else if (rtype[1] == "int[]") { - // Array of int - ret = new Array(); - xNode = xNode.firstChild; - while (xNode != null) { - ret.push(parseInt(xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue)); - xNode = xNode.nextSibling; - } // while - - } else if (rtype[1] == "float[]") { - // Array of float - ret = new Array(); - xNode = xNode.firstChild; - while (xNode != null) { - ret.push(parseFloat(xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue)); - xNode = xNode.nextSibling; - } // while - - } else if (rtype[1] == "bool[]") { - // Array of bool - ret = new Array(); - xNode = xNode.firstChild; - while (xNode != null) { - ret.push((xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue).toLowerCase() == "true"); - xNode = xNode.nextSibling; - } // while - - } else { - ret = xNode.textContent || xNode.innerText || xNode.text || xNode.childNodes[0].nodeValue; - } // if - - // store to _cache - if ((cc._cache != null) && (cc._cachekey != null)) { - cc._cache[cc._cachekey] = ret; - cc._cachekey = null; - } // if - - proxies.xmlhttp = null; - proxies.current = null; - - if (cc.func == null) { - return(ret); // sync - } else { - cc.func(ret); // async - return(null); - } // if - - } else if (proxies.current.onException == null) { - // no exception - - } else { - // raise an exception - ret = new Error(); - - if (x.status == 404) { - ret.message = "The webservice could not be found."; - - } else if (x.status == 500) { - ret.name = "SoapException"; - var n = x.responseXML.documentElement.firstChild.firstChild.firstChild; - while (n != null) { - if (n.nodeName == "faultcode") ret.message = n.firstChild.nodeValue; - if (n.nodeName == "faultstring") ret.description = n.firstChild.nodeValue; - n = n.nextSibling; - } // while - - } else if ((x.status == 502) || (x.status == 12031)) { - ret.message = "The server could not be found."; - - } else { - // no classified response. - ret.message = "Result-Status:" + x.status + "\n" + x.responseText; - } // if - proxies.current.onException(ret); - } // if - - proxies.xmlhttp = null; - proxies.current = null; - } // if -} // proxies._response - - -///Callback method to show the result of a soap call in an alert box. -///To set up a debug output in an alert box use: -///proxies.service.method.corefunc = proxies.alertResult; -proxies.alertResult = function () { - var x = proxies.xmlhttp; - - if (x.readyState == 4) { - if (x.status == 200) { - if (x.responseXML.documentElement.firstChild.firstChild.firstChild == null) - alert("(no result)"); - else - alert(x.responseXML.documentElement.firstChild.firstChild.firstChild.firstChild.nodeValue); - - } else if (x.status == 404) { alert("Error!\n\nThe webservice could not be found."); - - } else if (x.status == 500) { - // a SoapException - var ex = new Error(); - ex.name = "SoapException"; - var n = x.responseXML.documentElement.firstChild.firstChild.firstChild; - while (n != null) { - if (n.nodeName == "faultcode") ex.message = n.firstChild.nodeValue; - if (n.nodeName == "faultstring") ex.description = n.firstChild.nodeValue; - n = n.nextSibling; - } // while - alert("The server threw an exception.\n\n" + ex.message + "\n\n" + ex.description); - - } else if (x.status == 502) { alert("Error!\n\nThe server could not be found."); - - } else { - // no classified response. - alert("Result-Status:" + x.status + "\n" + x.responseText); - } // if - - proxies.xmlhttp = null; - proxies.current = null; - } // if -} // proxies.alertResult - - -///Show all the details of the returned data of a webservice call. -///Use this method for debugging transmission problems. -///To set up a debug output in an alert box use: -///proxies.service.method.corefunc = proxies.alertResponseText; -proxies.alertResponseText = function () { - if (proxies.xmlhttp.readyState == 4) - alert("Status:" + proxies.xmlhttp.status + "\nRESULT:" + proxies.xmlhttp.responseText); -} // proxies.alertResponseText - - -///show the details about an exception. -proxies.alertException = function(ex) { - var s = "Exception:\n\n"; - - if (ex.constructor == String) { - s = ex; - } else { - if ((ex.name != null) && (ex.name != "")) - s += "Type: " + ex.name + "\n\n"; - - if ((ex.message != null) && (ex.message != "")) - s += "Message:\n" + ex.message + "\n\n"; - - if ((ex.description != null) && (ex.description != "") && (ex.message != ex.description)) - s += "Description:\n" + ex.description + "\n\n"; - } // if - alert(s); -} // proxies.alertException - - -///Get a browser specific implementation of the XMLHttpRequest object. -// from http://blogs.msdn.com/ie/archive/2006/01/23/516393.aspx -proxies._getXHR = function () { - var x = null; - if (window.XMLHttpRequest) { - // if IE7, Mozilla, Safari, etc: Use native object - x = new XMLHttpRequest() - - } else if (window.ActiveXObject) { - // ...otherwise, use the ActiveX control for IE5.x and IE6 - try { x = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { } - if (x == null) - try { x = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { } - } // if - return(x); -} // proxies._getXHR - - -///Get a browser specific implementation of the XMLDOM object, containing a XML document. -///the xml document as string. -ajax._getXMLDOM = function (xmlText) { - var obj = null; - - if ((document.implementation != null) && (typeof document.implementation.createDocument == "function")) { - // Gecko / Mozilla / Firefox - var parser = new DOMParser(); - obj = parser.parseFromString(xmlText, "text/xml"); - - } else { - // IE - try { - obj = new ActiveXObject("MSXML2.DOMDocument"); - } catch (e) { } - - if (obj == null) { - try { - obj = new ActiveXObject("Microsoft.XMLDOM"); - } catch (e) { } - } // if - - if (obj != null) { - obj.async = false; - obj.validateOnParse = false; - } // if - obj.loadXML(xmlText); - } // if - return(obj); -} // _getXMLDOM - - -///show the details of a javascript object. -///This helps a lot while developing and debugging. -function inspectObj(obj) { - var s = "InspectObj:"; - - if (obj == null) { - s = "(null)"; alert(s); return; - } else if (obj.constructor == String) { - s = "\"" + obj + "\""; - } else if (obj.constructor == Array) { - s += " _ARRAY"; - } else if (typeof(obj) == "function") { - s += " [function]" + obj; - - } else if ((typeof(XMLSerializer) != "undefined") && (obj.constructor == XMLDocument)) { - s = "[XMLDocument]:\n" + (new XMLSerializer()).serializeToString(obj.firstChild); - alert(s); return; - - } else if ((obj.constructor == null) && (typeof(obj) == "object") && (obj.xml != null)) { - s = "[XML]:\n" + obj.xml; - alert(s); return; - } - - for (p in obj) { - try { - if (obj[p] == null) { - s += "\n" + String(p) + " (...)"; - - } else if (typeof(obj[p]) == "function") { - s += "\n" + String(p) + " [function]"; - - } else if (obj[p].constructor == Array) { - s += "\n" + String(p) + " [ARRAY]: " + obj[p]; - for (n = 0; n < obj[p].length; n++) - s += "\n " + n + ": " + obj[p][n]; - - } else { - s += "\n" + String(p) + " [" + typeof(obj[p]) + "]: " + obj[p]; - } // if - } catch (e) { s+= e;} - } // for - alert(s); -} // inspectObj - -// ----- End ----- diff --git a/src/Umbraco.Web.UI/Umbraco/webservices/codeEditorSave.asmx b/src/Umbraco.Web.UI/Umbraco/webservices/codeEditorSave.asmx deleted file mode 100644 index 947a6fb889..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/webservices/codeEditorSave.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="codeEditorSave.asmx.cs" Class="umbraco.presentation.webservices.codeEditorSave" %> diff --git a/src/Umbraco.Web.UI/Umbraco/webservices/legacyAjaxCalls.asmx b/src/Umbraco.Web.UI/Umbraco/webservices/legacyAjaxCalls.asmx deleted file mode 100644 index 5acc6e6022..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/webservices/legacyAjaxCalls.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="legacyAjaxCalls.asmx.cs" Class="umbraco.presentation.webservices.legacyAjaxCalls" %> diff --git a/src/Umbraco.Web.UI/Umbraco/webservices/nodeSorter.asmx b/src/Umbraco.Web.UI/Umbraco/webservices/nodeSorter.asmx deleted file mode 100644 index ae09ffa463..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/webservices/nodeSorter.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="nodeSorter.asmx.cs" Class="umbraco.presentation.webservices.nodeSorter" %> diff --git a/src/Umbraco.Web.UI/Umbraco/webservices/templates.asmx b/src/Umbraco.Web.UI/Umbraco/webservices/templates.asmx deleted file mode 100644 index 4a6e4ee189..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/webservices/templates.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="c#" Codebehind="templates.asmx.cs" Class="umbraco.webservices.templates" %> diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 656bbd29c5..8986f7eff6 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1314,19 +1314,6 @@ - - - CheckForUpgrade.asmx - Component - - - legacyAjaxCalls.asmx - Component - - - nodeSorter.asmx - Component - @@ -1338,9 +1325,6 @@ - - Component - Component @@ -1367,10 +1351,7 @@ - - - ASPXCodeBehind diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx deleted file mode 100644 index 226022e0fd..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="CheckForUpgrade.asmx.cs" Class="umbraco.presentation.webservices.CheckForUpgrade" %> diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs deleted file mode 100644 index 9007f9c41e..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/CheckForUpgrade.asmx.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web; -using System.Web.Services; -using System.Web.Script.Services; -using Umbraco.Core; -using Umbraco.Web.WebServices; -using Umbraco.Core.Configuration; -using Umbraco.Web; -using Umbraco.Web.Composing; -using Umbraco.Web.Install; - - -namespace umbraco.presentation.webservices -{ - /// - /// Summary description for CheckForUpgrade - /// - [WebService(Namespace = "http://umbraco.org/")] - [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] - [System.ComponentModel.ToolboxItem(false)] - [ScriptService] - public class CheckForUpgrade : UmbracoAuthorizedWebService - { - - [WebMethod] - [ScriptMethod] - public UpgradeResult CallUpgradeService() - { - if (!AuthorizeRequest()) return null; - - var check = new global::Umbraco.Web.org.umbraco.update.CheckForUpgrade(); - var result = check.CheckUpgrade(UmbracoVersion.Current.Major, - UmbracoVersion.Current.Minor, - UmbracoVersion.Current.Build, - UmbracoVersion.CurrentComment); - return new UpgradeResult(result.UpgradeType.ToString(), result.Comment, result.UpgradeUrl); - } - - [WebMethod] - [ScriptMethod] - public void InstallStatus(bool isCompleted, string userAgent, string errorMsg) - { - bool isUpgrade = false; - // if it's an upgrade, you'll need to be logged in before we allow this call - if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus) == false) - { - isUpgrade = true; - try - { - AuthorizeRequest(true); - } - catch (Exception) - { - //we don't want to throw the exception back to JS - return; - } - } - - // Check for current install Id - Guid installId = Guid.NewGuid(); - var installCookie = Context.Request.GetCookieValue(Constants.Web.InstallerCookieName); - if (string.IsNullOrEmpty(installCookie) == false) - { - if (Guid.TryParse(installCookie, out installId)) - { - // check that it's a valid Guid - if (installId == Guid.Empty) - installId = Guid.NewGuid(); - - } - } - Context.Response.Cookies.Set(new HttpCookie(Constants.Web.InstallerCookieName, installId.ToString())); - - string dbProvider = string.Empty; - if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus) == false) - dbProvider = InstallHelper.GetDbProviderString(Current.SqlContext); - - var check = new global::Umbraco.Web.org.umbraco.update.CheckForUpgrade(); - check.Install(installId, - isUpgrade, - isCompleted, - DateTime.Now, - UmbracoVersion.Current.Major, - UmbracoVersion.Current.Minor, - UmbracoVersion.Current.Build, - UmbracoVersion.CurrentComment, - errorMsg, - userAgent, - dbProvider); - } - } - - - public class UpgradeResult - { - public string UpgradeType { get; set; } - public string UpgradeComment { get; set; } - public string UpgradeUrl { get; set; } - - public UpgradeResult() { } - public UpgradeResult(string upgradeType, string upgradeComment, string upgradeUrl) - { - UpgradeType = upgradeType; - UpgradeComment = upgradeComment; - UpgradeUrl = upgradeUrl + "?version=" + HttpContext.Current.Server.UrlEncode(UmbracoVersion.Current.ToString(3)); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/UmbracoAuthorizedWebService.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/UmbracoAuthorizedWebService.cs deleted file mode 100644 index 33c4831c40..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/UmbracoAuthorizedWebService.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Security; -using Umbraco.Web.Security; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; -using Umbraco.Web; -using Umbraco.Web.WebServices; - -namespace umbraco.presentation.webservices -{ - /// - /// An abstract web service class that has the methods and properties to correct validate an Umbraco user - /// - public abstract class UmbracoAuthorizedWebService : UmbracoWebService - { - private bool _hasValidated = false; - - /// - /// Checks if the umbraco context id is valid - /// - /// - /// - protected bool ValidateUserContextId(string currentUmbracoUserContextId) - { - return UmbracoContext.Security.ValidateCurrentUser(); - } - - /// - /// Checks if the username/password credentials are valid - /// - /// - /// - /// - protected bool ValidateCredentials(string username, string password) - { - return UmbracoContext.Security.ValidateBackOfficeCredentials(username, password); - } - - /// - /// Validates the user for access to a certain application - /// - /// The application alias. - /// true if an exception should be thrown if authorization fails - /// - protected bool AuthorizeRequest(string app, bool throwExceptions = false) - { - //ensure we have a valid user first! - if (!AuthorizeRequest(throwExceptions)) return false; - - //if it is empty, don't validate - if (app.IsNullOrWhiteSpace()) - { - return true; - } - var hasAccess = UserHasAppAccess(app, Security.CurrentUser); - if (!hasAccess && throwExceptions) - throw new SecurityException("The user does not have access to the required application"); - return hasAccess; - } - - /// - /// Checks if the specified user as access to the app - /// - /// - /// - /// - protected bool UserHasAppAccess(string app, IUser user) - { - return Security.UserHasSectionAccess(app, user); - } - - /// - /// Checks if the specified user by username as access to the app - /// - /// - /// - /// - protected bool UserHasAppAccess(string app, string username) - { - return Security.UserHasSectionAccess(app, username); - } - - /// - /// Returns true if there is a valid logged in user and that ssl is enabled if required - /// - /// true if an exception should be thrown if authorization fails - /// - protected bool AuthorizeRequest(bool throwExceptions = false) - { - var result = Security.AuthorizeRequest(throwExceptions); - return result == ValidateRequestAttempt.Success; - } - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/ajaxHelpers.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/ajaxHelpers.cs deleted file mode 100644 index 3e6ad7d221..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/ajaxHelpers.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Data; -using System.Configuration; -using System.Web; -using System.Web.Security; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.WebControls.WebParts; -using System.Web.UI.HtmlControls; -using Umbraco.Core.IO; - -namespace umbraco.presentation.webservices -{ - public class ajaxHelpers - { - public static void EnsureLegacyCalls(Page page) - { - var sm = ScriptManager.GetCurrent(page); - var legacyPath = new ServiceReference(SystemDirectories.WebServices + "/legacyAjaxCalls.asmx"); - - if (!sm.Services.Contains(legacyPath)) - sm.Services.Add(legacyPath); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx deleted file mode 100644 index 5acc6e6022..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="legacyAjaxCalls.asmx.cs" Class="umbraco.presentation.webservices.legacyAjaxCalls" %> diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs deleted file mode 100644 index 28ba66709a..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Web; -using System.Web.Services; -using System.ComponentModel; -using System.Web.Script.Services; -using Umbraco.Core; -using Umbraco.Web; -using Umbraco.Web.WebServices; -using Umbraco.Core.Models.Membership; -using Umbraco.Web.Composing; -using Umbraco.Web._Legacy.UI; -using Umbraco.Core.Services; - -namespace umbraco.presentation.webservices -{ - /// - /// Summary description for legacyAjaxCalls - /// - [WebService(Namespace = "http://umbraco.org/webservices")] - [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] - [ToolboxItem(false)] - [ScriptService] - public class legacyAjaxCalls : UmbracoAuthorizedWebService - { - /// - /// method to accept a string value for the node id. Used for tree's such as python - /// and xslt since the file names are the node IDs - /// - /// - /// - /// - [WebMethod] - [ScriptMethod] - public void Delete(string nodeId, string alias, string nodeType) - { - if (!AuthorizeRequest()) - return; - - //U4-2686 - alias is html encoded, make sure to decode - alias = HttpUtility.HtmlDecode(alias); - - //check which parameters to pass depending on the types passed in - int intNodeId; - if (nodeType == "memberGroups") - { - LegacyDialogHandler.Delete( - new HttpContextWrapper(HttpContext.Current), - Security.CurrentUser, - nodeType, 0, nodeId); - } - else if (int.TryParse(nodeId, out intNodeId) && nodeType != "member") // Fix for #26965 - numeric member login gets parsed as nodeId - { - LegacyDialogHandler.Delete( - new HttpContextWrapper(HttpContext.Current), - Security.CurrentUser, - nodeType, intNodeId, alias); - } - else - { - LegacyDialogHandler.Delete( - new HttpContextWrapper(HttpContext.Current), - Security.CurrentUser, - nodeType, 0, nodeId); - } - } - - /// - /// Permanently deletes a document/media object. - /// Used to remove an item from the recycle bin. - /// - /// - /// - [WebMethod] - [ScriptMethod] - public void DeleteContentPermanently(string nodeId, string nodeType) - { - int intNodeId; - if (int.TryParse(nodeId, out intNodeId)) - { - switch (nodeType) - { - case "media": - case "mediaRecycleBin": - //ensure user has access to media - AuthorizeRequest(Constants.Applications.Media.ToString(), true); - var media = Current.Services.MediaService.GetById(intNodeId); - if (media != null) - Current.Services.MediaService.Delete(media); - break; - case "content": - case "contentRecycleBin": - default: - //ensure user has access to content - AuthorizeRequest(Constants.Applications.Content.ToString(), true); - var content = Current.Services.ContentService.GetById(intNodeId); - if (content != null) - Current.Services.ContentService.Delete(content); - break; - } - } - else - { - throw new ArgumentException("The nodeId argument could not be parsed to an integer"); - } - } - - [WebMethod] - [ScriptMethod] - public void DisableUser(int userId) - { - AuthorizeRequest(Constants.Applications.Users.ToString(), true); - - var user = Services.UserService.GetUserById(userId); - if (user == null) return; - - user.IsApproved = false; - Services.UserService.Save(user); - } - - [WebMethod] - [ScriptMethod] - public string NiceUrl(int nodeId) - { - - AuthorizeRequest(true); - - var umbHelper = new UmbracoHelper(Current.UmbracoContext, Current.Services, Current.ApplicationCache); - - return umbHelper.Url(nodeId); - } - - [WebMethod] - [ScriptMethod] - public string ProgressStatus(string Key) - { - AuthorizeRequest(true); - - return Application[Context.Request.GetItemAsString("key")].ToString(); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx deleted file mode 100644 index ae09ffa463..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="nodeSorter.asmx.cs" Class="umbraco.presentation.webservices.nodeSorter" %> diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs deleted file mode 100644 index f82587a413..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs +++ /dev/null @@ -1,262 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Web.Script.Services; -using System.Web.Services; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Web; -using Umbraco.Web.Composing; -using Umbraco.Web._Legacy.Actions; - -namespace umbraco.presentation.webservices -{ - /// - /// Summary description for nodeSorter - /// - [WebService(Namespace = "http://umbraco.org/")] - [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] - [ToolboxItem(false)] - [ScriptService] - public class nodeSorter : UmbracoAuthorizedWebService - { - [WebMethod] - public SortNode GetNodes(string ParentId, string App) - { - if (AuthorizeRequest()) - { - var nodes = new List(); - - // "hack for stylesheet" - if (App == "settings") - { - var stylesheet = Services.FileService.GetStylesheetByName(ParentId.EnsureEndsWith(".css")); - if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + ParentId); - - var sort = 0; - foreach (var child in stylesheet.Properties) - { - nodes.Add(new SortNode(child.Name.GetHashCode(), sort, child.Name, DateTime.Now)); - sort++; - } - - return new SortNode() - { - SortNodes = nodes.ToArray() - }; - } - else - { - var asInt = int.Parse(ParentId); - - var parent = new SortNode { Id = asInt }; - - var entityService = Services.EntityService; - - // Root nodes? - if (asInt == -1) - { - if (App == "media") - { - var rootMedia = entityService.GetRootEntities(UmbracoObjectTypes.Media); - nodes.AddRange(rootMedia.Select(media => new SortNode(media.Id, media.SortOrder, media.Name, media.CreateDate))); - } - else - { - var rootContent = entityService.GetRootEntities(UmbracoObjectTypes.Document); - nodes.AddRange(rootContent.Select(content => new SortNode(content.Id, content.SortOrder, content.Name, content.CreateDate))); - } - } - else - { - var children = entityService.GetChildren(asInt); - nodes.AddRange(children.Select(child => new SortNode(child.Id, child.SortOrder, child.Name, child.CreateDate))); - } - - - parent.SortNodes = nodes.ToArray(); - - return parent; - } - } - - throw new ArgumentException("User not logged in"); - } - - public void UpdateSortOrder(int ParentId, string SortOrder) - { - UpdateSortOrder(ParentId.ToString(), SortOrder); - } - - [WebMethod] - public void UpdateSortOrder(string ParentId, string SortOrder) - { - if (AuthorizeRequest() == false) return; - if (SortOrder.Trim().Length <= 0) return; - - var isContent = Context.Request.GetItemAsString("app") == "content" | Context.Request.GetItemAsString("app") == ""; - var isMedia = Context.Request.GetItemAsString("app") == "media"; - - //ensure user is authorized for the app requested - if (isContent && AuthorizeRequest(Constants.Applications.Content.ToString()) == false) return; - if (isMedia && AuthorizeRequest(Constants.Applications.Media.ToString()) == false) return; - - var ids = SortOrder.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); - if (isContent) - { - SortContent(ids, int.Parse(ParentId)); - } - else if (isMedia) - { - SortMedia(ids); - } - else - { - SortStylesheetProperties(ParentId, ids); - } - } - - private void SortMedia(string[] ids) - { - var mediaService = Services.MediaService; - var sortedMedia = new List(); - try - { - for (var i = 0; i < ids.Length; i++) - { - var id = int.Parse(ids[i]); - var m = mediaService.GetById(id); - sortedMedia.Add(m); - } - - // Save Media with new sort order and update content xml in db accordingly - var sorted = mediaService.Sort(sortedMedia); - } - catch (Exception ex) - { - Current.Logger.Error(ex, "Could not update media sort order"); - } - } - - - private void SortStylesheetProperties(string stylesheetName, string[] names) - { - var stylesheet = Services.FileService.GetStylesheetByName(stylesheetName.EnsureEndsWith(".css")); - if (stylesheet == null) throw new InvalidOperationException("No stylesheet found by name " + stylesheetName); - - var currProps = stylesheet.Properties.ToArray(); - //remove them all first - foreach (var prop in currProps) - { - stylesheet.RemoveProperty(prop.Name); - } - - //re-add them in the right order - for (var i = 0; i < names.Length; i++) - { - var found = currProps.Single(x => x.Name == names[i]); - stylesheet.AddProperty(found); - } - - Services.FileService.SaveStylesheet(stylesheet); - } - - private void SortContent(string[] ids, int parentId) - { - var contentService = Services.ContentService; - try - { - // Save content with new sort order and update db+cache accordingly - var intIds = new List(); - foreach (var stringId in ids) - { - int intId; - if (int.TryParse(stringId, out intId)) - intIds.Add(intId); - } - var sorted = contentService.Sort(intIds.ToArray()); - - // refresh sort order on cached xml - // but no... this is not distributed - solely relying on content service & events should be enough - //content.Instance.SortNodes(parentId); - - //send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here - if (parentId > 0) - { - Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings); - } - - } - catch (Exception ex) - { - Current.Logger.Error(ex, "Could not update content sort order"); - } - } - - } - - [Serializable] - public class SortNode - { - public SortNode() - { - } - - private SortNode[] _sortNodes; - - public SortNode[] SortNodes - { - get { return _sortNodes; } - set { _sortNodes = value; } - } - - public int TotalNodes - { - get { return _sortNodes != null ? _sortNodes.Length : 0; } - set { int test = value; } - } - - public SortNode(int Id, int SortOrder, string Name, DateTime CreateDate) - { - _id = Id; - _sortOrder = SortOrder; - _name = Name; - _createDate = CreateDate; - } - - private DateTime _createDate; - - public DateTime CreateDate - { - get { return _createDate; } - set { _createDate = value; } - } - - private string _name; - - public string Name - { - get { return _name; } - set { _name = value; } - } - - private int _sortOrder; - - public int SortOrder - { - get { return _sortOrder; } - set { _sortOrder = value; } - } - - private int _id; - - public int Id - { - get { return _id; } - set { _id = value; } - } - } -} From c94775608aaaec61955e614c07af77e4c277d71e Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 09:18:26 +0100 Subject: [PATCH 068/337] When returning a collection of languages - such as through the GetAllLanguages API Controller call the model mapping ensures that rather than order by name we, also put the default lang first then order a-z --- .../Models/Mapping/LanguageMapperProfile.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs index b305ee2824..6dd6135329 100644 --- a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs @@ -28,7 +28,21 @@ namespace Umbraco.Web.Models.Mapping { public IEnumerable Convert(IEnumerable source, IEnumerable destination, ResolutionContext context) { - return source.Select(x => context.Mapper.Map(x, null, context)).OrderBy(x => x.Name); + var langs = source.Select(x => context.Mapper.Map(x, null, context)).ToList(); + + //Put the default language first in the list & then sort rest by a-z + var defaultLang = langs.SingleOrDefault(x => x.IsDefault); + + //Remove the default lang from the list for now + langs.Remove(defaultLang); + + //Sort the remaining languages a-z + langs.OrderBy(x => x.Name); + + //Insert the default lang as the first item + langs.Insert(0, defaultLang); + + return langs; } } } From df1c4faeb96b5538ccae8cd8dbb6d2c7b14fad37 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Wed, 24 Oct 2018 08:26:13 +0200 Subject: [PATCH 069/337] Create doctype collections under the chosen parent --- .../Editors/ContentTypeController.cs | 32 ++++--------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index ac58b764f0..3f6df5c4b7 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -209,20 +209,6 @@ namespace Umbraco.Web.Editors public DocumentTypeCollectionDisplay PostCreateCollection(int parentId, string collectionName, bool collectionCreateTemplate, string collectionItemName, bool collectionItemCreateTemplate, string collectionIcon, string collectionItemIcon) { - var storeInContainer = false; - var allowUnderDocType = -1; - // check if it's a folder - if (Services.ContentTypeService.GetContentType(parentId) == null) - { - storeInContainer = true; - } else - { - // if it's not a container, we'll change the parentid to the root, - // and use the parent id as the doc type the collection should be allowed under - allowUnderDocType = parentId; - parentId = -1; - } - // create item doctype var itemDocType = new ContentType(parentId); itemDocType.Name = collectionItemName; @@ -260,20 +246,16 @@ namespace Umbraco.Web.Editors // save collection doctype Services.ContentTypeService.Save(collectionDocType); - // test if the parent id exist and then allow the collection underneath - if (storeInContainer == false && allowUnderDocType != -1) + // test if the parent exist and then allow the collection underneath + var parentCt = Services.ContentTypeService.GetContentType(parentId); + if (parentCt != null) { - var parentCt = Services.ContentTypeService.GetContentType(allowUnderDocType); - if (parentCt != null) - { - var allowedCts = parentCt.AllowedContentTypes.ToList(); - allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count())); - parentCt.AllowedContentTypes = allowedCts; - Services.ContentTypeService.Save(parentCt); - } + var allowedCts = parentCt.AllowedContentTypes.ToList(); + allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count())); + parentCt.AllowedContentTypes = allowedCts; + Services.ContentTypeService.Save(parentCt); } - return new DocumentTypeCollectionDisplay { CollectionId = collectionDocType.Id, From 05f5f2715baa519c6ee28ab7f7c9fe642913d3b7 Mon Sep 17 00:00:00 2001 From: Hemant Joshi Date: Wed, 24 Oct 2018 10:30:15 +0530 Subject: [PATCH 070/337] Added Correct Link of Getting Started with V8 --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6e421da5d7..6cbb764056 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,4 +1,4 @@ -_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/docs/CONTRIBUTING.md) to go to the v8 branch_ +_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_ # Contributing to Umbraco CMS 👍🎉 First off, thanks for taking the time to contribute! 🎉👍 From e7c55e6d702b728dc5618bb254c703f90a5dbda3 Mon Sep 17 00:00:00 2001 From: Joelvis Roman Date: Tue, 23 Oct 2018 23:07:35 +0100 Subject: [PATCH 071/337] Fix spelling mistake Fix spelling mistake --- .../src/common/services/navigation.service.js | 2 +- .../src/controllers/navigation.controller.js | 2 +- src/Umbraco.Web/Templates/TemplateRenderer.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index e617f62ed4..5b0706150c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -463,7 +463,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo //if it is not two parts long then this most likely means that it's a legacy action var js = action.metaData["jsAction"].replace("javascript:", ""); - //there's not really a different way to acheive this except for eval + //there's not really a different way to achieve this except for eval eval(js); } else { diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index 0c6bcf941a..e0330bd555 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -11,7 +11,7 @@ */ function NavigationController($scope, $rootScope, $location, $log, $routeParams, $timeout, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper) { - //TODO: Need to think about this and an nicer way to acheive what this is doing. + //TODO: Need to think about this and an nicer way to achieve what this is doing. //the tree event handler i used to subscribe to the main tree click events $scope.treeEventHandler = $({}); navigationService.setupTreeEvents($scope.treeEventHandler); diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index d7d331d887..32b06880ec 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -169,7 +169,7 @@ namespace Umbraco.Web.Templates /// /// /// - /// To acheive this we temporarily change the output text writer of the current HttpResponse, then + /// To achieve this we temporarily change the output text writer of the current HttpResponse, then /// execute the controller via the handler which innevitably writes the result to the text writer /// that has been assigned to the response. Then we change the response textwriter back to the original /// before continuing . From fa2bd54f77147ce8afdaeb64855aa08fd0bf7652 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 24 Oct 2018 11:05:05 +0200 Subject: [PATCH 072/337] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6cbb764056..51f9b1dd68 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -72,7 +72,6 @@ The pull request team consists of a member of Umbraco HQ, [Sebastiaan](https://g - [Anders Bjerner](https://github.com/abjerner) - [Dave Woestenborghs](https://github.com/dawoe) - [Emma Burstow](https://github.com/emmaburstow) -- [Kyle Weems](https://github.com/cssquirrel) - [Poornima Nayar](https://github.com/poornimanayar) These wonderful volunteers will provide you with a first reply to your PR, review and test out your changes and might ask more questions. After that they'll let Umbraco HQ know if everything seems okay. From 30c312c4b09f19c23a34f73dd7467d3ab2b8f87c Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 10:20:10 +0100 Subject: [PATCH 073/337] CSS & DOM element for overlay to prevent double click through to undelying input element --- .../src/less/components/umb-property-editor.less | 15 +++++++++++++++ .../components/property/umb-property-editor.html | 1 + 2 files changed, 16 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less index cbea6987e7..5c681d78a8 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less @@ -1,3 +1,18 @@ .umb-property-editor.-not-clickable { pointer-events: none; } + +.umb-property-editor { + position:relative; +} + +.umb-property-editor .overlay { + background: rgba(255,0,0,0.5); + display: block; + position: absolute; + top:0; + left:0; + height:100%; + width:100%; + cursor: not-allowed; +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html index 13a5491184..22d5764da4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html @@ -1,3 +1,4 @@
+
From ba0d96ce2a2e8d6e235b931a66fe450e7d68e99b Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 10:36:45 +0100 Subject: [PATCH 074/337] WIP for CSS overlay click through prevention stuff with Z-indexes --- .../src/less/components/umb-property-editor.less | 13 ++++++++++--- .../components/property/umb-property-editor.html | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less index 5c681d78a8..c1268b3410 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less @@ -1,13 +1,18 @@ .umb-property-editor.-not-clickable { - pointer-events: none; + // pointer-events: none; } .umb-property-editor { position:relative; } -.umb-property-editor .overlay { - background: rgba(255,0,0,0.5); +.umb-property-editor__view{ + z-index:1; + position:relative; +} + +.umb-property-editor__overlay { + background: rgba(255,0,255,0.5); display: block; position: absolute; top:0; @@ -15,4 +20,6 @@ height:100%; width:100%; cursor: not-allowed; + user-select: none; + z-index:2; } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html index 22d5764da4..4b43d9634c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html @@ -1,4 +1,4 @@
-
-
+
+
From 82622695928e4b8b2fb38446dee8f6e512391b12 Mon Sep 17 00:00:00 2001 From: Dave Woestenborghs Date: Wed, 24 Oct 2018 11:51:07 +0200 Subject: [PATCH 075/337] Make sure indexes are created as unique when using .Unique() syntax builder (#3319) (#3363) --- .../DefinitionFactory.cs | 6 ++-- .../IndexDefinition.cs | 7 ++++- .../Syntax/Alter/Column/AlterColumnBuilder.cs | 9 ++++-- .../Syntax/Alter/Table/AlterTableBuilder.cs | 7 +++-- .../Create/Column/CreateColumnBuilder.cs | 7 +++-- .../Syntax/Create/Index/CreateIndexBuilder.cs | 28 ++++++------------- .../Syntax/Create/Table/CreateTableBuilder.cs | 7 +++-- .../SqlCeSyntaxProviderTests.cs | 4 +-- 8 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs index e3c35e01b4..5b38533c2b 100644 --- a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs +++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/DefinitionFactory.cs @@ -158,9 +158,7 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions Name = indexName, IndexType = attribute.IndexType, ColumnName = columnName, - TableName = tableName, - IsClustered = attribute.IndexType == IndexTypes.Clustered, - IsUnique = attribute.IndexType == IndexTypes.UniqueNonClustered + TableName = tableName, }; if (string.IsNullOrEmpty(attribute.ForColumns) == false) @@ -174,4 +172,4 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions return definition; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs index ec46d35780..963e0a8ad6 100644 --- a/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs +++ b/src/Umbraco.Core/Persistence/DatabaseModelDefinitions/IndexDefinition.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Umbraco.Core.Persistence.DatabaseAnnotations; @@ -14,9 +15,13 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions public virtual string SchemaName { get; set; } public virtual string TableName { get; set; } public virtual string ColumnName { get; set; } + + [Obsolete("Use the IndexType property instead and set it to IndexTypes.UniqueNonClustered")] public virtual bool IsUnique { get; set; } + + [Obsolete("Use the IndexType property instead and set it to IndexTypes.Clustered")] public bool IsClustered { get; set; } public virtual ICollection Columns { get; set; } public IndexTypes IndexType { get; set; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnBuilder.cs index a7077f2d35..b2b2dfd17f 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Column/AlterColumnBuilder.cs @@ -1,4 +1,5 @@ using System.Data; +using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions; using Umbraco.Core.Persistence.Migrations.Syntax.Expressions; @@ -139,10 +140,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column { Name = indexName, SchemaName = Expression.SchemaName, - TableName = Expression.TableName, - IsUnique = true + TableName = Expression.TableName, + IndexType = IndexTypes.UniqueNonClustered }); + + index.Index.Columns.Add(new IndexColumnDefinition { Name = Expression.Column.Name @@ -242,4 +245,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column return this; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableBuilder.cs index 7a6ab8d47a..ad72176089 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Alter/Table/AlterTableBuilder.cs @@ -1,4 +1,5 @@ using System.Data; +using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions; using Umbraco.Core.Persistence.Migrations.Syntax.Expressions; @@ -124,8 +125,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table { Name = indexName, SchemaName = Expression.SchemaName, - TableName = Expression.TableName, - IsUnique = true + TableName = Expression.TableName, + IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition @@ -259,4 +260,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table return this; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Column/CreateColumnBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Column/CreateColumnBuilder.cs index d004cd1176..dad72c54ef 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Column/CreateColumnBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Column/CreateColumnBuilder.cs @@ -1,4 +1,5 @@ using System.Data; +using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Migrations.Syntax.Expressions; using Umbraco.Core.Persistence.SqlSyntax; @@ -114,8 +115,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Column { Name = indexName, SchemaName = Expression.SchemaName, - TableName = Expression.TableName, - IsUnique = true + TableName = Expression.TableName, + IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition @@ -217,4 +218,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Column return this; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Index/CreateIndexBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Index/CreateIndexBuilder.cs index 4d1396ff79..2740014150 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Index/CreateIndexBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Index/CreateIndexBuilder.cs @@ -47,39 +47,27 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Index } ICreateIndexOnColumnSyntax ICreateIndexColumnOptionsSyntax.Unique() - { - Expression.Index.IsUnique = true; - //if it is Unique then it must be unique nonclustered and set the other flags - Expression.Index.IndexType = IndexTypes.UniqueNonClustered; - Expression.Index.IsClustered = false; + { + Expression.Index.IndexType = IndexTypes.UniqueNonClustered; return this; } public ICreateIndexOnColumnSyntax NonClustered() { - Expression.Index.IndexType = IndexTypes.NonClustered; - Expression.Index.IsClustered = false; - Expression.Index.IndexType = IndexTypes.NonClustered; - Expression.Index.IsUnique = false; + Expression.Index.IndexType = IndexTypes.NonClustered; return this; } public ICreateIndexOnColumnSyntax Clustered() - { - Expression.Index.IndexType = IndexTypes.Clustered; - Expression.Index.IsClustered = true; - //if it is clustered then we have to change the index type set the other flags - Expression.Index.IndexType = IndexTypes.Clustered; - Expression.Index.IsClustered = true; - Expression.Index.IsUnique = false; - return this; + { + Expression.Index.IndexType = IndexTypes.Clustered; + return this; } ICreateIndexOnColumnSyntax ICreateIndexOptionsSyntax.Unique() { - Expression.Index.IndexType = IndexTypes.UniqueNonClustered; - Expression.Index.IsUnique = true; + Expression.Index.IndexType = IndexTypes.UniqueNonClustered; return this; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Table/CreateTableBuilder.cs b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Table/CreateTableBuilder.cs index 86760b71bc..5c19634321 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Table/CreateTableBuilder.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Syntax/Create/Table/CreateTableBuilder.cs @@ -1,4 +1,5 @@ using System.Data; +using Umbraco.Core.Persistence.DatabaseAnnotations; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions; using Umbraco.Core.Persistence.Migrations.Syntax.Expressions; @@ -164,8 +165,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Table { Name = indexName, SchemaName = Expression.SchemaName, - TableName = Expression.TableName, - IsUnique = true + TableName = Expression.TableName, + IndexType = IndexTypes.UniqueNonClustered }); index.Index.Columns.Add(new IndexColumnDefinition @@ -267,4 +268,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Table return this; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs index 105b3d0c11..2043feafc4 100644 --- a/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs +++ b/src/Umbraco.Tests/Persistence/SyntaxProvider/SqlCeSyntaxProviderTests.cs @@ -89,7 +89,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine, var sqlSyntax = new SqlServerSyntaxProvider(); var indexDefinition = CreateIndexDefinition(); - indexDefinition.IsClustered = false; + indexDefinition.IndexType = IndexTypes.Clustered; var actual = sqlSyntax.Format(indexDefinition); Assert.AreEqual("CREATE CLUSTERED INDEX [IX_A] ON [TheTable] ([A])", actual); @@ -159,4 +159,4 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine, } } -} \ No newline at end of file +} From 62716fb417217ad86c1c21086c95976d165b5a52 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 11:03:41 +0100 Subject: [PATCH 076/337] WIP disable tab index directive --- .../util/disabletabindex.directive.js | 85 ++++++++++++------- .../less/components/umb-property-editor.less | 1 - .../content/umb-tabbed-content.html | 10 +-- .../property/umb-property-editor.html | 6 +- .../views/components/umb-groups-builder.html | 3 +- 5 files changed, 64 insertions(+), 41 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js index 624404c641..8a32f3b089 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -3,55 +3,78 @@ angular.module("umbraco.directives") return { restrict: 'A', //Can only be used as an attribute + scope: { disableTabindex: "<"}, link: function (scope, element, attrs) { - //Use DOM Mutation Observer - //Select the node that will be observed for mutations (native DOM element not jQLite version) - var targetNode = element[0]; + function enableTest(){ + //Add in observer code - // Options for the observer (which mutations to observe) - var config = { attributes: false, childList: true, subtree: false }; + //Use DOM Mutation Observer + //Select the node that will be observed for mutations (native DOM element not jQLite version) + var targetNode = element[0]; - // Callback function to execute when mutations are observed - var callback = function(mutationsList, observer) { - for(var mutation of mutationsList) { + // Options for the observer (which mutations to observe) + var config = { attributes: false, childList: true, subtree: false }; - console.log('mutation', mutation); + // Callback function to execute when mutations are observed + var callback = function(mutationsList, observer) { + for(var mutation of mutationsList) { - //DOM items have been added or removed - if (mutation.type == 'childList') { + console.log('mutation', mutation); - //Check if any child items in mutation.target contain an input - var jqLiteEl = angular.element(mutation.target); - var childInputs = jqLiteEl.find('input'); + //DOM items have been added or removed + if (mutation.type == 'childList') { - //For each item in childInputs - override or set HTML attribute tabindex="-1" - angular.forEach(childInputs, function(element){ - console.log('item in loop', element); + //Check if any child items in mutation.target contain an input + var jqLiteEl = angular.element(mutation.target); + var childInputs = jqLiteEl.find('input'); - //TODO: Note we updating way too many times from the DOMSubtreeModified event - is this expensive? - angular.element(element).attr('tabindex', '-1'); - }); + //For each item in childInputs - override or set HTML attribute tabindex="-1" + angular.forEach(childInputs, function(element){ + console.log('item in loop', element); + + //TODO: Get existing element & it's tabindex (if any set) + + + //TODO: Note we updating way too many times from the DOMSubtreeModified event - is this expensive? + angular.element(element).attr('tabindex', '-1'); + }); + } } - } + }; + + // Create an observer instance linked to the callback function + var observer = new MutationObserver(callback); + + // Start observing the target node for configured mutations + //GO GO GO + observer.observe(targetNode, config); }; - // Create an observer instance linked to the callback function - var observer = new MutationObserver(callback); - // Start observing the target node for configured mutations - //GO GO GO - observer.observe(targetNode, config); + scope.$watch('disableTabindex',(newVal, oldVal) =>{ + console.log('new val', newVal); + + if(newVal === true){ + enableTest(); + }else{ + + } + }); + + + + //TODO: Unsure if we need to do this - to ensure the browser not trying to notify us still //When we browse away from the page - element.on('$destroy', function(e){ - console.log('element with disable-tabindex attribute is destoryed'); + // element.on('$destroy', function(e){ + // console.log('element with disable-tabindex attribute is destoryed'); - //Remove/stop the observer - observer.disconnect(); - }); + // //Remove/stop the observer + // observer.disconnect(); + // }); } }; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less index c1268b3410..b019892a9f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less @@ -12,7 +12,6 @@ } .umb-property-editor__overlay { - background: rgba(255,0,255,0.5); display: block; position: absolute; top:0; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html index 9ab8c509fd..7663aa8997 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html @@ -9,9 +9,9 @@
- -
- + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html index 4b43d9634c..8674e4f6d3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html @@ -1,4 +1,6 @@
-
-
+
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html index 8732da91e7..c976899cb8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-groups-builder.html @@ -232,8 +232,7 @@ + preview="true"> From a5b7e8b0ae1240d3d01a2b6453a216e80c6f45c4 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 11:57:02 +0100 Subject: [PATCH 077/337] WIP put the tabindex back to what it was before --- .../util/disabletabindex.directive.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js index 8a32f3b089..71d9ff0e5d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -6,6 +6,8 @@ angular.module("umbraco.directives") scope: { disableTabindex: "<"}, link: function (scope, element, attrs) { + var tabIndexesToRollback = []; + function enableTest(){ //Add in observer code @@ -34,7 +36,17 @@ angular.module("umbraco.directives") console.log('item in loop', element); //TODO: Get existing element & it's tabindex (if any set) + //Check if the element has an existing tab index + //If so store in a collection (that when this directive is disabled/toggled) + //The tabindex is returned back to normal + var currentTabIndex = angular.element(element).attr('tabindex'); + console.log('currentTabIndex', currentTabIndex); + if(currentTabIndex){ + //A value has been set - need to track it + var itemToRevert = { dom: element, tabindex: currentTabIndex }; + tabIndexesToRollback.push(itemToRevert); + } //TODO: Note we updating way too many times from the DOMSubtreeModified event - is this expensive? angular.element(element).attr('tabindex', '-1'); @@ -58,6 +70,15 @@ angular.module("umbraco.directives") if(newVal === true){ enableTest(); }else{ + console.log('what do I need to revert', tabIndexesToRollback); + + //Stop observation? + //TODO: Will it refire the observer?! + + angular.forEach(tabIndexesToRollback, function(rollbackItem){ + console.log('item in rollback', rollbackItem); + angular.element(rollbackItem.dom).attr('tabindex', rollbackItem.tabindex); + }); } }); From 5b84702c2f10c764a3e87d8fb1c0539d11dc8b18 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 13:37:33 +0100 Subject: [PATCH 078/337] Cleanup of disable tab directive & adds in tabbable 3rd party lib (wrapped as an AngularJS service) --- .../util/disabletabindex.directive.js | 105 ++------- .../src/common/services/tabbable.service.js | 223 ++++++++++++++++++ .../property/umb-property-editor.html | 8 +- 3 files changed, 248 insertions(+), 88 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/services/tabbable.service.js diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js index 71d9ff0e5d..35b49d0ddf 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -1,101 +1,40 @@ angular.module("umbraco.directives") - .directive('disableTabindex', function () { + .directive('disableTabindex', function (tabbableService) { return { restrict: 'A', //Can only be used as an attribute - scope: { disableTabindex: "<"}, link: function (scope, element, attrs) { - var tabIndexesToRollback = []; + //Select the node that will be observed for mutations (native DOM element not jQLite version) + var targetNode = element[0]; - function enableTest(){ - //Add in observer code + //Watch for DOM changes - so when the property editor subview loads in + //We can be notified its updated the child elements inside the DIV we are watching + var observer = new MutationObserver(domChange); - //Use DOM Mutation Observer - //Select the node that will be observed for mutations (native DOM element not jQLite version) - var targetNode = element[0]; + // Options for the observer (which mutations to observe) + var config = { attributes: true, childList: true, subtree: false }; - // Options for the observer (which mutations to observe) - var config = { attributes: false, childList: true, subtree: false }; + function domChange(mutationsList, observer){ + for(var mutation of mutationsList) { - // Callback function to execute when mutations are observed - var callback = function(mutationsList, observer) { - for(var mutation of mutationsList) { + //DOM items have been added or removed + if (mutation.type == 'childList') { - console.log('mutation', mutation); + //Check if any child items in mutation.target contain an input + var childInputs = tabbableService.tabbable(mutation.target); - //DOM items have been added or removed - if (mutation.type == 'childList') { - - //Check if any child items in mutation.target contain an input - var jqLiteEl = angular.element(mutation.target); - var childInputs = jqLiteEl.find('input'); - - //For each item in childInputs - override or set HTML attribute tabindex="-1" - angular.forEach(childInputs, function(element){ - console.log('item in loop', element); - - //TODO: Get existing element & it's tabindex (if any set) - //Check if the element has an existing tab index - //If so store in a collection (that when this directive is disabled/toggled) - //The tabindex is returned back to normal - var currentTabIndex = angular.element(element).attr('tabindex'); - console.log('currentTabIndex', currentTabIndex); - - if(currentTabIndex){ - //A value has been set - need to track it - var itemToRevert = { dom: element, tabindex: currentTabIndex }; - tabIndexesToRollback.push(itemToRevert); - } - - //TODO: Note we updating way too many times from the DOMSubtreeModified event - is this expensive? - angular.element(element).attr('tabindex', '-1'); - }); - } + //For each item in childInputs - override or set HTML attribute tabindex="-1" + angular.forEach(childInputs, function(element){ + angular.element(element).attr('tabindex', '-1'); + }); } - }; - - // Create an observer instance linked to the callback function - var observer = new MutationObserver(callback); - - // Start observing the target node for configured mutations - //GO GO GO - observer.observe(targetNode, config); - }; - - - scope.$watch('disableTabindex',(newVal, oldVal) =>{ - console.log('new val', newVal); - - if(newVal === true){ - enableTest(); - }else{ - console.log('what do I need to revert', tabIndexesToRollback); - - //Stop observation? - //TODO: Will it refire the observer?! - - angular.forEach(tabIndexesToRollback, function(rollbackItem){ - console.log('item in rollback', rollbackItem); - angular.element(rollbackItem.dom).attr('tabindex', rollbackItem.tabindex); - }); - } - }); + } - - - - - - //TODO: Unsure if we need to do this - to ensure the browser not trying to notify us still - //When we browse away from the page - // element.on('$destroy', function(e){ - // console.log('element with disable-tabindex attribute is destoryed'); - - // //Remove/stop the observer - // observer.disconnect(); - // }); + // Start observing the target node for configured mutations + //GO GO GO + observer.observe(targetNode, config); } }; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tabbable.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tabbable.service.js new file mode 100644 index 0000000000..4d8d5f68f3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/tabbable.service.js @@ -0,0 +1,223 @@ +//tabbable JS Lib (Wrapped in angular service) +//https://github.com/davidtheclark/tabbable + +(function() { + 'use strict'; + + function tabbableService() { + + var candidateSelectors = [ + 'input', + 'select', + 'textarea', + 'a[href]', + 'button', + '[tabindex]', + 'audio[controls]', + 'video[controls]', + '[contenteditable]:not([contenteditable="false"])' + ]; + var candidateSelector = candidateSelectors.join(','); + + var matches = typeof Element === 'undefined' + ? function () {} + : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; + + function tabbable(el, options) { + options = options || {}; + + var elementDocument = el.ownerDocument || el; + var regularTabbables = []; + var orderedTabbables = []; + + var untouchabilityChecker = new UntouchabilityChecker(elementDocument); + var candidates = el.querySelectorAll(candidateSelector); + + if (options.includeContainer) { + if (matches.call(el, candidateSelector)) { + candidates = Array.prototype.slice.apply(candidates); + candidates.unshift(el); + } + } + + var i, candidate, candidateTabindex; + for (i = 0; i < candidates.length; i++) { + candidate = candidates[i]; + + if (!isNodeMatchingSelectorTabbable(candidate, untouchabilityChecker)) continue; + + candidateTabindex = getTabindex(candidate); + if (candidateTabindex === 0) { + regularTabbables.push(candidate); + } else { + orderedTabbables.push({ + documentOrder: i, + tabIndex: candidateTabindex, + node: candidate + }); + } + } + + var tabbableNodes = orderedTabbables + .sort(sortOrderedTabbables) + .map(function(a) { return a.node }) + .concat(regularTabbables); + + return tabbableNodes; + } + + tabbable.isTabbable = isTabbable; + tabbable.isFocusable = isFocusable; + + function isNodeMatchingSelectorTabbable(node, untouchabilityChecker) { + if ( + !isNodeMatchingSelectorFocusable(node, untouchabilityChecker) + || isNonTabbableRadio(node) + || getTabindex(node) < 0 + ) { + return false; + } + return true; + } + + function isTabbable(node, untouchabilityChecker) { + if (!node) throw new Error('No node provided'); + if (matches.call(node, candidateSelector) === false) return false; + return isNodeMatchingSelectorTabbable(node, untouchabilityChecker); + } + + function isNodeMatchingSelectorFocusable(node, untouchabilityChecker) { + untouchabilityChecker = untouchabilityChecker || new UntouchabilityChecker(node.ownerDocument || node); + if ( + node.disabled + || isHiddenInput(node) + || untouchabilityChecker.isUntouchable(node) + ) { + return false; + } + return true; + } + + var focusableCandidateSelector = candidateSelectors.concat('iframe').join(','); + function isFocusable(node, untouchabilityChecker) { + if (!node) throw new Error('No node provided'); + if (matches.call(node, focusableCandidateSelector) === false) return false; + return isNodeMatchingSelectorFocusable(node, untouchabilityChecker); + } + + function getTabindex(node) { + var tabindexAttr = parseInt(node.getAttribute('tabindex'), 10); + if (!isNaN(tabindexAttr)) return tabindexAttr; + // Browsers do not return `tabIndex` correctly for contentEditable nodes; + // so if they don't have a tabindex attribute specifically set, assume it's 0. + if (isContentEditable(node)) return 0; + return node.tabIndex; + } + + function sortOrderedTabbables(a, b) { + return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex; + } + + // Array.prototype.find not available in IE. + function find(list, predicate) { + for (var i = 0, length = list.length; i < length; i++) { + if (predicate(list[i])) return list[i]; + } + } + + function isContentEditable(node) { + return node.contentEditable === 'true'; + } + + function isInput(node) { + return node.tagName === 'INPUT'; + } + + function isHiddenInput(node) { + return isInput(node) && node.type === 'hidden'; + } + + function isRadio(node) { + return isInput(node) && node.type === 'radio'; + } + + function isNonTabbableRadio(node) { + return isRadio(node) && !isTabbableRadio(node); + } + + function getCheckedRadio(nodes) { + for (var i = 0; i < nodes.length; i++) { + if (nodes[i].checked) { + return nodes[i]; + } + } + } + + function isTabbableRadio(node) { + if (!node.name) return true; + // This won't account for the edge case where you have radio groups with the same + // in separate forms on the same page. + var radioSet = node.ownerDocument.querySelectorAll('input[type="radio"][name="' + node.name + '"]'); + var checked = getCheckedRadio(radioSet); + return !checked || checked === node; + } + + // An element is "untouchable" if *it or one of its ancestors* has + // `visibility: hidden` or `display: none`. + function UntouchabilityChecker(elementDocument) { + this.doc = elementDocument; + // Node cache must be refreshed on every check, in case + // the content of the element has changed. The cache contains tuples + // mapping nodes to their boolean result. + this.cache = []; + } + + // getComputedStyle accurately reflects `visibility: hidden` of ancestors + // but not `display: none`, so we need to recursively check parents. + UntouchabilityChecker.prototype.hasDisplayNone = function hasDisplayNone(node, nodeComputedStyle) { + if (node === this.doc.documentElement) return false; + + // Search for a cached result. + var cached = find(this.cache, function(item) { + return item === node; + }); + if (cached) return cached[1]; + + nodeComputedStyle = nodeComputedStyle || this.doc.defaultView.getComputedStyle(node); + + var result = false; + + if (nodeComputedStyle.display === 'none') { + result = true; + } else if (node.parentNode) { + result = this.hasDisplayNone(node.parentNode); + } + + this.cache.push([node, result]); + + return result; + } + + UntouchabilityChecker.prototype.isUntouchable = function isUntouchable(node) { + if (node === this.doc.documentElement) return false; + var computedStyle = this.doc.defaultView.getComputedStyle(node); + if (this.hasDisplayNone(node, computedStyle)) return true; + return computedStyle.visibility === 'hidden'; + } + + //module.exports = tabbable; + + //////////// + + var service = { + tabbable: tabbable, + isTabbable: isTabbable, + isFocusable: isFocusable + }; + + return service; + } + + angular.module('umbraco.services').factory('tabbableService', tabbableService); + + })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html index 8674e4f6d3..cb82a83168 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html @@ -1,6 +1,4 @@ -
-
-
-
-
+
+
+
From 81c7a1de78d278cf2bad707ad0a214565acd8185 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 23:55:55 +1100 Subject: [PATCH 079/337] Cleans up the notification system, removes coupling on System.Web, simplifies the whole thing, removes old legacy files, adds sort event, moves sort notification to be event based and not part of the controller --- .../Models/NotificationEmailBodyParams.cs | 28 +++ .../Models/NotificationEmailSubjectParams.cs | 23 +++ src/Umbraco.Core/Services/IContentService.cs | 4 +- .../Services/INotificationService.cs | 21 +- .../Services/Implement/ContentService.cs | 49 +++-- .../Services/Implement/NotificationService.cs | 165 +++++---------- src/Umbraco.Core/Umbraco.Core.csproj | 2 + src/Umbraco.Tests/TestHelpers/TestObjects.cs | 4 +- .../views/content/content.sort.controller.js | 6 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 3 - .../Umbraco/dialogs/SendPublish.aspx | 13 -- .../Components/NotificationsComponent.cs | 190 ++++++++++++++---- src/Umbraco.Web/Editors/ContentController.cs | 9 +- .../NotificationServiceExtensions.cs | 145 ------------- .../Trees/LegacyTreeDataConverter.cs | 27 +-- src/Umbraco.Web/Umbraco.Web.csproj | 9 - .../umbraco/dialogs/SendPublish.aspx | 13 -- .../umbraco/dialogs/SendPublish.aspx.cs | 37 ---- .../dialogs/SendPublish.aspx.designer.cs | 16 -- 19 files changed, 302 insertions(+), 462 deletions(-) create mode 100644 src/Umbraco.Core/Models/NotificationEmailBodyParams.cs create mode 100644 src/Umbraco.Core/Models/NotificationEmailSubjectParams.cs delete mode 100644 src/Umbraco.Web.UI/Umbraco/dialogs/SendPublish.aspx delete mode 100644 src/Umbraco.Web/NotificationServiceExtensions.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.designer.cs diff --git a/src/Umbraco.Core/Models/NotificationEmailBodyParams.cs b/src/Umbraco.Core/Models/NotificationEmailBodyParams.cs new file mode 100644 index 0000000000..ff316b1cf7 --- /dev/null +++ b/src/Umbraco.Core/Models/NotificationEmailBodyParams.cs @@ -0,0 +1,28 @@ +using System; + +namespace Umbraco.Core.Models +{ + public class NotificationEmailBodyParams + { + public NotificationEmailBodyParams(string recipientName, string action, string itemName, string itemId, string itemUrl, string editedUser, string siteUrl, string summary) + { + RecipientName = recipientName ?? throw new ArgumentNullException(nameof(recipientName)); + Action = action ?? throw new ArgumentNullException(nameof(action)); + ItemName = itemName ?? throw new ArgumentNullException(nameof(itemName)); + ItemId = itemId ?? throw new ArgumentNullException(nameof(itemId)); + ItemUrl = itemUrl ?? throw new ArgumentNullException(nameof(itemUrl)); + Summary = summary ?? throw new ArgumentNullException(nameof(summary)); + EditedUser = editedUser ?? throw new ArgumentNullException(nameof(editedUser)); + SiteUrl = siteUrl ?? throw new ArgumentNullException(nameof(siteUrl)); + } + + public string RecipientName { get; } + public string Action { get; } + public string ItemName { get; } + public string ItemId { get; } + public string ItemUrl { get; } + public string Summary { get; } + public string EditedUser { get; } + public string SiteUrl { get; } + } +} diff --git a/src/Umbraco.Core/Models/NotificationEmailSubjectParams.cs b/src/Umbraco.Core/Models/NotificationEmailSubjectParams.cs new file mode 100644 index 0000000000..07b26dbcc1 --- /dev/null +++ b/src/Umbraco.Core/Models/NotificationEmailSubjectParams.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Umbraco.Core.Models +{ + + public class NotificationEmailSubjectParams + { + public NotificationEmailSubjectParams(string siteUrl, string action, string itemName) + { + SiteUrl = siteUrl ?? throw new ArgumentNullException(nameof(siteUrl)); + Action = action ?? throw new ArgumentNullException(nameof(action)); + ItemName = itemName ?? throw new ArgumentNullException(nameof(itemName)); + } + + public string SiteUrl { get; } + public string Action { get; } + public string ItemName { get; } + } +} diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 64877e393e..ed682096c0 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -337,12 +337,12 @@ namespace Umbraco.Core.Services /// /// Sorts documents. /// - bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true); + OperationResult Sort(IEnumerable items, int userId = 0, bool raiseEvents = true); /// /// Sorts documents. /// - bool Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true); + OperationResult Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true); #endregion diff --git a/src/Umbraco.Core/Services/INotificationService.cs b/src/Umbraco.Core/Services/INotificationService.cs index 3af603a31c..92a1e93e2f 100644 --- a/src/Umbraco.Core/Services/INotificationService.cs +++ b/src/Umbraco.Core/Services/INotificationService.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Web; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Models.Membership; @@ -13,20 +12,6 @@ namespace Umbraco.Core.Services { public interface INotificationService : IService { - /// - /// Sends the notifications for the specified user regarding the specified node and action. - /// - /// - /// - /// - /// - /// - /// - /// - void SendNotifications(IUser operatingUser, IUmbracoEntity entity, string action, string actionName, HttpContextBase http, - Func createSubject, - Func createBody); - /// /// Sends the notifications for the specified user regarding the specified nodes and action. /// @@ -37,9 +22,9 @@ namespace Umbraco.Core.Services /// /// /// - void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, HttpContextBase http, - Func createSubject, - Func createBody); + void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, Uri siteUri, + Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject, + Func<(IUser user, NotificationEmailBodyParams body, bool isHtml), string> createBody); /// /// Gets the notifications for the user diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index 2cd9051e72..ac1171cfdd 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -1906,16 +1906,18 @@ namespace Umbraco.Core.Services.Implement /// /// /// True if sorting succeeded, otherwise False - public bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true) + public OperationResult Sort(IEnumerable items, int userId = 0, bool raiseEvents = true) { + var evtMsgs = EventMessagesFactory.Get(); + var itemsA = items.ToArray(); - if (itemsA.Length == 0) return true; + if (itemsA.Length == 0) return new OperationResult(OperationResultType.NoOperation, evtMsgs); using (var scope = ScopeProvider.CreateScope()) { scope.WriteLock(Constants.Locks.ContentTree); - var ret = Sort(scope, itemsA, userId, raiseEvents); + var ret = Sort(scope, itemsA, userId, evtMsgs, raiseEvents); scope.Complete(); return ret; } @@ -1933,27 +1935,37 @@ namespace Umbraco.Core.Services.Implement /// /// /// True if sorting succeeded, otherwise False - public bool Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true) + public OperationResult Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true) { + var evtMsgs = EventMessagesFactory.Get(); + var idsA = ids.ToArray(); - if (idsA.Length == 0) return true; + if (idsA.Length == 0) return new OperationResult(OperationResultType.NoOperation, evtMsgs); using (var scope = ScopeProvider.CreateScope()) { scope.WriteLock(Constants.Locks.ContentTree); var itemsA = GetByIds(idsA).ToArray(); - var ret = Sort(scope, itemsA, userId, raiseEvents); + var ret = Sort(scope, itemsA, userId, evtMsgs, raiseEvents); scope.Complete(); return ret; } } - private bool Sort(IScope scope, IContent[] itemsA, int userId, bool raiseEvents) + private OperationResult Sort(IScope scope, IContent[] itemsA, int userId, EventMessages evtMsgs, bool raiseEvents) { var saveEventArgs = new SaveEventArgs(itemsA); - if (raiseEvents && scope.Events.DispatchCancelable(Saving, this, saveEventArgs, "Saving")) - return false; + if (raiseEvents) + { + //raise cancelable sorting event + if (scope.Events.DispatchCancelable(Saving, this, saveEventArgs, nameof(Sorting))) + return OperationResult.Cancel(evtMsgs); + + //raise saving event (this one cannot be canceled) + saveEventArgs.CanCancel = false; + scope.Events.Dispatch(Saving, this, saveEventArgs, nameof(Saving)); + } var published = new List(); var saved = new List(); @@ -1985,8 +1997,9 @@ namespace Umbraco.Core.Services.Implement if (raiseEvents) { - saveEventArgs.CanCancel = false; - scope.Events.Dispatch(Saved, this, saveEventArgs, "Saved"); + //first saved, then sorted + scope.Events.Dispatch(Saved, this, saveEventArgs, nameof(Saved)); + scope.Events.Dispatch(Sorted, this, saveEventArgs, nameof(Sorted)); } scope.Events.Dispatch(TreeChanged, this, saved.Select(x => new TreeChange(x, TreeChangeTypes.RefreshNode)).ToEventArgs()); @@ -1994,8 +2007,8 @@ namespace Umbraco.Core.Services.Implement if (raiseEvents && published.Any()) scope.Events.Dispatch(Published, this, new PublishEventArgs(published, false, false), "Published"); - Audit(AuditType.Sort, "Sorting content performed by user", userId, 0); - return true; + Audit(AuditType.Sort, userId, 0, "Sorting content performed by user"); + return OperationResult.Succeed(evtMsgs); } #endregion @@ -2070,6 +2083,16 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler DeletedVersions; + /// + /// Occurs before Sorting + /// + public static event TypedEventHandler> Sorting; + + /// + /// Occurs after Sorting + /// + public static event TypedEventHandler> Sorted; + /// /// Occurs before Save /// diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index cc76374715..12e575d903 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -6,8 +6,8 @@ using System.Linq; using System.Net.Mail; using System.Text; using System.Threading; -using System.Web; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -26,89 +26,21 @@ namespace Umbraco.Core.Services.Implement private readonly IContentService _contentService; private readonly INotificationsRepository _notificationsRepository; private readonly IGlobalSettings _globalSettings; + private readonly IContentSection _contentSection; private readonly ILogger _logger; - public NotificationService(IScopeProvider provider, IUserService userService, IContentService contentService, ILogger logger, - INotificationsRepository notificationsRepository, IGlobalSettings globalSettings) + public NotificationService(IScopeProvider provider, IUserService userService, IContentService contentService, + ILogger logger, INotificationsRepository notificationsRepository, IGlobalSettings globalSettings, IContentSection contentSection) { _notificationsRepository = notificationsRepository; _globalSettings = globalSettings; + _contentSection = contentSection; _uowProvider = provider ?? throw new ArgumentNullException(nameof(provider)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _contentService = contentService ?? throw new ArgumentNullException(nameof(contentService)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - /// - /// Sends the notifications for the specified user regarding the specified node and action. - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Currently this will only work for Content entities! - /// - public void SendNotifications(IUser operatingUser, IUmbracoEntity entity, string action, string actionName, HttpContextBase http, - Func createSubject, - Func createBody) - { - if (entity is IContent == false) - throw new NotSupportedException(); - - var content = (IContent) entity; - - // lazily get previous version - IContentBase prevVersion = null; - - // do not load *all* users in memory at once - // do not load notifications *per user* (N+1 select) - // cannot load users & notifications in 1 query (combination btw User2AppDto and User2NodeNotifyDto) - // => get batches of users, get all their notifications in 1 query - // re. users: - // users being (dis)approved = not an issue, filtered in memory not in SQL - // users being modified or created = not an issue, ordering by ID, as long as we don't *insert* low IDs - // users being deleted = not an issue for GetNextUsers - var id = Constants.Security.SuperUserId; - var nodeIds = content.Path.Split(',').Select(int.Parse).ToArray(); - const int pagesz = 400; // load batches of 400 users - do - { - // users are returned ordered by id, notifications are returned ordered by user id - var users = ((UserService) _userService).GetNextUsers(id, pagesz).Where(x => x.IsApproved).ToList(); - var notifications = GetUsersNotifications(users.Select(x => x.Id), action, nodeIds, Constants.ObjectTypes.Document).ToList(); - if (notifications.Count == 0) break; - - var i = 0; - foreach (var user in users) - { - // continue if there's no notification for this user - if (notifications[i].UserId != user.Id) continue; // next user - - // lazy load prev version - if (prevVersion == null) - { - prevVersion = GetPreviousVersion(entity.Id); - } - - // queue notification - var req = CreateNotificationRequest(operatingUser, user, content, prevVersion, actionName, http, createSubject, createBody); - Enqueue(req); - - // skip other notifications for this user - while (i < notifications.Count && notifications[i++].UserId == user.Id) ; - if (i >= notifications.Count) break; // break if no more notifications - } - - // load more users if any - id = users.Count == pagesz ? users.Last().Id + 1 : -1; - - } while (id > 0); - } - /// /// Gets the previous version to the latest version of the content item if there is one /// @@ -131,15 +63,15 @@ namespace Umbraco.Core.Services.Implement /// /// /// - /// + /// /// /// /// /// Currently this will only work for Content entities! /// - public void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, HttpContextBase http, - Func createSubject, - Func createBody) + public void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, Uri siteUri, + Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject, + Func<(IUser user, NotificationEmailBodyParams body, bool isHtml), string> createBody) { if (entities is IEnumerable == false) throw new NotSupportedException(); @@ -156,7 +88,7 @@ namespace Umbraco.Core.Services.Implement var prevVersionDictionary = new Dictionary(); // see notes above - var id = 0; + var id = Constants.Security.SuperUserId; const int pagesz = 400; // load batches of 400 users do { @@ -185,7 +117,7 @@ namespace Umbraco.Core.Services.Implement } // queue notification - var req = CreateNotificationRequest(operatingUser, user, content, prevVersionDictionary[content.Id], actionName, http, createSubject, createBody); + var req = CreateNotificationRequest(operatingUser, user, content, prevVersionDictionary[content.Id], actionName, siteUri, createSubject, createBody); Enqueue(req); } @@ -350,18 +282,19 @@ namespace Umbraco.Core.Services.Implement /// /// /// The action readable name - currently an action is just a single letter, this is the name associated with the letter - /// + /// /// Callback to create the mail subject /// Callback to create the mail body private NotificationRequest CreateNotificationRequest(IUser performingUser, IUser mailingUser, IContentBase content, IContentBase oldDoc, - string actionName, HttpContextBase http, - Func createSubject, - Func createBody) + string actionName, + Uri siteUri, + Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject, + Func<(IUser user, NotificationEmailBodyParams body, bool isHtml), string> createBody) { if (performingUser == null) throw new ArgumentNullException("performingUser"); if (mailingUser == null) throw new ArgumentNullException("mailingUser"); if (content == null) throw new ArgumentNullException("content"); - if (http == null) throw new ArgumentNullException("http"); + if (siteUri == null) throw new ArgumentNullException("siteUri"); if (createSubject == null) throw new ArgumentNullException("createSubject"); if (createBody == null) throw new ArgumentNullException("createBody"); @@ -402,7 +335,7 @@ namespace Umbraco.Core.Services.Implement summary.Append(p.PropertyType.Name); summary.Append(""); summary.Append(""); - summary.Append(ReplaceLinks(CompareText(oldText, newText, true, false, "", string.Empty), http.Request)); + summary.Append(ReplaceLinks(CompareText(oldText, newText, true, false, "", string.Empty), siteUri)); summary.Append(""); summary.Append(""); summary.Append(""); @@ -410,7 +343,7 @@ namespace Umbraco.Core.Services.Implement summary.Append(p.PropertyType.Name); summary.Append(""); summary.Append(""); - summary.Append(ReplaceLinks(CompareText(newText, oldText, true, false, "", string.Empty), http.Request)); + summary.Append(ReplaceLinks(CompareText(newText, oldText, true, false, "", string.Empty), siteUri)); summary.Append(""); summary.Append(""); } @@ -429,39 +362,39 @@ namespace Umbraco.Core.Services.Implement " "); } - string protocol = _globalSettings.UseHttps ? "https" : "http"; + var protocol = _globalSettings.UseHttps ? "https" : "http"; + var subjectVars = new NotificationEmailSubjectParams( + string.Concat(siteUri.Authority, IOHelper.ResolveUrl(SystemDirectories.Umbraco)), + actionName, + content.Name); - string[] subjectVars = { - string.Concat(http.Request.ServerVariables["SERVER_NAME"], ":", http.Request.Url.Port, IOHelper.ResolveUrl(SystemDirectories.Umbraco)), - actionName, - content.Name - }; - string[] bodyVars = { - mailingUser.Name, - actionName, - content.Name, - performingUser.Name, - string.Concat(http.Request.ServerVariables["SERVER_NAME"], ":", http.Request.Url.Port, IOHelper.ResolveUrl(SystemDirectories.Umbraco)), - content.Id.ToString(CultureInfo.InvariantCulture), summary.ToString(), - string.Format("{2}://{0}/{1}", - string.Concat(http.Request.ServerVariables["SERVER_NAME"], ":", http.Request.Url.Port), - //TODO: RE-enable this so we can have a nice url - /*umbraco.library.NiceUrl(documentObject.Id))*/ - string.Concat(content.Id, ".aspx"), - protocol) - - }; + var bodyVars = new NotificationEmailBodyParams( + mailingUser.Name, + actionName, + content.Name, + content.Id.ToString(CultureInfo.InvariantCulture), + string.Format("{2}://{0}/{1}", + string.Concat(siteUri.Authority), + //TODO: RE-enable this so we can have a nice url + /*umbraco.library.NiceUrl(documentObject.Id))*/ + string.Concat(content.Id, ".aspx"), + protocol), + performingUser.Name, + string.Concat(siteUri.Authority, IOHelper.ResolveUrl(SystemDirectories.Umbraco)), + summary.ToString()); // create the mail message - var mail = new MailMessage(UmbracoConfig.For.UmbracoSettings().Content.NotificationEmailAddress, mailingUser.Email); + var mail = new MailMessage(_contentSection.NotificationEmailAddress, mailingUser.Email); // populate the message - mail.Subject = createSubject(mailingUser, subjectVars); - if (UmbracoConfig.For.UmbracoSettings().Content.DisableHtmlEmail) + + + mail.Subject = createSubject((mailingUser, subjectVars)); + if (_contentSection.DisableHtmlEmail) { mail.IsBodyHtml = false; - mail.Body = createBody(mailingUser, bodyVars); + mail.Body = createBody((user: mailingUser, body: bodyVars, false)); } else { @@ -470,14 +403,14 @@ namespace Umbraco.Core.Services.Implement string.Concat(@" -", createBody(mailingUser, bodyVars)); +", createBody((user: mailingUser, body: bodyVars, true))); } // nh, issue 30724. Due to hardcoded http strings in resource files, we need to check for https replacements here // adding the server name to make sure we don't replace external links if (_globalSettings.UseHttps && string.IsNullOrEmpty(mail.Body) == false) { - string serverName = http.Request.ServerVariables["SERVER_NAME"]; + string serverName = siteUri.Host; mail.Body = mail.Body.Replace( string.Format("http://{0}", serverName), string.Format("https://{0}", serverName)); @@ -486,12 +419,10 @@ namespace Umbraco.Core.Services.Implement return new NotificationRequest(mail, actionName, mailingUser.Name, mailingUser.Email); } - private string ReplaceLinks(string text, HttpRequestBase request) + private string ReplaceLinks(string text, Uri siteUri) { var sb = new StringBuilder(_globalSettings.UseHttps ? "https://" : "http://"); - sb.Append(request.ServerVariables["SERVER_NAME"]); - sb.Append(":"); - sb.Append(request.Url.Port); + sb.Append(siteUri.Authority); sb.Append("/"); var domain = sb.ToString(); text = text.Replace("href=\"/", "href=\"" + domain); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e0aa93efec..ad6e6f9310 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -394,6 +394,8 @@ + + diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index 2707c73607..6d0d14ce11 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -10,6 +10,7 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Events; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -106,6 +107,7 @@ namespace Umbraco.Tests.TestHelpers CacheHelper cache, ILogger logger, IGlobalSettings globalSettings, + IUmbracoSettingsSection umbracoSettings, IEventMessagesFactory eventMessagesFactory, IEnumerable urlSegmentProviders, IServiceFactory container = null) @@ -161,7 +163,7 @@ namespace Umbraco.Tests.TestHelpers var userService = GetLazyService(container, c => new UserService(scopeProvider, logger, eventMessagesFactory, runtimeState, GetRepo(c), GetRepo(c),globalSettings)); var dataTypeService = GetLazyService(container, c => new DataTypeService(scopeProvider, logger, eventMessagesFactory, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); var contentService = GetLazyService(container, c => new ContentService(scopeProvider, logger, eventMessagesFactory, mediaFileSystem, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); - var notificationService = GetLazyService(container, c => new NotificationService(scopeProvider, userService.Value, contentService.Value, logger, GetRepo(c),globalSettings)); + var notificationService = GetLazyService(container, c => new NotificationService(scopeProvider, userService.Value, contentService.Value, logger, GetRepo(c), globalSettings, umbracoSettings.Content)); var serverRegistrationService = GetLazyService(container, c => new ServerRegistrationService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); var memberGroupService = GetLazyService(container, c => new MemberGroupService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); var memberService = GetLazyService(container, c => new MemberService(scopeProvider, logger, eventMessagesFactory, memberGroupService.Value, mediaFileSystem, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js index 4581b78c8c..53759d7d97 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.sort.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function ContentSortController($scope, $filter, contentResource, navigationService) { + function ContentSortController($scope, $filter, $routeParams, contentResource, navigationService) { var vm = this; var parentId = $scope.currentNode.parentId ? $scope.currentNode.parentId : "-1"; @@ -30,7 +30,7 @@ function onInit() { vm.loading = true; - contentResource.getChildren(id) + contentResource.getChildren(id, { cultureName: $routeParams.cculture ? $routeParams.cculture : $routeParams.mculture }) .then(function(data){ vm.children = data.items; vm.loading = false; @@ -79,4 +79,4 @@ } angular.module("umbraco").controller("Umbraco.Editors.Content.SortController", ContentSortController); -})(); \ No newline at end of file +})(); diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index d95d8ca664..55ecd9834c 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -344,12 +344,9 @@ - - - Designer diff --git a/src/Umbraco.Web.UI/Umbraco/dialogs/SendPublish.aspx b/src/Umbraco.Web.UI/Umbraco/dialogs/SendPublish.aspx deleted file mode 100644 index 8b190d575c..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/dialogs/SendPublish.aspx +++ /dev/null @@ -1,13 +0,0 @@ -<%@ Page language="c#" Codebehind="SendPublish.aspx.cs" AutoEventWireup="True" Inherits="umbraco.dialogs.SendPublish" %> - - - - umbraco - <%=Services.TextService.Localize("editContentSendToPublish")%> - - - -

Republish <%=Services.TextService.Localize("editContentSendToPublishText")%>

-
- <%=Services.TextService.Localize("closewindow")%> - - diff --git a/src/Umbraco.Web/Components/NotificationsComponent.cs b/src/Umbraco.Web/Components/NotificationsComponent.cs index 27fc604d29..f0605a7673 100644 --- a/src/Umbraco.Web/Components/NotificationsComponent.cs +++ b/src/Umbraco.Web/Components/NotificationsComponent.cs @@ -1,67 +1,175 @@ using System.Collections.Generic; using Umbraco.Core; +using Umbraco.Core.Logging; using Umbraco.Core.Components; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; using Umbraco.Web._Legacy.Actions; +using Umbraco.Core.Composing; +using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; +using System.Linq; +using Umbraco.Core.Models.Membership; +using System; +using System.Globalization; namespace Umbraco.Web.Components { [RuntimeLevel(MinLevel = RuntimeLevel.Run)] public sealed class NotificationsComponent : UmbracoComponentBase, IUmbracoCoreComponent { - public void Initialize(INotificationService notificationService) + public override void Compose(Composition composition) { - ContentService.SentToPublish += (sender, args) => - notificationService.SendNotification(args.Entity, ActionToPublish.Instance); + base.Compose(composition); + composition.Container.RegisterSingleton(); + } + + public void Initialize(INotificationService notificationService, Notifier notifier) + { + //Send notifications for the send to publish action + ContentService.SentToPublish += (sender, args) => notifier.Notify(ActionToPublish.Instance, args.Entity); //Send notifications for the published action - ContentService.Published += (sender, args) => - { - foreach (var content in args.PublishedEntities) - notificationService.SendNotification(content, ActionPublish.Instance); - }; + ContentService.Published += (sender, args) => notifier.Notify(ActionPublish.Instance, args.PublishedEntities.ToArray()); + + //Send notifications for the saved action + ContentService.Sorted += (sender, args) => ContentServiceSorted(notifier, sender, args); //Send notifications for the update and created actions - ContentService.Saved += (sender, args) => - { - var newEntities = new List(); - var updatedEntities = new List(); - - //need to determine if this is updating or if it is new - foreach (var entity in args.SavedEntities) - { - var dirty = (IRememberBeingDirty) entity; - if (dirty.WasPropertyDirty("Id")) - { - //it's new - newEntities.Add(entity); - } - else - { - //it's updating - updatedEntities.Add(entity); - } - } - notificationService.SendNotification(newEntities, ActionNew.Instance); - notificationService.SendNotification(updatedEntities, ActionUpdate.Instance); - }; + ContentService.Saved += (sender, args) => ContentServiceSaved(notifier, sender, args); //Send notifications for the delete action - ContentService.Deleted += (sender, args) => - { - foreach (var content in args.DeletedEntities) - notificationService.SendNotification(content, ActionDelete.Instance); - }; - + ContentService.Deleted += (sender, args) => notifier.Notify(ActionDelete.Instance, args.DeletedEntities.ToArray()); + //Send notifications for the unpublish action - ContentService.Unpublished += (sender, args) => + ContentService.Unpublished += (sender, args) => notifier.Notify(ActionUnpublish.Instance, args.PublishedEntities.ToArray()); + } + + private void ContentServiceSorted(Notifier notifier, IContentService sender, Core.Events.SaveEventArgs args) + { + var parentId = args.SavedEntities.Select(x => x.ParentId).Distinct().ToList(); + if (parentId.Count != 1) return; // this shouldn't happen, for sorting all entities will have the same parent id + + // in this case there's nothing to report since if the root is sorted we can't report on a fake entity. + // this is how it was in v7, we can't report on root changes because you can't subscribe to root changes. + if (parentId[0] <= 0) return; + + var parent = sender.GetById(parentId[0]); + if (parent == null) return; // this shouldn't happen + + notifier.Notify(ActionSort.Instance, new[] { parent }); + } + + private void ContentServiceSaved(Notifier notifier, IContentService sender, Core.Events.SaveEventArgs args) + { + var newEntities = new List(); + var updatedEntities = new List(); + + //need to determine if this is updating or if it is new + foreach (var entity in args.SavedEntities) { - foreach (var content in args.PublishedEntities) - notificationService.SendNotification(content, ActionUnpublish.Instance); - }; + var dirty = (IRememberBeingDirty)entity; + if (dirty.WasPropertyDirty("Id")) + { + //it's new + newEntities.Add(entity); + } + else + { + //it's updating + updatedEntities.Add(entity); + } + } + notifier.Notify(ActionNew.Instance, newEntities.ToArray()); + notifier.Notify(ActionUpdate.Instance, updatedEntities.ToArray()); + } + + /// + /// This class is used to send the notifications + /// + public sealed class Notifier + { + private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IRuntimeState _runtimeState; + private readonly INotificationService _notificationService; + private readonly IUserService _userService; + private readonly ILocalizedTextService _textService; + private readonly IGlobalSettings _globalSettings; + private readonly IContentSection _contentConfig; + private readonly ILogger _logger; + + /// + /// Constructor + /// + /// + /// + /// + /// + /// + /// + /// + public Notifier(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState, INotificationService notificationService, IUserService userService, ILocalizedTextService textService, IGlobalSettings globalSettings, IContentSection contentConfig, ILogger logger) + { + _umbracoContextAccessor = umbracoContextAccessor; + _runtimeState = runtimeState; + _notificationService = notificationService; + _userService = userService; + _textService = textService; + _globalSettings = globalSettings; + _contentConfig = contentConfig; + _logger = logger; + } + + public void Notify(IAction action, params IUmbracoEntity[] entities) + { + IUser user = null; + if (_umbracoContextAccessor.UmbracoContext != null) + { + user = _umbracoContextAccessor.UmbracoContext.Security.CurrentUser; + } + + //if there is no current user, then use the admin + if (user == null) + { + _logger.Debug(typeof(Notifier), "There is no current Umbraco user logged in, the notifications will be sent from the administrator"); + user = _userService.GetUserById(Constants.Security.SuperUserId); + if (user == null) + { + _logger.Warn(typeof(Notifier), "Noticiations can not be sent, no admin user with id {SuperUserId} could be resolved", Constants.Security.SuperUserId); + return; + } + } + + SendNotification(user, entities, action, _runtimeState.ApplicationUrl); + } + + private void SendNotification(IUser sender, IEnumerable entities, IAction action, Uri siteUri) + { + if (sender == null) throw new ArgumentNullException(nameof(sender)); + if (siteUri == null) throw new ArgumentNullException(nameof(siteUri)); + + _notificationService.SendNotifications( + sender, + entities, + action.Letter.ToString(CultureInfo.InvariantCulture), + _textService.Localize("actions", action.Alias), + siteUri, + ((IUser user, NotificationEmailSubjectParams subject) x) + => _textService.Localize( + "notifications/mailSubject", + x.user.GetUserCulture(_textService, _globalSettings), + new[] { x.subject.SiteUrl, x.subject.Action, x.subject.ItemName }), + ((IUser user, NotificationEmailBodyParams body, bool isHtml) x) + => _textService.Localize( + x.isHtml ? "notifications/mailBodyHtml" : "notifications/mailBody", + x.user.GetUserCulture(_textService, _globalSettings), + new[] { x.body.RecipientName, x.body.Action, x.body.ItemName, x.body.EditedUser, x.body.SiteUrl, x.body.ItemId, x.body.Summary, x.body.ItemUrl })); + } + } } + + } diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 6e095e8393..ea5546b6ea 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1068,17 +1068,14 @@ namespace Umbraco.Web.Editors var contentService = Services.ContentService; // Save content with new sort order and update content xml in db accordingly - if (contentService.Sort(sorted.IdSortOrder, Security.CurrentUser.Id) == false) + var sortResult = contentService.Sort(sorted.IdSortOrder, Security.CurrentUser.Id); + if (!sortResult.Success) { Logger.Warn("Content sorting failed, this was probably caused by an event being cancelled"); + //TODO: Now you can cancel sorting, does the event messages bubble up automatically? return Request.CreateValidationErrorResponse("Content sorting failed, this was probably caused by an event being cancelled"); } - if (sorted.ParentId > 0) - { - Services.NotificationService.SendNotification(contentService.GetById(sorted.ParentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings); - } - return Request.CreateResponse(HttpStatusCode.OK); } catch (Exception ex) diff --git a/src/Umbraco.Web/NotificationServiceExtensions.cs b/src/Umbraco.Web/NotificationServiceExtensions.cs deleted file mode 100644 index 1fb229a66e..0000000000 --- a/src/Umbraco.Web/NotificationServiceExtensions.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Globalization; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; -using Umbraco.Core.Models; -using Umbraco.Web._Legacy.Actions; -using System.Collections.Generic; -using Umbraco.Core.Models.Entities; -using Umbraco.Web.Composing; - -namespace Umbraco.Web -{ - // TODO: all of these require an UmbracoContext because currently to send the notifications we need an HttpContext, this is based on legacy code - // for which probably requires updating so that these can be sent outside of the http context. - - internal static class NotificationServiceExtensions - { - internal static void SendNotification(this INotificationService service, IUmbracoEntity entity, IAction action) - { - if (Current.UmbracoContext == null) - { - Current.Logger.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext"); - return; - } - service.SendNotification(entity, action, Current.UmbracoContext, Current.Services.TextService, UmbracoConfig.For.GlobalSettings()); - } - - internal static void SendNotification(this INotificationService service, IEnumerable entities, IAction action) - { - if (Current.UmbracoContext == null) - { - Current.Logger.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext"); - return; - } - service.SendNotification(entities, action, Current.UmbracoContext, Current.Services.TextService, UmbracoConfig.For.GlobalSettings()); - } - - //internal static void SendNotification(this INotificationService service, IUmbracoEntity entity, IAction action, UmbracoContext umbracoContext) - //{ - // if (umbracoContext == null) - // { - // Current.Logger.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext"); - // return; - // } - // service.SendNotification(entity, action, umbracoContext); - //} - - //internal static void SendNotification(this INotificationService service, IEnumerable entities, IAction action, UmbracoContext umbracoContext) - //{ - // if (umbracoContext == null) - // { - // Current.Logger.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext"); - // return; - // } - // service.SendNotification(entities, action, umbracoContext); - //} - - internal static void SendNotification(this INotificationService service, IUmbracoEntity entity, IAction action, UmbracoContext umbracoContext, ILocalizedTextService textService, IGlobalSettings globalSettings) - { - if (umbracoContext == null) - { - Current.Logger.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext"); - return; - } - - var user = umbracoContext.Security.CurrentUser; - var userService = Current.Services.UserService; // fixme inject - - //if there is no current user, then use the admin - if (user == null) - { - Current.Logger.Debug(typeof(NotificationServiceExtensions), "There is no current Umbraco user logged in, the notifications will be sent from the administrator"); - user = userService.GetUserById(Constants.Security.SuperUserId); - if (user == null) - { - Current.Logger.Warn(typeof(NotificationServiceExtensions), "Noticiations can not be sent, no admin user with id {SuperUserId} could be resolved", Constants.Security.SuperUserId); - return; - } - } - service.SendNotification(user, entity, action, umbracoContext, textService, globalSettings); - } - - internal static void SendNotification(this INotificationService service, IEnumerable entities, IAction action, UmbracoContext umbracoContext, ILocalizedTextService textService, IGlobalSettings globalSettings) - { - if (umbracoContext == null) - { - Current.Logger.Warn(typeof(NotificationServiceExtensions), "Cannot send notifications, there is no current UmbracoContext"); - return; - } - - var user = umbracoContext.Security.CurrentUser; - var userService = Current.Services.UserService; // fixme inject - - //if there is no current user, then use the admin - if (user == null) - { - Current.Logger.Debug(typeof(NotificationServiceExtensions), "There is no current Umbraco user logged in, the notifications will be sent from the administrator"); - user = userService.GetUserById(Constants.Security.SuperUserId); - if (user == null) - { - Current.Logger.Warn(typeof(NotificationServiceExtensions), "Noticiations can not be sent, no admin user with id {SuperUserId} could be resolved", Constants.Security.SuperUserId); - return; - } - } - service.SendNotification(user, entities, action, umbracoContext, textService, globalSettings); - } - - internal static void SendNotification(this INotificationService service, IUser sender, IUmbracoEntity entity, IAction action, UmbracoContext umbracoContext, ILocalizedTextService textService, IGlobalSettings globalSettings) - { - if (sender == null) throw new ArgumentNullException(nameof(sender)); - if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); - - service.SendNotifications( - sender, - entity, - action.Letter.ToString(CultureInfo.InvariantCulture), - textService.Localize("actions", action.Alias), - umbracoContext.HttpContext, - (mailingUser, strings) => textService.Localize("notifications/mailSubject", mailingUser.GetUserCulture(textService, globalSettings), strings), - (mailingUser, strings) => UmbracoConfig.For.UmbracoSettings().Content.DisableHtmlEmail - ? textService.Localize("notifications/mailBody", mailingUser.GetUserCulture(textService, globalSettings), strings) - : textService.Localize("notifications/mailBodyHtml", mailingUser.GetUserCulture(textService, globalSettings), strings)); - } - - internal static void SendNotification(this INotificationService service, IUser sender, IEnumerable entities, IAction action, UmbracoContext umbracoContext, ILocalizedTextService textService, IGlobalSettings globalSettings) - { - if (sender == null) throw new ArgumentNullException(nameof(sender)); - if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); - - service.SendNotifications( - sender, - entities, - action.Letter.ToString(CultureInfo.InvariantCulture), - textService.Localize("actions", action.Alias), - umbracoContext.HttpContext, - (mailingUser, strings) => textService.Localize("notifications/mailSubject", mailingUser.GetUserCulture(textService, globalSettings), strings), - (mailingUser, strings) => UmbracoConfig.For.UmbracoSettings().Content.DisableHtmlEmail - ? textService.Localize("notifications/mailBody", mailingUser.GetUserCulture(textService, globalSettings), strings) - : textService.Localize("notifications/mailBodyHtml", mailingUser.GetUserCulture(textService, globalSettings), strings)); - } - } -} diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index 131c7954c8..663a6904e9 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -49,6 +49,8 @@ namespace Umbraco.Web.Trees /// internal static Attempt GetUrlAndTitleFromLegacyAction(IAction action, string nodeId, string nodeType, string nodeName, string currentSection) { + //TODO: DO we need any of this anymore? + if (action.JsFunctionName.IsNullOrWhiteSpace()) { return Attempt.Fail(); @@ -71,41 +73,16 @@ namespace Umbraco.Web.Trees new LegacyUrlAction( "dialogs/protectPage.aspx?mode=cut&nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, Current.Services.TextService.Localize("actions/protect"))); - case "UmbClientMgr.appActions().actionRollback()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/rollback.aspx?nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/rollback"))); case "UmbClientMgr.appActions().actionNotify()": return Attempt.Succeed( new LegacyUrlAction( "dialogs/notifications.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, Current.Services.TextService.Localize("actions/notify"))); - case "UmbClientMgr.appActions().actionPublish()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/publish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/publish"))); case "UmbClientMgr.appActions().actionChangeDocType()": return Attempt.Succeed( new LegacyUrlAction( "dialogs/ChangeDocType.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, Current.Services.TextService.Localize("actions/changeDocType"))); - case "UmbClientMgr.appActions().actionToPublish()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/SendPublish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/sendtopublish"))); - case "UmbClientMgr.appActions().actionRePublish()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/republish.aspx?rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/republish"))); - case "UmbClientMgr.appActions().actionSendToTranslate()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/sendToTranslation.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/sendToTranslate"))); } return Attempt.Fail(); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 8986f7eff6..0d40846fae 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -777,7 +777,6 @@ - @@ -1295,13 +1294,6 @@ republish.aspx - - SendPublish.aspx - ASPXCodeBehind - - - SendPublish.aspx - editPackage.aspx ASPXCodeBehind @@ -1370,7 +1362,6 @@ ASPXCodeBehind - ASPXCodeBehind diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx deleted file mode 100644 index 8b190d575c..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx +++ /dev/null @@ -1,13 +0,0 @@ -<%@ Page language="c#" Codebehind="SendPublish.aspx.cs" AutoEventWireup="True" Inherits="umbraco.dialogs.SendPublish" %> - - - - umbraco - <%=Services.TextService.Localize("editContentSendToPublish")%> - - - -

Republish <%=Services.TextService.Localize("editContentSendToPublishText")%>

-
- <%=Services.TextService.Localize("closewindow")%> - - diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs deleted file mode 100644 index 727af897ca..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using Umbraco.Web; -using Umbraco.Core; -using Umbraco.Web._Legacy.Actions; - -namespace umbraco.dialogs -{ - /// - /// Runs all action handlers for the ActionToPublish action for the document with - /// the corresponding document id passed in by query string - /// - public partial class SendPublish : Umbraco.Web.UI.Pages.UmbracoEnsuredPage - { - public SendPublish() - { - CurrentApp = Constants.Applications.Content.ToString(); - } - - protected void Page_Load(object sender, EventArgs e) - { - if (!string.IsNullOrEmpty(Request.QueryString["id"])) - { - int docId; - if (int.TryParse(Request.QueryString["id"], out docId)) - { - //send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here - Services.NotificationService.SendNotification( - Services.ContentService.GetById(docId), ActionToPublish.Instance); - } - - } - - } - - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.designer.cs deleted file mode 100644 index 36e42291f7..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.designer.cs +++ /dev/null @@ -1,16 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.4200 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.dialogs { - - - public partial class SendPublish { - } -} From e2557697bcee66cc4075a071a5c573eae4d1d659 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 14:08:15 +0100 Subject: [PATCH 080/337] Emit a single event if the language has been created or been saved - send through a new property in args to determine if it was new or not Then event listener updates the tree languages dropdown only when a new language has been added or deleted OR when an existing language has been saved/updated to be set as the new default language (as this now at top of list) --- .../src/controllers/navigation.controller.js | 21 ++++++++++++++----- .../src/views/languages/edit.controller.js | 12 +++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index 2912755ce7..5d8f46c6db 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -194,7 +194,7 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar $rootScope.emptySection = false; } } - + })); //Listen for section state changes @@ -222,10 +222,21 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar }); })); - evts.push(eventsService.on("editors.languages.languageCreated", function (e, args) { - loadLanguages().then(function (languages) { - $scope.languages = languages; - }); + //Emitted when a language is created or an existing one saved/edited + evts.push(eventsService.on("editors.languages.languageSaved", function (e, args) { + console.log('lang event listen args', args); + if(args.isNew){ + //A new language has been created - reload languages for tree + loadLanguages().then(function (languages) { + $scope.languages = languages; + }); + } + else if(args.language.isDefault){ + //A language was saved and was set to be the new default (refresh the tree, so its at the top) + loadLanguages().then(function (languages) { + $scope.languages = languages; + }); + } })); //This reacts to clicks passed to the body element which emits a global call to close all dialogs diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js index 961470b03a..a11aa8bff8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js @@ -113,11 +113,9 @@ notificationsService.success(value); }); - // emit event when language is created - if($routeParams.create) { - var args = { language: lang }; - eventsService.emit("editors.languages.languageCreated", args); - } + // emit event when language is created or updated/saved + var args = { language: lang, isNew: $routeParams.create ? true : false }; + eventsService.emit("editors.languages.languageSaved", args); back(); @@ -129,7 +127,7 @@ }); } - + } function back() { @@ -145,7 +143,7 @@ } function toggleDefault() { - + // it shouldn't be possible to uncheck the default language if(vm.initIsDefault) { return; From b716ed196467708c1af2e164e58cccfea9efa436 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 25 Oct 2018 00:28:37 +1100 Subject: [PATCH 081/337] Fixes UI error when there is an unathorized request, fixes NotificationService to accept IContent since that's all it supports --- src/Umbraco.Core/Services/INotificationService.cs | 2 +- .../Services/Implement/NotificationService.cs | 10 ++-------- .../src/common/interceptors/security.interceptor.js | 7 ++----- src/Umbraco.Web/Components/NotificationsComponent.cs | 4 ++-- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Core/Services/INotificationService.cs b/src/Umbraco.Core/Services/INotificationService.cs index 92a1e93e2f..a990b1e0ff 100644 --- a/src/Umbraco.Core/Services/INotificationService.cs +++ b/src/Umbraco.Core/Services/INotificationService.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Services /// /// /// - void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, Uri siteUri, + void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, Uri siteUri, Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject, Func<(IUser user, NotificationEmailBodyParams body, bool isHtml), string> createBody); diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index 12e575d903..0bc2f993d7 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -66,17 +66,11 @@ namespace Umbraco.Core.Services.Implement /// /// /// - /// - /// Currently this will only work for Content entities! - /// - public void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, Uri siteUri, + public void SendNotifications(IUser operatingUser, IEnumerable entities, string action, string actionName, Uri siteUri, Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject, Func<(IUser user, NotificationEmailBodyParams body, bool isHtml), string> createBody) { - if (entities is IEnumerable == false) - throw new NotSupportedException(); - - var entitiesL = entities as List ?? entities.Cast().ToList(); + var entitiesL = entities.ToList(); //exit if there are no entities if (entitiesL.Count == 0) return; diff --git a/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js b/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js index b636a0a51c..13d5fbc057 100644 --- a/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js +++ b/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js @@ -102,11 +102,8 @@ //It was decided to just put these messages into the normal status messages. - var msg = "Unauthorized access to URL:
" + rejection.config.url.split('?')[0] + ""; - if (rejection.config.data) { - msg += "
with data:
" + angular.toJson(rejection.config.data) + "
Contact your administrator for information."; - } - + var msg = "Unauthorized access to URL:
" + rejection.config.url.split('?')[0] + "
Contact your administrator for information."; + notificationsService.error("Authorization error", msg); } diff --git a/src/Umbraco.Web/Components/NotificationsComponent.cs b/src/Umbraco.Web/Components/NotificationsComponent.cs index f0605a7673..7eaaf0e18c 100644 --- a/src/Umbraco.Web/Components/NotificationsComponent.cs +++ b/src/Umbraco.Web/Components/NotificationsComponent.cs @@ -122,7 +122,7 @@ namespace Umbraco.Web.Components _logger = logger; } - public void Notify(IAction action, params IUmbracoEntity[] entities) + public void Notify(IAction action, params IContent[] entities) { IUser user = null; if (_umbracoContextAccessor.UmbracoContext != null) @@ -145,7 +145,7 @@ namespace Umbraco.Web.Components SendNotification(user, entities, action, _runtimeState.ApplicationUrl); } - private void SendNotification(IUser sender, IEnumerable entities, IAction action, Uri siteUri) + private void SendNotification(IUser sender, IEnumerable entities, IAction action, Uri siteUri) { if (sender == null) throw new ArgumentNullException(nameof(sender)); if (siteUri == null) throw new ArgumentNullException(nameof(siteUri)); From c3e50ecc48359da9e8cd73dd339efd7f0b258ef4 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 25 Oct 2018 00:45:45 +1100 Subject: [PATCH 082/337] Removes the broken text comparison for RTE --- .../Services/Implement/NotificationService.cs | 115 ++---------------- 1 file changed, 11 insertions(+), 104 deletions(-) diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index 0bc2f993d7..5d7860026b 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -313,47 +313,15 @@ namespace Umbraco.Core.Services.Implement ReplaceHtmlSymbols(ref newText); } - - // make sure to only highlight changes done using TinyMCE editor... other changes will be displayed using default summary - // TODO: We should probably allow more than just tinymce?? - if ((p.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.TinyMce) - && string.CompareOrdinal(oldText, newText) != 0) - { - summary.Append(""); - summary.Append(" Note: "); - summary.Append( - " Red for deleted characters Yellow for inserted characters"); - summary.Append(""); - summary.Append(""); - summary.Append(" New "); - summary.Append(p.PropertyType.Name); - summary.Append(""); - summary.Append(""); - summary.Append(ReplaceLinks(CompareText(oldText, newText, true, false, "", string.Empty), siteUri)); - summary.Append(""); - summary.Append(""); - summary.Append(""); - summary.Append(" Old "); - summary.Append(p.PropertyType.Name); - summary.Append(""); - summary.Append(""); - summary.Append(ReplaceLinks(CompareText(newText, oldText, true, false, "", string.Empty), siteUri)); - summary.Append(""); - summary.Append(""); - } - else - { - summary.Append(""); - summary.Append(""); - summary.Append(p.PropertyType.Name); - summary.Append(""); - summary.Append(""); - summary.Append(newText); - summary.Append(""); - summary.Append(""); - } - summary.Append( - " "); + //show the values + summary.Append(""); + summary.Append(""); + summary.Append(p.PropertyType.Name); + summary.Append(""); + summary.Append(""); + summary.Append(newText); + summary.Append(""); + summary.Append(""); } var protocol = _globalSettings.UseHttps ? "https" : "http"; @@ -430,6 +398,7 @@ namespace Umbraco.Core.Services.Implement /// The old string. private static void ReplaceHtmlSymbols(ref string oldString) { + if (oldString.IsNullOrWhiteSpace()) return; oldString = oldString.Replace(" ", " "); oldString = oldString.Replace("’", "'"); oldString = oldString.Replace("&", "&"); @@ -437,69 +406,7 @@ namespace Umbraco.Core.Services.Implement oldString = oldString.Replace("”", "”"); oldString = oldString.Replace(""", "\""); } - - /// - /// Compares the text. - /// - /// The old text. - /// The new text. - /// if set to true [display inserted text]. - /// if set to true [display deleted text]. - /// The inserted style. - /// The deleted style. - /// - private static string CompareText(string oldText, string newText, bool displayInsertedText, - bool displayDeletedText, string insertedStyle, string deletedStyle) - { - var sb = new StringBuilder(); - var diffs = Diff.DiffText1(oldText, newText); - - int pos = 0; - for (var n = 0; n < diffs.Length; n++) - { - var it = diffs[n]; - - // write unchanged chars - while ((pos < it.StartB) && (pos < newText.Length)) - { - sb.Append(newText[pos]); - pos++; - } // while - - // write deleted chars - if (displayDeletedText && it.DeletedA > 0) - { - sb.Append(deletedStyle); - for (var m = 0; m < it.DeletedA; m++) - { - sb.Append(oldText[it.StartA + m]); - } // for - sb.Append(""); - } - - // write inserted chars - if (displayInsertedText && pos < it.StartB + it.InsertedB) - { - sb.Append(insertedStyle); - while (pos < it.StartB + it.InsertedB) - { - sb.Append(newText[pos]); - pos++; - } // while - sb.Append(""); - } // if - } // while - - // write rest of unchanged chars - while (pos < newText.Length) - { - sb.Append(newText[pos]); - pos++; - } // while - - return sb.ToString(); - } - + // manage notifications // ideally, would need to use IBackgroundTasks - but they are not part of Core! From 9a1a13ba81f601919f87e4a24dc63d6183ee77c8 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 24 Oct 2018 14:55:01 +0100 Subject: [PATCH 083/337] Fix the ordering logic - it helps if you actually assign the ordered items back to the list *facepalm* --- .../Models/Mapping/ContentItemDisplayVariationResolver.cs | 2 +- src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs index 562797e3e3..7db491ad2e 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs @@ -59,7 +59,7 @@ namespace Umbraco.Web.Models.Mapping variants.Remove(defaultLang); //Sort the remaining languages a-z - variants.OrderBy(x => x.Language.Name); + variants = variants.OrderBy(x => x.Name).ToList(); //Insert the default lang as the first item variants.Insert(0, defaultLang); diff --git a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs index 6dd6135329..f820d5ae54 100644 --- a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs @@ -37,7 +37,7 @@ namespace Umbraco.Web.Models.Mapping langs.Remove(defaultLang); //Sort the remaining languages a-z - langs.OrderBy(x => x.Name); + langs = langs.OrderBy(x => x.Name).ToList(); //Insert the default lang as the first item langs.Insert(0, defaultLang); From 63fbe6365609960c75da7f8c52868a2baf1e1209 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 25 Oct 2018 01:01:42 +1100 Subject: [PATCH 084/337] Fixes js error and removes Current usage --- .../validation/valsubview.directive.js | 128 +++++++++--------- .../Editors/BackOfficeController.cs | 6 +- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valsubview.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valsubview.directive.js index 097602fe20..d5a21e0ba6 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valsubview.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valsubview.directive.js @@ -5,74 +5,78 @@ * @description Used to show validation warnings for a editor sub view to indicate that the section content has validation errors in its data. * In order for this directive to work, the valFormManager directive must be placed on the containing form. **/ -(function() { - 'use strict'; +(function () { + 'use strict'; - function valSubViewDirective() { + function valSubViewDirective() { - function controller($scope, $element) { - //expose api - return { - valStatusChanged: function(args) { - if (!args.form.$valid) { - var subViewContent = $element.find(".ng-invalid"); + function controller($scope, $element) { + //expose api + return { + valStatusChanged: function (args) { - if (subViewContent.length > 0) { - $scope.model.hasError = true; - $scope.model.errorClass = args.showValidation ? 'show-validation' : null; - } else { - $scope.model.hasError = false; - $scope.model.errorClass = null; + //TODO: Verify this is correct, does $scope.model ever exist? + if ($scope.model) { + if (!args.form.$valid) { + var subViewContent = $element.find(".ng-invalid"); + + if (subViewContent.length > 0) { + $scope.model.hasError = true; + $scope.model.errorClass = args.showValidation ? 'show-validation' : null; + } else { + $scope.model.hasError = false; + $scope.model.errorClass = null; + } + } + else { + $scope.model.hasError = false; + $scope.model.errorClass = null; + } + } + } } - } - else { - $scope.model.hasError = false; - $scope.model.errorClass = null; - } } - } + + function link(scope, el, attr, ctrl) { + + //if there are no containing form or valFormManager controllers, then we do nothing + if (!ctrl || !angular.isArray(ctrl) || ctrl.length !== 2 || !ctrl[0] || !ctrl[1]) { + return; + } + + var valFormManager = ctrl[1]; + scope.model.hasError = false; + + //listen for form validation changes + valFormManager.onValidationStatusChanged(function (evt, args) { + if (!args.form.$valid) { + + var subViewContent = el.find(".ng-invalid"); + + if (subViewContent.length > 0) { + scope.model.hasError = true; + } else { + scope.model.hasError = false; + } + + } + else { + scope.model.hasError = false; + } + }); + + } + + var directive = { + require: ['?^^form', '?^^valFormManager'], + restrict: "A", + link: link, + controller: controller + }; + + return directive; } - function link(scope, el, attr, ctrl) { - - //if there are no containing form or valFormManager controllers, then we do nothing - if (!ctrl || !angular.isArray(ctrl) || ctrl.length !== 2 || !ctrl[0] || !ctrl[1]) { - return; - } - - var valFormManager = ctrl[1]; - scope.model.hasError = false; - - //listen for form validation changes - valFormManager.onValidationStatusChanged(function (evt, args) { - if (!args.form.$valid) { - - var subViewContent = el.find(".ng-invalid"); - - if (subViewContent.length > 0) { - scope.model.hasError = true; - } else { - scope.model.hasError = false; - } - - } - else { - scope.model.hasError = false; - } - }); - - } - - var directive = { - require: ['?^^form', '?^^valFormManager'], - restrict: "A", - link: link, - controller: controller - }; - - return directive; - } - - angular.module('umbraco.directives').directive('valSubView', valSubViewDirective); + angular.module('umbraco.directives').directive('valSubView', valSubViewDirective); })(); diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 15554b7f50..8a81cedc2d 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -49,6 +49,7 @@ namespace Umbraco.Web.Editors { private readonly ManifestParser _manifestParser; private readonly UmbracoFeatures _features; + private readonly IRuntimeState _runtimeState; private BackOfficeUserManager _userManager; private BackOfficeSignInManager _signInManager; @@ -56,10 +57,11 @@ namespace Umbraco.Web.Editors private const string TokenPasswordResetCode = "PasswordResetCode"; private static readonly string[] TempDataTokenNames = { TokenExternalSignInError, TokenPasswordResetCode }; - public BackOfficeController(ManifestParser manifestParser, UmbracoFeatures features) + public BackOfficeController(ManifestParser manifestParser, UmbracoFeatures features, IRuntimeState runtimeState) { _manifestParser = manifestParser; _features = features; + _runtimeState = runtimeState; } protected BackOfficeSignInManager SignInManager => _signInManager ?? (_signInManager = OwinContext.GetBackOfficeSignInManager()); @@ -261,7 +263,7 @@ namespace Umbraco.Web.Editors [MinifyJavaScriptResult(Order = 1)] public JavaScriptResult ServerVariables() { - var serverVars = new BackOfficeServerVariables(Url, Current.RuntimeState, _features, GlobalSettings); + var serverVars = new BackOfficeServerVariables(Url, _runtimeState, _features, GlobalSettings); //cache the result if debugging is disabled var result = HttpContext.IsDebuggingEnabled From 4420f101d2a8654c6201f58d0144a2e6abbe3db0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 24 Oct 2018 20:41:58 +0200 Subject: [PATCH 085/337] add toggle to disable tabindex directive --- .../util/disabletabindex.directive.js | 49 ++++++++++--------- .../property/umb-property-editor.html | 8 +-- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js index 35b49d0ddf..800efb8c28 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/disabletabindex.directive.js @@ -2,39 +2,44 @@ angular.module("umbraco.directives") .directive('disableTabindex', function (tabbableService) { return { - restrict: 'A', //Can only be used as an attribute + restrict: 'A', //Can only be used as an attribute, + scope: { + "disableTabindex": "<" + }, link: function (scope, element, attrs) { - //Select the node that will be observed for mutations (native DOM element not jQLite version) - var targetNode = element[0]; + if(scope.disableTabindex) { + //Select the node that will be observed for mutations (native DOM element not jQLite version) + var targetNode = element[0]; - //Watch for DOM changes - so when the property editor subview loads in - //We can be notified its updated the child elements inside the DIV we are watching - var observer = new MutationObserver(domChange); + //Watch for DOM changes - so when the property editor subview loads in + //We can be notified its updated the child elements inside the DIV we are watching + var observer = new MutationObserver(domChange); - // Options for the observer (which mutations to observe) - var config = { attributes: true, childList: true, subtree: false }; + // Options for the observer (which mutations to observe) + var config = { attributes: true, childList: true, subtree: false }; - function domChange(mutationsList, observer){ - for(var mutation of mutationsList) { + function domChange(mutationsList, observer){ + for(var mutation of mutationsList) { - //DOM items have been added or removed - if (mutation.type == 'childList') { + //DOM items have been added or removed + if (mutation.type == 'childList') { - //Check if any child items in mutation.target contain an input - var childInputs = tabbableService.tabbable(mutation.target); + //Check if any child items in mutation.target contain an input + var childInputs = tabbableService.tabbable(mutation.target); - //For each item in childInputs - override or set HTML attribute tabindex="-1" - angular.forEach(childInputs, function(element){ - angular.element(element).attr('tabindex', '-1'); - }); + //For each item in childInputs - override or set HTML attribute tabindex="-1" + angular.forEach(childInputs, function(element){ + angular.element(element).attr('tabindex', '-1'); + }); + } } } - } - // Start observing the target node for configured mutations - //GO GO GO - observer.observe(targetNode, config); + // Start observing the target node for configured mutations + //GO GO GO + observer.observe(targetNode, config); + } } }; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html index cb82a83168..8674e4f6d3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html @@ -1,4 +1,6 @@ -
-
-
+
+
+
+
+
From 2137c1026b1bcfa674cb14ef3940980af144068e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 24 Oct 2018 20:44:07 +0200 Subject: [PATCH 086/337] css cleanup --- .../less/components/umb-property-editor.less | 21 +++++++------------ .../property/umb-property-editor.html | 2 +- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less index b019892a9f..a3e094d9be 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-editor.less @@ -1,24 +1,19 @@ -.umb-property-editor.-not-clickable { - // pointer-events: none; -} - .umb-property-editor { - position:relative; + position: relative; } .umb-property-editor__view{ - z-index:1; - position:relative; + z-index: 1; + position: relative; } .umb-property-editor__overlay { display: block; position: absolute; - top:0; - left:0; - height:100%; - width:100%; - cursor: not-allowed; + top: 0; + left: 0; + height: 100%; + width: 100%; user-select: none; - z-index:2; + z-index: 2; } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html index 8674e4f6d3..820721df9e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-editor.html @@ -1,4 +1,4 @@ -
+
From 42f0d2b356f02de5e6d156324fa2776100254f6f Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 25 Oct 2018 15:47:25 +1100 Subject: [PATCH 087/337] Fixes dirty tracking with resetting properties --- src/Umbraco.Core/Models/Content.cs | 23 ++++++--------- src/Umbraco.Core/Models/ContentBase.cs | 29 ++++++++----------- src/Umbraco.Core/Models/ContentTypeBase.cs | 28 +++++++----------- .../Models/ContentTypeCompositionBase.cs | 19 +++++------- .../Models/DictionaryTranslation.cs | 19 ++++-------- .../Models/Entities/EntityBase.cs | 21 ++++++++++---- src/Umbraco.Core/Models/File.cs | 21 ++++---------- src/Umbraco.Core/Models/Macro.cs | 24 +++++++-------- src/Umbraco.Core/Models/Member.cs | 19 +++++------- src/Umbraco.Core/Models/Membership/User.cs | 29 ++++++++----------- src/Umbraco.Core/Models/Property.cs | 15 +++------- src/Umbraco.Core/Models/PropertyGroup.cs | 20 +++++-------- src/Umbraco.Core/Models/PropertyType.cs | 17 ++++------- src/Umbraco.Core/Models/PublicAccessEntry.cs | 18 ++++-------- 14 files changed, 117 insertions(+), 185 deletions(-) diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index 3e5becf021..d46e318aea 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -499,28 +499,23 @@ namespace Umbraco.Core.Models return clone; } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (Content) base.DeepClone(); + base.PerformDeepClone(clone); - //turn off change tracking - clone.DisableChangeTracking(); + var clonedContent = (Content)clone; //need to manually clone this since it's not settable - clone._contentType = (IContentType) ContentType.DeepClone(); + clonedContent._contentType = (IContentType) ContentType.DeepClone(); //if culture infos exist then deal with event bindings - if (clone._publishInfos != null) + if (clonedContent._publishInfos != null) { - clone._publishInfos.CollectionChanged -= PublishNamesCollectionChanged; //clear this event handler if any - clone._publishInfos = (ContentCultureInfosCollection) _publishInfos.DeepClone(); //manually deep clone - clone._publishInfos.CollectionChanged += clone.PublishNamesCollectionChanged; //re-assign correct event handler + clonedContent._publishInfos.CollectionChanged -= PublishNamesCollectionChanged; //clear this event handler if any + clonedContent._publishInfos = (ContentCultureInfosCollection) _publishInfos.DeepClone(); //manually deep clone + clonedContent._publishInfos.CollectionChanged += clonedContent.PublishNamesCollectionChanged; //re-assign correct event handler } - - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; + } } } diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 863374726d..7e70238d2f 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -475,33 +475,28 @@ namespace Umbraco.Core.Models /// /// Overriden to deal with specific object instances /// - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (ContentBase) base.DeepClone(); + base.PerformDeepClone(clone); - //turn off change tracking - clone.DisableChangeTracking(); + var clonedContent = (ContentBase)clone; //if culture infos exist then deal with event bindings - if (clone._cultureInfos != null) + if (clonedContent._cultureInfos != null) { - clone._cultureInfos.CollectionChanged -= CultureInfosCollectionChanged; //clear this event handler if any - clone._cultureInfos = (ContentCultureInfosCollection) _cultureInfos.DeepClone(); //manually deep clone - clone._cultureInfos.CollectionChanged += clone.CultureInfosCollectionChanged; //re-assign correct event handler + clonedContent._cultureInfos.CollectionChanged -= CultureInfosCollectionChanged; //clear this event handler if any + clonedContent._cultureInfos = (ContentCultureInfosCollection) _cultureInfos.DeepClone(); //manually deep clone + clonedContent._cultureInfos.CollectionChanged += clonedContent.CultureInfosCollectionChanged; //re-assign correct event handler } //if properties exist then deal with event bindings - if (clone._properties != null) + if (clonedContent._properties != null) { - clone._properties.CollectionChanged -= PropertiesChanged; //clear this event handler if any - clone._properties = (PropertyCollection) _properties.DeepClone(); //manually deep clone - clone._properties.CollectionChanged += clone.PropertiesChanged; //re-assign correct event handler + clonedContent._properties.CollectionChanged -= PropertiesChanged; //clear this event handler if any + clonedContent._properties = (PropertyCollection) _properties.DeepClone(); //manually deep clone + clonedContent._properties.CollectionChanged += clonedContent.PropertiesChanged; //re-assign correct event handler } - - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; + } } } diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs index 9f848c6d14..caa63d7526 100644 --- a/src/Umbraco.Core/Models/ContentTypeBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeBase.cs @@ -467,35 +467,29 @@ namespace Umbraco.Core.Models } } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (ContentTypeBase) base.DeepClone(); + base.PerformDeepClone(clone); - //turn off change tracking - clone.DisableChangeTracking(); + var clonedEntity = (ContentTypeBase) clone; - if (clone._noGroupPropertyTypes != null) + if (clonedEntity._noGroupPropertyTypes != null) { //need to manually wire up the event handlers for the property type collections - we've ensured // its ignored from the auto-clone process because its return values are unions, not raw and // we end up with duplicates, see: http://issues.umbraco.org/issue/U4-4842 - clone._noGroupPropertyTypes.CollectionChanged -= PropertyTypesChanged; //clear this event handler if any - clone._noGroupPropertyTypes = (PropertyTypeCollection) _noGroupPropertyTypes.DeepClone(); //manually deep clone - clone._noGroupPropertyTypes.CollectionChanged += clone.PropertyTypesChanged; //re-assign correct event handler + clonedEntity._noGroupPropertyTypes.CollectionChanged -= PropertyTypesChanged; //clear this event handler if any + clonedEntity._noGroupPropertyTypes = (PropertyTypeCollection) _noGroupPropertyTypes.DeepClone(); //manually deep clone + clonedEntity._noGroupPropertyTypes.CollectionChanged += clonedEntity.PropertyTypesChanged; //re-assign correct event handler } - if (clone._propertyGroups != null) + if (clonedEntity._propertyGroups != null) { - clone._propertyGroups.CollectionChanged -= PropertyGroupsChanged; //clear this event handler if any - clone._propertyGroups = (PropertyGroupCollection) _propertyGroups.DeepClone(); //manually deep clone - clone._propertyGroups.CollectionChanged += clone.PropertyGroupsChanged; //re-assign correct event handler + clonedEntity._propertyGroups.CollectionChanged -= PropertyGroupsChanged; //clear this event handler if any + clonedEntity._propertyGroups = (PropertyGroupCollection) _propertyGroups.DeepClone(); //manually deep clone + clonedEntity._propertyGroups.CollectionChanged += clonedEntity.PropertyGroupsChanged; //re-assign correct event handler } - - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; } public IContentType DeepCloneWithResetIdentities(string alias) diff --git a/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs b/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs index 838a75b98b..cf43b661c7 100644 --- a/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs @@ -290,20 +290,15 @@ namespace Umbraco.Core.Models .Union(ContentTypeComposition.SelectMany(x => x.CompositionIds())); } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (ContentTypeCompositionBase)base.DeepClone(); - //turn off change tracking - clone.DisableChangeTracking(); - //need to manually assign since this is an internal field and will not be automatically mapped - clone.RemovedContentTypeKeyTracker = new List(); - clone._contentTypeComposition = ContentTypeComposition.Select(x => (IContentTypeComposition)x.DeepClone()).ToList(); - //this shouldn't really be needed since we're not tracking - clone.ResetDirtyProperties(false); - //re-enable tracking - clone.EnableChangeTracking(); + base.PerformDeepClone(clone); - return clone; + var clonedEntity = (ContentTypeCompositionBase)clone; + + //need to manually assign since this is an internal field and will not be automatically mapped + clonedEntity.RemovedContentTypeKeyTracker = new List(); + clonedEntity._contentTypeComposition = ContentTypeComposition.Select(x => (IContentTypeComposition)x.DeepClone()).ToList(); } } } diff --git a/src/Umbraco.Core/Models/DictionaryTranslation.cs b/src/Umbraco.Core/Models/DictionaryTranslation.cs index 2105e8057c..c3b5a8a3b2 100644 --- a/src/Umbraco.Core/Models/DictionaryTranslation.cs +++ b/src/Umbraco.Core/Models/DictionaryTranslation.cs @@ -104,23 +104,14 @@ namespace Umbraco.Core.Models set { SetPropertyValueAndDetectChanges(value, ref _value, Ps.Value.ValueSelector); } } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (DictionaryTranslation)base.DeepClone(); + base.PerformDeepClone(clone); + + var clonedEntity = (DictionaryTranslation)clone; // clear fields that were memberwise-cloned and that we don't want to clone - clone._language = null; - - // turn off change tracking - clone.DisableChangeTracking(); - - // this shouldn't really be needed since we're not tracking - clone.ResetDirtyProperties(false); - - // re-enable tracking - clone.EnableChangeTracking(); - - return clone; + clonedEntity._language = null; } } } diff --git a/src/Umbraco.Core/Models/Entities/EntityBase.cs b/src/Umbraco.Core/Models/Entities/EntityBase.cs index 0b69586abf..5c6f943c60 100644 --- a/src/Umbraco.Core/Models/Entities/EntityBase.cs +++ b/src/Umbraco.Core/Models/Entities/EntityBase.cs @@ -159,7 +159,7 @@ namespace Umbraco.Core.Models.Entities } } - public virtual object DeepClone() + public object DeepClone() { // memberwise-clone (ie shallow clone) the entity var unused = Key; // ensure that 'this' has a key, before cloning @@ -169,20 +169,29 @@ namespace Umbraco.Core.Models.Entities clone.InstanceId = Guid.NewGuid(); #endif - // clear changes (ensures the clone has its own dictionaries) - // then disable change tracking - clone.ResetDirtyProperties(false); + //disable change tracking while we deep clone IDeepCloneable properties clone.DisableChangeTracking(); // deep clone ref properties that are IDeepCloneable DeepCloneHelper.DeepCloneRefProperties(this, clone); - // clear changes again (just to be sure, because we were not tracking) - // then enable change tracking + PerformDeepClone(clone); + + // clear changes (ensures the clone has its own dictionaries) clone.ResetDirtyProperties(false); + + //re-enable change tracking clone.EnableChangeTracking(); return clone; } + + /// + /// Used by inheritors to modify the DeepCloning logic + /// + /// + protected virtual void PerformDeepClone(object clone) + { + } } } diff --git a/src/Umbraco.Core/Models/File.cs b/src/Umbraco.Core/Models/File.cs index 2e85b13261..2f8e021f4c 100644 --- a/src/Umbraco.Core/Models/File.cs +++ b/src/Umbraco.Core/Models/File.cs @@ -156,26 +156,17 @@ namespace Umbraco.Core.Models clone._alias = Alias; } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (File) base.DeepClone(); + base.PerformDeepClone(clone); + + var clonedFile = (File)clone; // clear fields that were memberwise-cloned and that we don't want to clone - clone._content = null; - - // turn off change tracking - clone.DisableChangeTracking(); + clonedFile._content = null; // ... - DeepCloneNameAndAlias(clone); - - // this shouldn't really be needed since we're not tracking - clone.ResetDirtyProperties(false); - - // re-enable tracking - clone.EnableChangeTracking(); - - return clone; + DeepCloneNameAndAlias(clonedFile); } } } diff --git a/src/Umbraco.Core/Models/Macro.cs b/src/Umbraco.Core/Models/Macro.cs index 6e68bda439..5ef49305ac 100644 --- a/src/Umbraco.Core/Models/Macro.cs +++ b/src/Umbraco.Core/Models/Macro.cs @@ -284,22 +284,18 @@ namespace Umbraco.Core.Models get { return _properties; } } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (Macro)base.DeepClone(); - //turn off change tracking - clone.DisableChangeTracking(); - clone._addedProperties = new List(); - clone._removedProperties = new List(); - clone._properties = (MacroPropertyCollection)Properties.DeepClone(); - //re-assign the event handler - clone._properties.CollectionChanged += clone.PropertiesChanged; - //this shouldn't really be needed since we're not tracking - clone.ResetDirtyProperties(false); - //re-enable tracking - clone.EnableChangeTracking(); + base.PerformDeepClone(clone); - return clone; + var clonedEntity = (Macro)clone; + + clonedEntity._addedProperties = new List(); + clonedEntity._removedProperties = new List(); + clonedEntity._properties = (MacroPropertyCollection)Properties.DeepClone(); + //re-assign the event handler + clonedEntity._properties.CollectionChanged += clonedEntity.PropertiesChanged; + } } } diff --git a/src/Umbraco.Core/Models/Member.cs b/src/Umbraco.Core/Models/Member.cs index 7576f01ce0..38927898cf 100644 --- a/src/Umbraco.Core/Models/Member.cs +++ b/src/Umbraco.Core/Models/Member.cs @@ -598,20 +598,15 @@ namespace Umbraco.Core.Models return true; } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (Member)base.DeepClone(); - //turn off change tracking - clone.DisableChangeTracking(); + base.PerformDeepClone(clone); + + var clonedEntity = (Member)clone; + //need to manually clone this since it's not settable - clone._contentType = (IMemberType)ContentType.DeepClone(); - //this shouldn't really be needed since we're not tracking - clone.ResetDirtyProperties(false); - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; - + clonedEntity._contentType = (IMemberType)ContentType.DeepClone(); + } /// diff --git a/src/Umbraco.Core/Models/Membership/User.cs b/src/Umbraco.Core/Models/Membership/User.cs index 9066674193..0694194996 100644 --- a/src/Umbraco.Core/Models/Membership/User.cs +++ b/src/Umbraco.Core/Models/Membership/User.cs @@ -448,18 +448,19 @@ namespace Umbraco.Core.Models.Membership [DoNotClone] internal object AdditionalDataLock { get { return _additionalDataLock; } } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (User)base.DeepClone(); - //turn off change tracking - clone.DisableChangeTracking(); + base.PerformDeepClone(clone); + + var clonedEntity = (User)clone; + //manually clone the start node props - clone._startContentIds = _startContentIds.ToArray(); - clone._startMediaIds = _startMediaIds.ToArray(); + clonedEntity._startContentIds = _startContentIds.ToArray(); + clonedEntity._startMediaIds = _startMediaIds.ToArray(); // this value has been cloned and points to the same object // which obviously is bad - needs to point to a new object - clone._additionalDataLock = new object(); + clonedEntity._additionalDataLock = new object(); if (_additionalData != null) { @@ -467,7 +468,7 @@ namespace Umbraco.Core.Models.Membership // changing one clone impacts all of them - so we need to reset it with a fresh // dictionary that will contain the same values - and, if some values are deep // cloneable, they should be deep-cloned too - var cloneAdditionalData = clone._additionalData = new Dictionary(); + var cloneAdditionalData = clonedEntity._additionalData = new Dictionary(); lock (_additionalDataLock) { @@ -480,15 +481,9 @@ namespace Umbraco.Core.Models.Membership } //need to create new collections otherwise they'll get copied by ref - clone._userGroups = new HashSet(_userGroups); - clone._allowedSections = _allowedSections != null ? new List(_allowedSections) : null; - //re-create the event handler - //this shouldn't really be needed since we're not tracking - clone.ResetDirtyProperties(false); - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; + clonedEntity._userGroups = new HashSet(_userGroups); + clonedEntity._allowedSections = _allowedSections != null ? new List(_allowedSections) : null; + } /// diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 8a97dc2cfc..0c71544111 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -392,21 +392,14 @@ namespace Umbraco.Core.Models return PropertyType.IsPropertyValueValid(value); } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (Property) base.DeepClone(); + base.PerformDeepClone(clone); - //turn off change tracking - clone.DisableChangeTracking(); + var clonedEntity = (Property)clone; //need to manually assign since this is a readonly property - clone.PropertyType = (PropertyType) PropertyType.DeepClone(); - - //re-enable tracking - clone.ResetDirtyProperties(false); // not needed really, since we're not tracking - clone.EnableChangeTracking(); - - return clone; + clonedEntity.PropertyType = (PropertyType) PropertyType.DeepClone(); } } } diff --git a/src/Umbraco.Core/Models/PropertyGroup.cs b/src/Umbraco.Core/Models/PropertyGroup.cs index 6c1f2e5c61..1d0b949932 100644 --- a/src/Umbraco.Core/Models/PropertyGroup.cs +++ b/src/Umbraco.Core/Models/PropertyGroup.cs @@ -100,24 +100,18 @@ namespace Umbraco.Core.Models return baseHash ^ nameHash; } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (PropertyGroup)base.DeepClone(); + base.PerformDeepClone(clone); - //turn off change tracking - clone.DisableChangeTracking(); + var clonedEntity = (PropertyGroup)clone; - if (clone._propertyTypes != null) + if (clonedEntity._propertyTypes != null) { - clone._propertyTypes.CollectionChanged -= PropertyTypesChanged; //clear this event handler if any - clone._propertyTypes = (PropertyTypeCollection) _propertyTypes.DeepClone(); //manually deep clone - clone._propertyTypes.CollectionChanged += clone.PropertyTypesChanged; //re-assign correct event handler + clonedEntity._propertyTypes.CollectionChanged -= PropertyTypesChanged; //clear this event handler if any + clonedEntity._propertyTypes = (PropertyTypeCollection) _propertyTypes.DeepClone(); //manually deep clone + clonedEntity._propertyTypes.CollectionChanged += clonedEntity.PropertyTypesChanged; //re-assign correct event handler } - - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; } } } diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs index a34fdb04ed..d44e7d464f 100644 --- a/src/Umbraco.Core/Models/PropertyType.cs +++ b/src/Umbraco.Core/Models/PropertyType.cs @@ -424,22 +424,17 @@ namespace Umbraco.Core.Models } /// - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (PropertyType)base.DeepClone(); - //turn off change tracking - clone.DisableChangeTracking(); + base.PerformDeepClone(clone); + + var clonedEntity = (PropertyType)clone; + //need to manually assign the Lazy value as it will not be automatically mapped if (PropertyGroupId != null) { - clone._propertyGroupId = new Lazy(() => PropertyGroupId.Value); + clonedEntity._propertyGroupId = new Lazy(() => PropertyGroupId.Value); } - //this shouldn't really be needed since we're not tracking - clone.ResetDirtyProperties(false); - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; } } } diff --git a/src/Umbraco.Core/Models/PublicAccessEntry.cs b/src/Umbraco.Core/Models/PublicAccessEntry.cs index 7fd0849e27..e93dc56e35 100644 --- a/src/Umbraco.Core/Models/PublicAccessEntry.cs +++ b/src/Umbraco.Core/Models/PublicAccessEntry.cs @@ -153,23 +153,17 @@ namespace Umbraco.Core.Models } } - public override object DeepClone() + protected override void PerformDeepClone(object clone) { - var clone = (PublicAccessEntry) base.DeepClone(); + base.PerformDeepClone(clone); - //turn off change tracking - clone.DisableChangeTracking(); + var cloneEntity = (PublicAccessEntry)clone; - if (clone._ruleCollection != null) + if (cloneEntity._ruleCollection != null) { - clone._ruleCollection.CollectionChanged -= _ruleCollection_CollectionChanged; //clear this event handler if any - clone._ruleCollection.CollectionChanged += clone._ruleCollection_CollectionChanged; //re-assign correct event handler + cloneEntity._ruleCollection.CollectionChanged -= _ruleCollection_CollectionChanged; //clear this event handler if any + cloneEntity._ruleCollection.CollectionChanged += cloneEntity._ruleCollection_CollectionChanged; //re-assign correct event handler } - - //re-enable tracking - clone.EnableChangeTracking(); - - return clone; } } } From de313a5d195596b6b5214f075462bca33a99a7a6 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 25 Oct 2018 16:09:58 +1100 Subject: [PATCH 088/337] Adds tests for verifying remember dirty properties on content --- src/Umbraco.Core/Models/Content.cs | 3 + src/Umbraco.Tests/Models/ContentTests.cs | 104 +++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index d46e318aea..dfd0313078 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -467,6 +467,9 @@ namespace Umbraco.Core.Models { base.ResetDirtyProperties(rememberDirty); + Template.ResetDirtyProperties(rememberDirty); + ContentType.ResetDirtyProperties(rememberDirty); + // take care of the published state _publishedState = _published ? PublishedState.Published : PublishedState.Unpublished; diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 807231730b..31110d7196 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -271,8 +271,13 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextpageContentType(); contentType.Id = 99; + contentType.Variations = ContentVariation.Culture; var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + content.SetCultureName("Hello", "en-US"); + content.SetCultureName("World", "es-ES"); + content.PublishCulture("en-US"); + // should not try to clone something that's not Published or Unpublished // (and in fact it will not work) // but we cannot directly set the state to Published - hence this trick @@ -301,6 +306,8 @@ namespace Umbraco.Tests.Models content.UpdateDate = DateTime.Now; content.WriterId = 23; + + // Act var clone = (Content)content.DeepClone(); @@ -349,6 +356,22 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.Properties[index], content.Properties[index]); } + Assert.AreNotSame(clone.PublishCultureInfos, content.PublishCultureInfos); + Assert.AreEqual(clone.PublishCultureInfos.Count, content.PublishCultureInfos.Count); + foreach (var key in content.PublishCultureInfos.Keys) + { + Assert.AreNotSame(clone.PublishCultureInfos[key], content.PublishCultureInfos[key]); + Assert.AreEqual(clone.PublishCultureInfos[key], content.PublishCultureInfos[key]); + } + + Assert.AreNotSame(clone.CultureInfos, content.CultureInfos); + Assert.AreEqual(clone.CultureInfos.Count, content.CultureInfos.Count); + foreach (var key in content.CultureInfos.Keys) + { + Assert.AreNotSame(clone.CultureInfos[key], content.CultureInfos[key]); + Assert.AreEqual(clone.CultureInfos[key], content.CultureInfos[key]); + } + //This double verifies by reflection var allProps = clone.GetType().GetProperties(); foreach (var propertyInfo in allProps) @@ -369,6 +392,87 @@ namespace Umbraco.Tests.Models Assert.IsTrue(asDirty.IsPropertyDirty("Properties")); } + [Test] + public void Remember_Dirty_Properties() + { + // Arrange + var contentType = MockedContentTypes.CreateTextpageContentType(); + contentType.Id = 99; + contentType.Variations = ContentVariation.Culture; + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); + + content.SetCultureName("Hello", "en-US"); + content.SetCultureName("World", "es-ES"); + content.PublishCulture("en-US"); + + var i = 200; + foreach (var property in content.Properties) + { + property.Id = ++i; + } + content.Id = 10; + content.CreateDate = DateTime.Now; + content.CreatorId = 22; + content.ExpireDate = DateTime.Now; + content.Key = Guid.NewGuid(); + content.Level = 3; + content.Path = "-1,4,10"; + content.ReleaseDate = DateTime.Now; + content.SortOrder = 5; + content.Template = new Template((string)"Test Template", (string)"testTemplate") + { + Id = 88 + }; + + content.Trashed = true; + content.UpdateDate = DateTime.Now; + content.WriterId = 23; + + content.Template.UpdateDate = DateTime.Now; //update a child object + content.ContentType.UpdateDate = DateTime.Now; //update a child object + + // Act + content.ResetDirtyProperties(); + + // Assert + Assert.IsTrue(content.WasDirty()); + Assert.IsTrue(content.WasPropertyDirty("Id")); + Assert.IsTrue(content.WasPropertyDirty("CreateDate")); + Assert.IsTrue(content.WasPropertyDirty("CreatorId")); + Assert.IsTrue(content.WasPropertyDirty("ExpireDate")); + Assert.IsTrue(content.WasPropertyDirty("Key")); + Assert.IsTrue(content.WasPropertyDirty("Level")); + Assert.IsTrue(content.WasPropertyDirty("Path")); + Assert.IsTrue(content.WasPropertyDirty("ReleaseDate")); + Assert.IsTrue(content.WasPropertyDirty("SortOrder")); + Assert.IsTrue(content.WasPropertyDirty("Template")); + Assert.IsTrue(content.WasPropertyDirty("Trashed")); + Assert.IsTrue(content.WasPropertyDirty("UpdateDate")); + Assert.IsTrue(content.WasPropertyDirty("WriterId")); + foreach (var prop in content.Properties) + { + Assert.IsTrue(prop.WasDirty()); + Assert.IsTrue(prop.WasPropertyDirty("Id")); + } + Assert.IsTrue(content.WasPropertyDirty("CultureInfos")); + foreach(var culture in content.CultureInfos) + { + Assert.IsTrue(culture.Value.WasDirty()); + Assert.IsTrue(culture.Value.WasPropertyDirty("Name")); + Assert.IsTrue(culture.Value.WasPropertyDirty("Date")); + } + Assert.IsTrue(content.WasPropertyDirty("PublishCultureInfos")); + foreach (var culture in content.PublishCultureInfos) + { + Assert.IsTrue(culture.Value.WasDirty()); + Assert.IsTrue(culture.Value.WasPropertyDirty("Name")); + Assert.IsTrue(culture.Value.WasPropertyDirty("Date")); + } + //verify child objects were reset too + Assert.IsTrue(content.Template.WasPropertyDirty("UpdateDate")); + Assert.IsTrue(content.ContentType.WasPropertyDirty("UpdateDate")); + } + [Test] public void Can_Serialize_Without_Error() { From ca6fd56f09d6cbe27dd44cf1379d89cb6d23b02c Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 25 Oct 2018 17:21:10 +1100 Subject: [PATCH 089/337] Gets send to publish emails working for variants --- src/Umbraco.Core/Models/Content.cs | 6 +- .../Models/NotificationEmailBodyParams.cs | 4 + .../Services/Implement/NotificationService.cs | 106 +++++++++++++----- src/Umbraco.Tests/TestHelpers/TestObjects.cs | 4 +- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 10 +- .../Umbraco/config/lang/en_us.xml | 10 +- .../Components/NotificationsComponent.cs | 52 ++++++--- 7 files changed, 141 insertions(+), 51 deletions(-) diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index dfd0313078..b048998691 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -467,8 +467,10 @@ namespace Umbraco.Core.Models { base.ResetDirtyProperties(rememberDirty); - Template.ResetDirtyProperties(rememberDirty); - ContentType.ResetDirtyProperties(rememberDirty); + if (Template != null) + Template.ResetDirtyProperties(rememberDirty); + if (ContentType != null) + ContentType.ResetDirtyProperties(rememberDirty); // take care of the published state _publishedState = _published ? PublishedState.Published : PublishedState.Unpublished; diff --git a/src/Umbraco.Core/Models/NotificationEmailBodyParams.cs b/src/Umbraco.Core/Models/NotificationEmailBodyParams.cs index ff316b1cf7..e85284fe5a 100644 --- a/src/Umbraco.Core/Models/NotificationEmailBodyParams.cs +++ b/src/Umbraco.Core/Models/NotificationEmailBodyParams.cs @@ -21,6 +21,10 @@ namespace Umbraco.Core.Models public string ItemName { get; } public string ItemId { get; } public string ItemUrl { get; } + + /// + /// This will either be an HTML or text based summary depending on the email type being sent + /// public string Summary { get; } public string EditedUser { get; } public string SiteUrl { get; } diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index 5d7860026b..ef2bfafcf6 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -24,12 +24,13 @@ namespace Umbraco.Core.Services.Implement private readonly IScopeProvider _uowProvider; private readonly IUserService _userService; private readonly IContentService _contentService; + private readonly ILocalizationService _localizationService; private readonly INotificationsRepository _notificationsRepository; private readonly IGlobalSettings _globalSettings; private readonly IContentSection _contentSection; private readonly ILogger _logger; - public NotificationService(IScopeProvider provider, IUserService userService, IContentService contentService, + public NotificationService(IScopeProvider provider, IUserService userService, IContentService contentService, ILocalizationService localizationService, ILogger logger, INotificationsRepository notificationsRepository, IGlobalSettings globalSettings, IContentSection contentSection) { _notificationsRepository = notificationsRepository; @@ -38,6 +39,7 @@ namespace Umbraco.Core.Services.Implement _uowProvider = provider ?? throw new ArgumentNullException(nameof(provider)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _contentService = contentService ?? throw new ArgumentNullException(nameof(contentService)); + _localizationService = localizationService; _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -279,7 +281,7 @@ namespace Umbraco.Core.Services.Implement /// /// Callback to create the mail subject /// Callback to create the mail body - private NotificationRequest CreateNotificationRequest(IUser performingUser, IUser mailingUser, IContentBase content, IContentBase oldDoc, + private NotificationRequest CreateNotificationRequest(IUser performingUser, IUser mailingUser, IContent content, IContentBase oldDoc, string actionName, Uri siteUri, Func<(IUser user, NotificationEmailSubjectParams subject), string> createSubject, @@ -294,34 +296,88 @@ namespace Umbraco.Core.Services.Implement // build summary var summary = new StringBuilder(); - var props = content.Properties.ToArray(); - foreach (var p in props) + + if (content.ContentType.VariesByNothing()) { - //fixme doesn't take into account variants - - var newText = p.GetValue() != null ? p.GetValue().ToString() : ""; - var oldText = newText; - - // check if something was changed and display the changes otherwise display the fields - if (oldDoc.Properties.Contains(p.PropertyType.Alias)) + if (!_contentSection.DisableHtmlEmail) { - var oldProperty = oldDoc.Properties[p.PropertyType.Alias]; - oldText = oldProperty.GetValue() != null ? oldProperty.GetValue().ToString() : ""; + //create the html summary for invariant content - // replace html with char equivalent - ReplaceHtmlSymbols(ref oldText); - ReplaceHtmlSymbols(ref newText); + //list all of the property values like we used to + summary.Append(""); + foreach (var p in content.Properties) + { + //fixme doesn't take into account variants + + var newText = p.GetValue() != null ? p.GetValue().ToString() : ""; + var oldText = newText; + + // check if something was changed and display the changes otherwise display the fields + if (oldDoc.Properties.Contains(p.PropertyType.Alias)) + { + var oldProperty = oldDoc.Properties[p.PropertyType.Alias]; + oldText = oldProperty.GetValue() != null ? oldProperty.GetValue().ToString() : ""; + + // replace html with char equivalent + ReplaceHtmlSymbols(ref oldText); + ReplaceHtmlSymbols(ref newText); + } + + //show the values + summary.Append(""); + summary.Append(""); + summary.Append(""); + summary.Append(""); + } + summary.Append("
"); + summary.Append(p.PropertyType.Name); + summary.Append(""); + summary.Append(newText); + summary.Append("
"); } + + } + else if (content.ContentType.VariesByCulture()) + { + //it's variant, so detect what cultures have changed - //show the values - summary.Append(""); - summary.Append(""); - summary.Append(p.PropertyType.Name); - summary.Append(""); - summary.Append(""); - summary.Append(newText); - summary.Append(""); - summary.Append(""); + if (!_contentSection.DisableHtmlEmail) + { + //Create the html based summary (ul of culture names) + + var culturesChanged = content.CultureInfos.Where(x => x.Value.WasDirty()) + .Select(x => x.Key) + .Select(_localizationService.GetLanguageByIsoCode) + .WhereNotNull() + .Select(x => x.CultureName); + summary.Append("
    "); + foreach (var culture in culturesChanged) + { + summary.Append("
  • "); + summary.Append(culture); + summary.Append("
  • "); + } + summary.Append("
"); + } + else + { + //Create the text based summary (csv of culture names) + + var culturesChanged = string.Join(", ", content.CultureInfos.Where(x => x.Value.WasDirty()) + .Select(x => x.Key) + .Select(_localizationService.GetLanguageByIsoCode) + .WhereNotNull() + .Select(x => x.CultureName)); + + summary.Append("'"); + summary.Append(culturesChanged); + summary.Append("'"); + } + } + else + { + //not supported yet... + throw new NotSupportedException(); } var protocol = _globalSettings.UseHttps ? "https" : "http"; diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index 6d0d14ce11..088a696986 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -160,10 +160,11 @@ namespace Umbraco.Tests.TestHelpers var runtimeState = Mock.Of(); var idkMap = new IdkMap(scopeProvider); + var localizationService = GetLazyService(container, c => new LocalizationService(scopeProvider, logger, eventMessagesFactory, GetRepo(c), GetRepo(c), GetRepo(c))); var userService = GetLazyService(container, c => new UserService(scopeProvider, logger, eventMessagesFactory, runtimeState, GetRepo(c), GetRepo(c),globalSettings)); var dataTypeService = GetLazyService(container, c => new DataTypeService(scopeProvider, logger, eventMessagesFactory, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); var contentService = GetLazyService(container, c => new ContentService(scopeProvider, logger, eventMessagesFactory, mediaFileSystem, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); - var notificationService = GetLazyService(container, c => new NotificationService(scopeProvider, userService.Value, contentService.Value, logger, GetRepo(c), globalSettings, umbracoSettings.Content)); + var notificationService = GetLazyService(container, c => new NotificationService(scopeProvider, userService.Value, contentService.Value, localizationService.Value, logger, GetRepo(c), globalSettings, umbracoSettings.Content)); var serverRegistrationService = GetLazyService(container, c => new ServerRegistrationService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); var memberGroupService = GetLazyService(container, c => new MemberGroupService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); var memberService = GetLazyService(container, c => new MemberService(scopeProvider, logger, eventMessagesFactory, memberGroupService.Value, mediaFileSystem, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); @@ -171,7 +172,6 @@ namespace Umbraco.Tests.TestHelpers var contentTypeService = GetLazyService(container, c => new ContentTypeService(scopeProvider, logger, eventMessagesFactory, contentService.Value, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); var mediaTypeService = GetLazyService(container, c => new MediaTypeService(scopeProvider, logger, eventMessagesFactory, mediaService.Value, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); var fileService = GetLazyService(container, c => new FileService(scopeProvider, logger, eventMessagesFactory, GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c), GetRepo(c))); - var localizationService = GetLazyService(container, c => new LocalizationService(scopeProvider, logger, eventMessagesFactory, GetRepo(c), GetRepo(c), GetRepo(c))); var memberTypeService = GetLazyService(container, c => new MemberTypeService(scopeProvider, logger, eventMessagesFactory, memberService.Value, GetRepo(c), GetRepo(c), GetRepo(c))); var entityService = GetLazyService(container, c => new EntityService( diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index e852be1a4e..cd1591df8d 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -943,10 +943,13 @@ To manage your website, simply open the Umbraco back office and start adding con Go to http://%4%/#/content/content/edit/%5% to edit. + %6% + Have a nice day! Cheers from the Umbraco robot ]]> + The following languages have been modified %0% @@ -1002,9 +1005,7 @@ To manage your website, simply open the Umbraco back office and start adding con

Update summary:

- - %6% -
+ %6%

Have a nice day!

@@ -1025,6 +1026,9 @@ To manage your website, simply open the Umbraco back office and start adding con ]]> + The following languages have been modified:

+ %0% + ]]>
[%0%] Notification about %1% performed on %2% Notifications diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index 54d86eee5c..c6574198e8 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -963,10 +963,13 @@ To manage your website, simply open the Umbraco back office and start adding con Go to http://%4%/#/content/content/edit/%5% to edit. + %6% + Have a nice day! Cheers from the Umbraco robot ]]> + The following languages have been modified %0% @@ -1022,9 +1025,7 @@ To manage your website, simply open the Umbraco back office and start adding con

Update summary:

- - %6% -
+ %6%

Have a nice day!

@@ -1045,6 +1046,9 @@ To manage your website, simply open the Umbraco back office and start adding con ]]> + The following languages have been modified:

+ %0% + ]]>
[%0%] Notification about %1% performed on %2% Notifications diff --git a/src/Umbraco.Web/Components/NotificationsComponent.cs b/src/Umbraco.Web/Components/NotificationsComponent.cs index 7eaaf0e18c..40c19d0df4 100644 --- a/src/Umbraco.Web/Components/NotificationsComponent.cs +++ b/src/Umbraco.Web/Components/NotificationsComponent.cs @@ -150,22 +150,42 @@ namespace Umbraco.Web.Components if (sender == null) throw new ArgumentNullException(nameof(sender)); if (siteUri == null) throw new ArgumentNullException(nameof(siteUri)); - _notificationService.SendNotifications( - sender, - entities, - action.Letter.ToString(CultureInfo.InvariantCulture), - _textService.Localize("actions", action.Alias), - siteUri, - ((IUser user, NotificationEmailSubjectParams subject) x) - => _textService.Localize( - "notifications/mailSubject", - x.user.GetUserCulture(_textService, _globalSettings), - new[] { x.subject.SiteUrl, x.subject.Action, x.subject.ItemName }), - ((IUser user, NotificationEmailBodyParams body, bool isHtml) x) - => _textService.Localize( - x.isHtml ? "notifications/mailBodyHtml" : "notifications/mailBody", - x.user.GetUserCulture(_textService, _globalSettings), - new[] { x.body.RecipientName, x.body.Action, x.body.ItemName, x.body.EditedUser, x.body.SiteUrl, x.body.ItemId, x.body.Summary, x.body.ItemUrl })); + //group by the content type variation since the emails will be different + foreach(var contentVariantGroup in entities.GroupBy(x => x.ContentType.Variations)) + { + if (contentVariantGroup.Key == ContentVariation.CultureAndSegment || contentVariantGroup.Key == ContentVariation.Segment) + throw new NotSupportedException("Segments are not yet supported in Umbraco"); + + _notificationService.SendNotifications( + sender, + contentVariantGroup, + action.Letter.ToString(CultureInfo.InvariantCulture), + _textService.Localize("actions", action.Alias), + siteUri, + ((IUser user, NotificationEmailSubjectParams subject) x) + => _textService.Localize( + "notifications/mailSubject", + x.user.GetUserCulture(_textService, _globalSettings), + new[] { x.subject.SiteUrl, x.subject.Action, x.subject.ItemName }), + ((IUser user, NotificationEmailBodyParams body, bool isHtml) x) + => _textService.Localize( + x.isHtml ? "notifications/mailBodyHtml" : "notifications/mailBody", + x.user.GetUserCulture(_textService, _globalSettings), + new[] + { + x.body.RecipientName, + x.body.Action, + x.body.ItemName, + x.body.EditedUser, + x.body.SiteUrl, + x.body.ItemId, + //format the summary depending on if it's variant or not + contentVariantGroup.Key == ContentVariation.Culture + ? (x.isHtml ? _textService.Localize("notifications/mailBodyVariantHtmlSummary", new[]{ x.body.Summary }) : _textService.Localize("notifications/mailBodyVariantSummary", new []{ x.body.Summary })) + : x.body.Summary, + x.body.ItemUrl + })); + } } } From b63b25414c4f52bed57b8929c06fdbdd06a02375 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 25 Oct 2018 09:38:46 +0200 Subject: [PATCH 090/337] show inherted from label --- .../content/umbtabbedcontent.directive.js | 4 ++++ .../property/umbproperty.directive.js | 4 +++- .../content/umb-tabbed-content.html | 19 ++++++------------- .../components/property/umb-property.html | 4 ++++ 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js index 5176f65801..f83f441d66 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js @@ -17,6 +17,10 @@ return variant.active; }); + $scope.defaultVariant = _.find(this.content.variants, variant => { + return variant.language.isDefault; + }); + $scope.unlockInvariantValue = function(property) { property.unlockInvariantValue = !property.unlockInvariantValue; }; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbproperty.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbproperty.directive.js index 69457a6f10..302378b8c0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbproperty.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/property/umbproperty.directive.js @@ -7,7 +7,9 @@ angular.module("umbraco.directives") .directive('umbProperty', function (umbPropEditorHelper, userService) { return { scope: { - property: "=" + property: "=", + showInherit: "<", + inheritsFrom: "<" }, transclude: true, restrict: 'E', diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html index 7663aa8997..cdacea7cf1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html @@ -8,19 +8,12 @@
- - - +
internal class LegacyTreeDataConverter { + //fixme: remove this whole class when everything is angularized + /// /// This will look at the legacy IAction's JsFunctionName and convert it to a confirmation dialog view if possible /// @@ -24,14 +27,9 @@ namespace Umbraco.Web.Trees /// internal static Attempt GetLegacyConfirmView(IAction action) { - if (action.JsFunctionName.IsNullOrWhiteSpace()) + switch (action) { - return Attempt.Fail(); - } - - switch (action.JsFunctionName) - { - case "UmbClientMgr.appActions().actionDelete()": + case ActionDelete actionDelete: return Attempt.Succeed( UmbracoConfig.For.GlobalSettings().Path.EnsureEndsWith('/') + "views/common/dialogs/legacydelete.html"); } @@ -49,64 +47,18 @@ namespace Umbraco.Web.Trees /// internal static Attempt GetUrlAndTitleFromLegacyAction(IAction action, string nodeId, string nodeType, string nodeName, string currentSection) { - if (action.JsFunctionName.IsNullOrWhiteSpace()) + switch (action) { - return Attempt.Fail(); - } - - switch (action.JsFunctionName) - { - case "UmbClientMgr.appActions().actionNew()": + case ActionNew actionNew: return Attempt.Succeed( new LegacyUrlAction( "create.aspx?nodeId=" + nodeId + "&nodeType=" + nodeType + "&nodeName=" + nodeName + "&rnd=" + DateTime.UtcNow.Ticks, Current.Services.TextService.Localize("actions/create"))); - case "UmbClientMgr.appActions().actionNewFolder()": - return Attempt.Succeed( - new LegacyUrlAction( - "createFolder.aspx?nodeId=" + nodeId + "&nodeType=" + nodeType + "&nodeName=" + nodeName + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/create"))); - case "UmbClientMgr.appActions().actionProtect()": + case ActionProtect actionProtect: return Attempt.Succeed( new LegacyUrlAction( "dialogs/protectPage.aspx?mode=cut&nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, Current.Services.TextService.Localize("actions/protect"))); - case "UmbClientMgr.appActions().actionRollback()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/rollback.aspx?nodeId=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/rollback"))); - case "UmbClientMgr.appActions().actionNotify()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/notifications.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/notify"))); - case "UmbClientMgr.appActions().actionPublish()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/publish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/publish"))); - case "UmbClientMgr.appActions().actionChangeDocType()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/ChangeDocType.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/changeDocType"))); - case "UmbClientMgr.appActions().actionToPublish()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/SendPublish.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/sendtopublish"))); - case "UmbClientMgr.appActions().actionRePublish()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/republish.aspx?rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/republish"))); - case "UmbClientMgr.appActions().actionSendToTranslate()": - return Attempt.Succeed( - new LegacyUrlAction( - "dialogs/sendToTranslation.aspx?id=" + nodeId + "&rnd=" + DateTime.UtcNow.Ticks, - Current.Services.TextService.Localize("actions/sendToTranslate"))); - } return Attempt.Fail(); } diff --git a/src/Umbraco.Web/Trees/MacrosTreeController.cs b/src/Umbraco.Web/Trees/MacrosTreeController.cs index a4f486661e..0faa1ce75d 100644 --- a/src/Umbraco.Web/Trees/MacrosTreeController.cs +++ b/src/Umbraco.Web/Trees/MacrosTreeController.cs @@ -8,7 +8,8 @@ using Umbraco.Web.Models.Trees; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi.Filters; using Umbraco.Core.Services; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Actions; + using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees @@ -58,13 +59,13 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { //Create the normal create action - menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)) + menu.Items.Add(Services.TextService) //Since we haven't implemented anything for macros in angular, this needs to be converted to //use the legacy format .ConvertLegacyMenuItem(null, "initmacros", queryStrings.GetValue("application")); //refresh action - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } @@ -74,7 +75,7 @@ namespace Umbraco.Web.Trees if (macro == null) return new MenuItemCollection(); //add delete option for all macros - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)) + menu.Items.Add(Services.TextService) //Since we haven't implemented anything for macros in angular, this needs to be converted to //use the legacy format .ConvertLegacyMenuItem(new EntitySlim diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index 8eb37e6224..d260253218 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -8,10 +8,12 @@ using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; +using Umbraco.Web.Actions; +using Umbraco.Web.Composing; using Umbraco.Web.Models.Trees; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi.Filters; -using Umbraco.Web._Legacy.Actions; + using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Constants = Umbraco.Core.Constants; @@ -81,28 +83,25 @@ namespace Umbraco.Web.Trees var menu = new MenuItemCollection(); //set the default - menu.DefaultMenuAlias = ActionNew.Instance.Alias; + menu.DefaultMenuAlias = ActionNew.ActionAlias; if (id == Constants.System.Root.ToInvariantString()) { // if the user's start node is not the root then the only menu item to display is refresh if (UserStartNodes.Contains(Constants.System.Root) == false) { - menu.Items.Add( - Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)), - true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } // root actions - menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true); - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } - int iid; - if (int.TryParse(id, out iid) == false) + if (int.TryParse(id, out var iid) == false) { throw new HttpResponseException(HttpStatusCode.NotFound); } @@ -115,29 +114,27 @@ namespace Umbraco.Web.Trees //if the user has no path access for this node, all they can do is refresh if (Security.CurrentUser.HasPathAccess(item, Services.EntityService, RecycleBinId) == false) { - menu.Items.Add( - Services.TextService.Localize(string.Concat("actions/", ActionRefresh.Instance.Alias)), - true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } //return a normal node menu: - menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionMove.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionSort.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService); + menu.Items.Add(new RefreshNode(Services.TextService, true)); //if the media item is in the recycle bin, don't have a default menu, just show the regular menu if (item.Path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Contains(RecycleBinId.ToInvariantString())) { menu.DefaultMenuAlias = null; - menu.Items.Insert(2, new MenuItem(ActionRestore.Instance, Services.TextService.Localize("actions", ActionRestore.Instance.Alias))); + menu.Items.Insert(2, new MenuItem(Current.Actions.GetAction(), Services.TextService.Localize("actions", ActionRestore.ActionAlias))); } else { //set the default to create - menu.DefaultMenuAlias = ActionNew.Instance.Alias; + menu.DefaultMenuAlias = ActionNew.ActionAlias; } return menu; diff --git a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs index 7b346c6871..a679cefa32 100644 --- a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs @@ -9,8 +9,9 @@ using Umbraco.Core.Models; using Umbraco.Web.Models.Trees; using Umbraco.Web.WebApi.Filters; using Umbraco.Core.Services; +using Umbraco.Web.Actions; using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web._Legacy.Actions; + using Umbraco.Web.Search; namespace Umbraco.Web.Trees @@ -70,12 +71,11 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { //set the default to create - menu.DefaultMenuAlias = ActionNew.Instance.Alias; + menu.DefaultMenuAlias = ActionNew.ActionAlias; // root actions - menu.Items.Add(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionRefresh.Instance.Alias}")); + menu.Items.Add(Services.TextService); + menu.Items.Add(new RefreshNode(Services.TextService)); return menu; } @@ -83,9 +83,9 @@ namespace Umbraco.Web.Trees if (container != null) { //set the default to create - menu.DefaultMenuAlias = ActionNew.Instance.Alias; + menu.DefaultMenuAlias = ActionNew.ActionAlias; - menu.Items.Add(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); + menu.Items.Add(Services.TextService); menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename")) { @@ -95,10 +95,9 @@ namespace Umbraco.Web.Trees if (container.HasChildren == false) { //can delete doc type - menu.Items.Add(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}")); + menu.Items.Add(Services.TextService); } - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionRefresh.Instance.Alias}"), hasSeparator: true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); } else { @@ -107,29 +106,28 @@ namespace Umbraco.Web.Trees if (enableInheritedMediaTypes) { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")); + menu.Items.Add(Services.TextService); //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true); + menu.Items.Add(Services.TextService, true); } } else { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}")); + menu.Items.Add(Services.TextService); //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionMove.Instance.Alias}"), true); + menu.Items.Add(Services.TextService, true); } } - menu.Items.Add(Services.TextService.Localize($"actions/{ActionCopy.Instance.Alias}")); - menu.Items.Add(Services.TextService.Localize($"actions/{ActionDelete.Instance.Alias}")); + menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService); if (enableInheritedMediaTypes) - menu.Items.Add(Services.TextService.Localize( - $"actions/{ActionRefresh.Instance.Alias}"), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); } return menu; diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index f3ca0c9a02..f8bcb47b56 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -10,10 +10,11 @@ using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core.Security; +using Umbraco.Web.Actions; using Umbraco.Web.Models.Trees; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi.Filters; -using Umbraco.Web._Legacy.Actions; + using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Search; using Constants = Umbraco.Core.Constants; @@ -155,27 +156,32 @@ namespace Umbraco.Web.Trees if (_provider.IsUmbracoMembershipProvider()) { //set default - menu.DefaultMenuAlias = ActionNew.Instance.Alias; + menu.DefaultMenuAlias = ActionNew.ActionAlias; //Create the normal create action - menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); + menu.Items.Add(Services.TextService); } else { //Create a custom create action - this does not launch a dialog, it just navigates to the create screen // we'll create it based on the ActionNew so it maintains the same icon properties, name, etc... - var createMenuItem = new MenuItem(ActionNew.Instance); + var createMenuItem = new MenuItem + { + Name = Services.TextService.Localize($"actions/{ActionNew.ActionAlias}"), + Alias = ActionNew.ActionAlias, + Icon = "add" + }; //we want to go to this route: /member/member/edit/-1?create=true createMenuItem.NavigateToRoute("/member/member/edit/-1?create=true"); menu.Items.Add(createMenuItem); } - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } //add delete option for all members - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); + menu.Items.Add(Services.TextService); if (Security.CurrentUser.HasAccessToSensitiveData()) { diff --git a/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs b/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs index a710b52595..484ea1e2a9 100644 --- a/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs @@ -2,7 +2,8 @@ using System.Net.Http.Formatting; using Umbraco.Core; using Umbraco.Core.Services; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Actions; + using Umbraco.Web.Models.Trees; namespace Umbraco.Web.Trees @@ -25,14 +26,14 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { // root actions - menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new CreateChildEntity(Services.TextService)); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } else { //delete member type/group - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); + menu.Items.Add(Services.TextService); } return menu; diff --git a/src/Umbraco.Web/Trees/PackagesTreeController.cs b/src/Umbraco.Web/Trees/PackagesTreeController.cs index 31f577ad85..8f62047941 100644 --- a/src/Umbraco.Web/Trees/PackagesTreeController.cs +++ b/src/Umbraco.Web/Trees/PackagesTreeController.cs @@ -8,7 +8,8 @@ using Umbraco.Web.WebApi.Filters; using umbraco; using umbraco.cms.businesslogic.packager; using Umbraco.Core.Services; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Actions; + using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees @@ -83,21 +84,20 @@ namespace Umbraco.Web.Trees // Root actions if (id == "-1") { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")) + menu.Items.Add(Services.TextService) .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application")); } else if (id == "created") { - menu.Items.Add(Services.TextService.Localize($"actions/{ActionNew.Instance.Alias}")) + menu.Items.Add(Services.TextService) .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application")); - menu.Items.Add( - Services.TextService.Localize($"actions/{ActionRefresh.Instance.Alias}"), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); } else { //it's a package node - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)); + menu.Items.Add(Services.TextService); } return menu; diff --git a/src/Umbraco.Web/Trees/RelationTypeTreeController.cs b/src/Umbraco.Web/Trees/RelationTypeTreeController.cs index 4930b4dc5e..ab6e9e2dd7 100644 --- a/src/Umbraco.Web/Trees/RelationTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/RelationTypeTreeController.cs @@ -4,10 +4,11 @@ using System.Net.Http.Formatting; using Umbraco.Web.Models.Trees; using Umbraco.Web.WebApi.Filters; using Umbraco.Core; -using Umbraco.Web._Legacy.Actions; + using Umbraco.Core.Services; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; +using Umbraco.Web.Actions; namespace Umbraco.Web.Trees { @@ -24,12 +25,10 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { //Create the normal create action - menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)) - //Since we haven't implemented anything for relationtypes in angular, this needs to be converted to - //use the legacy format - .ConvertLegacyMenuItem(null, "initrelationTypes", queryStrings.GetValue("application")); + var addMenuItem = menu.Items.Add(Services.TextService); + addMenuItem.LaunchDialogUrl("developer/RelationTypes/NewRelationType.aspx", "Create New RelationType"); //refresh action - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } @@ -38,7 +37,7 @@ namespace Umbraco.Web.Trees if (relationType == null) return new MenuItemCollection(); //add delete option for all macros - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias)) + menu.Items.Add(Services.TextService) //Since we haven't implemented anything for relationtypes in angular, this needs to be converted to //use the legacy format .ConvertLegacyMenuItem(new EntitySlim diff --git a/src/Umbraco.Web/Trees/TemplatesTreeController.cs b/src/Umbraco.Web/Trees/TemplatesTreeController.cs index 768768f888..3ae45a072e 100644 --- a/src/Umbraco.Web/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web/Trees/TemplatesTreeController.cs @@ -8,12 +8,13 @@ using Umbraco.Core; using Umbraco.Core.Services; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; +using Umbraco.Web.Actions; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Models.Trees; using Umbraco.Web.Mvc; using Umbraco.Web.Search; using Umbraco.Web.WebApi.Filters; -using Umbraco.Web._Legacy.Actions; + using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees @@ -69,13 +70,13 @@ namespace Umbraco.Web.Trees var menu = new MenuItemCollection(); //Create the normal create action - var item = menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)); + var item = menu.Items.Add(Services.TextService); item.NavigateToRoute($"{queryStrings.GetValue("application")}/templates/edit/{id}?create=true"); if (id == Constants.System.Root.ToInvariantString()) { //refresh action - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } @@ -88,11 +89,11 @@ namespace Umbraco.Web.Trees if (template.IsMasterTemplate == false) { //add delete option if it doesn't have children - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias), true); + menu.Items.Add(Services.TextService, true); } //add refresh - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; diff --git a/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs b/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs index e381c7ec0f..479cc20083 100644 --- a/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs +++ b/src/Umbraco.Web/Trees/UserPermissionsTreeController.cs @@ -3,10 +3,11 @@ using System.Linq; using System.Net.Http.Formatting; using Umbraco.Core; using Umbraco.Core.Services; +using Umbraco.Web.Actions; using Umbraco.Web.Models.Trees; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi.Filters; -using Umbraco.Web._Legacy.Actions; + using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees @@ -43,7 +44,7 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { // root actions - menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } diff --git a/src/Umbraco.Web/Trees/UserTreeController.cs b/src/Umbraco.Web/Trees/UserTreeController.cs index 8ae5b002c6..f029a929de 100644 --- a/src/Umbraco.Web/Trees/UserTreeController.cs +++ b/src/Umbraco.Web/Trees/UserTreeController.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Services; using Umbraco.Web.Models.Trees; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi.Filters; -using Umbraco.Web._Legacy.Actions; + using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees diff --git a/src/Umbraco.Web/TypeLoaderExtensions.cs b/src/Umbraco.Web/TypeLoaderExtensions.cs index 710c342115..4d09783ca9 100644 --- a/src/Umbraco.Web/TypeLoaderExtensions.cs +++ b/src/Umbraco.Web/TypeLoaderExtensions.cs @@ -5,7 +5,7 @@ using Umbraco.Web.Mvc; using Umbraco.Web.Trees; using Umbraco.Web.WebApi; using Umbraco.Core.Composing; -using Umbraco.Web._Legacy.Actions; + namespace Umbraco.Web { @@ -14,15 +14,6 @@ namespace Umbraco.Web /// public static class TypeLoaderExtensions { - /// - /// Returns all available IAction in application - /// - /// - internal static IEnumerable GetActions(this TypeLoader mgr) - { - return mgr.GetTypes(); - } - /// /// Returns all available TreeApiController's in application that are attribute with TreeAttribute /// @@ -43,15 +34,5 @@ namespace Umbraco.Web return mgr.GetTypes(); } - /// - /// Returns all available ISearchableTrees in application - /// - /// - /// - internal static IEnumerable GetSearchableTrees(this TypeLoader mgr) - { - return mgr.GetTypes(); - } - } } diff --git a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs index 30adf2cc3d..9f13939bac 100644 --- a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs +++ b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs @@ -11,9 +11,10 @@ using Umbraco.Core.Exceptions; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Security; +using Umbraco.Web.Actions; using Umbraco.Web.Composing; using Umbraco.Web.Security; -using Umbraco.Web._Legacy.Actions; + namespace Umbraco.Web.UI.Pages { diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 656bbd29c5..f7317939dd 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -428,7 +428,6 @@ - @@ -531,39 +530,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -953,7 +945,6 @@ - @@ -1269,12 +1260,6 @@ NewRelationType.aspx - - RelationTypesWebService.asmx - Component - - - insertMasterpageContent.aspx ASPXCodeBehind @@ -1378,7 +1363,6 @@ ASPXCodeBehind - ASPXCodeBehind diff --git a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs index 4d9a6db129..5d71992b74 100644 --- a/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/EnsureUserPermissionForContentAttribute.cs @@ -5,9 +5,10 @@ using System.Web.Http.Filters; using Umbraco.Core.Exceptions; using Umbraco.Web.Composing; using Umbraco.Web.Editors; -using Umbraco.Web._Legacy.Actions; + using Umbraco.Core; using Umbraco.Core.Models; +using Umbraco.Web.Actions; namespace Umbraco.Web.WebApi.Filters { @@ -39,7 +40,7 @@ namespace Umbraco.Web.WebApi.Filters { if (string.IsNullOrEmpty(paramName)) throw new ArgumentNullOrEmptyException(nameof(paramName)); _paramName = paramName; - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public EnsureUserPermissionForContentAttribute(string paramName, char permissionToCheck) diff --git a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs index 748e0e8a7d..31e0b22ce1 100644 --- a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs @@ -8,7 +8,8 @@ using Umbraco.Core.Services; using Umbraco.Core; using Umbraco.Web.Composing; using Umbraco.Core.Models; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Actions; + namespace Umbraco.Web.WebApi.Filters { @@ -25,7 +26,7 @@ namespace Umbraco.Web.WebApi.Filters public FilterAllowedOutgoingContentAttribute(Type outgoingType) : this(outgoingType, Current.Services.UserService, Current.Services.EntityService) { - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public FilterAllowedOutgoingContentAttribute(Type outgoingType, char permissionToCheck) @@ -37,7 +38,7 @@ namespace Umbraco.Web.WebApi.Filters public FilterAllowedOutgoingContentAttribute(Type outgoingType, string propertyName) : this(outgoingType, propertyName, Current.Services.UserService, Current.Services.EntityService) { - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public FilterAllowedOutgoingContentAttribute(Type outgoingType, IUserService userService, IEntityService entityService) @@ -45,7 +46,7 @@ namespace Umbraco.Web.WebApi.Filters { _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } public FilterAllowedOutgoingContentAttribute(Type outgoingType, char permissionToCheck, IUserService userService, IEntityService entityService) @@ -65,7 +66,7 @@ namespace Umbraco.Web.WebApi.Filters _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _userService = userService; _entityService = entityService; - _permissionToCheck = ActionBrowse.Instance.Letter; + _permissionToCheck = ActionBrowse.ActionLetter; } protected override void FilterItems(IUser user, IList items) diff --git a/src/Umbraco.Web/_Legacy/Actions/Action.cs b/src/Umbraco.Web/_Legacy/Actions/Action.cs deleted file mode 100644 index 388a5735fd..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/Action.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; -using Umbraco.Core.Logging; -using Umbraco.Core.Models.Membership; -using Umbraco.Web.Composing; -using Umbraco.Core.Services; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// Actions and Actionhandlers are a key concept to umbraco and a developer whom wish to apply - /// businessrules whenever data is changed within umbraco, by implementing the IActionHandler - /// interface it's possible to invoke methods (foreign to umbraco) - this can be used whenever - /// there is a specific rule which needs to be applied to content. - /// - /// The Action class itself has responsibility for registering actions and actionhandlers, - /// and contains methods which will be invoked whenever a change is made to ex. a document, media or member - /// - /// An action/actionhandler will automatically be registered, using reflection - /// which is enabling thirdparty developers to extend the core functionality of - /// umbraco without changing the codebase. - /// - [Obsolete("Actions and ActionHandlers are obsolete and should no longer be used")] - public class Action - { - private static readonly Dictionary ActionJs = new Dictionary(); - - /// - /// Jacascript for the contextmenu - /// Suggestion: this method should be moved to the presentation layer. - /// - /// - /// String representation - public string ReturnJavascript(string language) - { - return findActions(language); - } - - /// - /// Returns a list of JavaScript file paths. - /// - /// - public static List GetJavaScriptFileReferences() - { - return Current.Actions - .Where(x => !string.IsNullOrWhiteSpace(x.JsSource)) - .Select(x => x.JsSource).ToList(); - //return ActionJsReference; - } - - /// - /// Javascript menuitems - tree contextmenu - /// Umbraco console - /// - /// Suggestion: this method should be moved to the presentation layer. - /// - /// - /// - private static string findActions(string language) - { - if (!ActionJs.ContainsKey(language)) - { - string _actionJsList = ""; - - foreach (IAction action in Current.Actions) - { - // Adding try/catch so this rutine doesn't fail if one of the actions fail - // Add to language JsList - try - { - // NH: Add support for css sprites - string icon = action.Icon; - if (!string.IsNullOrEmpty(icon) && icon.StartsWith(".")) - icon = icon.Substring(1, icon.Length - 1); - else - icon = "images/" + icon; - - _actionJsList += string.Format(",\n\tmenuItem(\"{0}\", \"{1}\", \"{2}\", \"{3}\")", - action.Letter, icon, Current.Services.TextService.Localize("actions/"+ action.Alias, new[] { language }), action.JsFunctionName); - } - catch (Exception ex) - { - Current.Logger.Error(ex, "Error registrering action to javascript"); - } - } - - if (_actionJsList.Length > 0) - _actionJsList = _actionJsList.Substring(2, _actionJsList.Length - 2); - - _actionJsList = "\nvar menuMethods = new Array(\n" + _actionJsList + "\n)\n"; - ActionJs.Add(language, _actionJsList); - } - - return ActionJs[language]; - - } - - internal static List FromEntityPermission(EntityPermission entityPermission) - { - List list = new List(); - foreach (var c in entityPermission.AssignedPermissions.Where(x => x.Length == 1).Select(x => x.ToCharArray()[0])) - { - IAction action = Current.Actions.ToList().Find( - delegate (IAction a) - { - return a.Letter == c; - } - ); - if (action != null) - list.Add(action); - } - return list; - } - - /// - /// Returns a list of IActions that are permission assignable - /// - /// - public static List GetPermissionAssignable() - { - return Current.Actions.ToList().FindAll(x => x.CanBePermissionAssigned); - } - - /// - /// Check if the current IAction is using legacy javascript methods - /// - /// - /// false if the Iaction is incompatible with 4.5 - public static bool ValidateActionJs(IAction action) - { - return !action.JsFunctionName.Contains("+"); - } - - /// - /// Method to convert the old modal calls to the new ones - /// - /// - /// - public static string ConvertLegacyJs(string javascript) - { - MatchCollection tags = - Regex.Matches(javascript, "openModal[^;]*;", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - foreach (Match tag in tags) - { - string[] function = tag.Value.Split(','); - if (function.Length > 0) - { - string newFunction = "UmbClientMgr.openModalWindow" + function[0].Substring(9).Replace("parent.nodeID", "UmbClientMgr.mainTree().getActionNode().nodeId").Replace("nodeID", "UmbClientMgr.mainTree().getActionNode().nodeId").Replace("parent.returnRandom()", "'" + Guid.NewGuid().ToString() + "'"); - newFunction += ", " + function[1]; - newFunction += ", true"; - newFunction += ", " + function[2]; - newFunction += ", " + function[3]; - javascript = javascript.Replace(tag.Value, newFunction); - } - } - - return javascript; - } - } - - /// - /// This class is used to manipulate IActions that are implemented in a wrong way - /// For instance incompatible trees with 4.0 vs 4.5 - /// - public class PlaceboAction : IAction - { - public char Letter { get; set; } - public bool ShowInNotifier { get; set; } - public bool CanBePermissionAssigned { get; set; } - public string Icon { get; set; } - public string Alias { get; set; } - public string JsFunctionName { get; set; } - public string JsSource { get; set; } - - public PlaceboAction() { } - public PlaceboAction(IAction legacyAction) - { - Letter = legacyAction.Letter; - ShowInNotifier = legacyAction.ShowInNotifier; - CanBePermissionAssigned = legacyAction.CanBePermissionAssigned; - Icon = legacyAction.Icon; - Alias = legacyAction.Alias; - JsFunctionName = legacyAction.JsFunctionName; - JsSource = legacyAction.JsSource; - } - } - -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs b/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs deleted file mode 100644 index 37de1f8e0f..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a domain is being assigned to a document - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionAssignDomain : IAction - { - public static ActionAssignDomain Instance { get; } = new ActionAssignDomain(); - - #region IAction Members - - public char Letter - { - get - { - return 'I'; - } - } - - public string JsFunctionName - { - get - { - return null; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "assignDomain"; - } - } - - public string Icon - { - get - { - return "home"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionBrowse.cs b/src/Umbraco.Web/_Legacy/Actions/ActionBrowse.cs deleted file mode 100644 index 1425b27917..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionBrowse.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is used as a security constraint that grants a user the ability to view nodes in a tree - /// that has permissions applied to it. - /// - /// - /// This action should not be invoked. It is used as the minimum required permission to view nodes in the content tree. By - /// granting a user this permission, the user is able to see the node in the tree but not edit the document. This may be used by other trees - /// that support permissions in the future. - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionBrowse : IAction - { - //create singleton - private static readonly ActionBrowse instance = new ActionBrowse(); - private ActionBrowse() { } - public static ActionBrowse Instance - { - get { return instance; } - } - - #region IAction Members - - public char Letter - { - get { return 'F'; } - } - - public bool ShowInNotifier - { - get { return false; } - } - - public bool CanBePermissionAssigned - { - get { return true; } - } - - public string Icon - { - get { return ""; } - } - - public string Alias - { - get { return "browse"; } - } - - public string JsFunctionName - { - get { return ""; } - } - - public string JsSource - { - get { return ""; } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionChangeDocType.cs b/src/Umbraco.Web/_Legacy/Actions/ActionChangeDocType.cs deleted file mode 100644 index 9c31c172ab..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionChangeDocType.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when the document type of a piece of content is changed - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionChangeDocType : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionChangeDocType m_instance = new ActionChangeDocType(); -#pragma warning restore 612,618 - - public static ActionChangeDocType Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return '7'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionChangeDocType()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "changeDocType"; - } - } - - public string Icon - { - get - { - - return "axis-rotation-2"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionCollectionBuilder.cs b/src/Umbraco.Web/_Legacy/Actions/ActionCollectionBuilder.cs deleted file mode 100644 index 39058d6836..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionCollectionBuilder.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using LightInject; -using Umbraco.Core.Composing; - -namespace Umbraco.Web._Legacy.Actions -{ - internal class ActionCollectionBuilder : ICollectionBuilder - { - private static Func> _producer; - - // for tests only - does not register the collection - public ActionCollectionBuilder() - { } - - public ActionCollectionBuilder(IServiceContainer container) - { - var collectionLifetime = CollectionLifetime; - - // register the collection - special lifetime - // the lifetime here is custom ResettablePerContainerLifetime which will manage one - // single instance of the collection (much alike PerContainerLifetime) but can be resetted - // to force a new collection to be created. - // this is needed because of the weird things we do during install, where we'd use the - // infamous DirtyBackdoorToConfiguration to reset the ActionResolver way after Resolution - // had frozen. This has been replaced by the possibility here to set the producer at any - // time - but the builder is internal - and all this will be gone eventually. - container.Register(factory => factory.GetInstance().CreateCollection(), collectionLifetime); - } - - public ActionCollection CreateCollection() - { - var actions = new List(); - foreach (var type in _producer()) - { - var getter = type.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static); - var instance = getter == null - ? Activator.CreateInstance(type) as IAction - : getter.GetValue(null, null) as IAction; - if (instance == null) continue; - actions.Add(instance); - } - return new ActionCollection(actions); - } - - public void SetProducer(Func> producer) - { - _producer = producer; - CollectionLifetime.Reset(); - } - - private ResettablePerContainerLifetime CollectionLifetime { get; } = new ResettablePerContainerLifetime(); - - private class ResettablePerContainerLifetime : ILifetime - { - private object _instance; - - public object GetInstance(Func createInstance, Scope scope) - { - // not dealing with disposable instances, actions are not disposable - return _instance ?? (_instance = createInstance()); - } - - public void Reset() - { - _instance = null; - } - } - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionCopy.cs b/src/Umbraco.Web/_Legacy/Actions/ActionCopy.cs deleted file mode 100644 index a489f1d280..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionCopy.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when copying a document, media, member - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.StructureCategory)] - public class ActionCopy : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionCopy m_instance = new ActionCopy(); -#pragma warning restore 612,618 - - public static ActionCopy Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'O'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionCopy()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "copy"; - } - } - - public string Icon - { - get - { - - return "documents"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionCreateBlueprintFromContent.cs b/src/Umbraco.Web/_Legacy/Actions/ActionCreateBlueprintFromContent.cs deleted file mode 100644 index e00de39aea..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionCreateBlueprintFromContent.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionCreateBlueprintFromContent : IAction - { - private static readonly ActionCreateBlueprintFromContent instance = new ActionCreateBlueprintFromContent(); - - public static ActionCreateBlueprintFromContent Instance - { - get { return instance; } - } - - public char Letter { get; private set; } - public bool ShowInNotifier { get; private set; } - public bool CanBePermissionAssigned { get; private set; } - public string Icon { get; private set; } - public string Alias { get; private set; } - public string JsFunctionName { get; private set; } - public string JsSource { get; private set; } - - public ActionCreateBlueprintFromContent() - { - Letter = 'ï'; - CanBePermissionAssigned = true; - Icon = "blueprint"; - Alias = "createblueprint"; - } - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionDelete.cs b/src/Umbraco.Web/_Legacy/Actions/ActionDelete.cs deleted file mode 100644 index 09ce4d8602..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionDelete.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a document, media, member is deleted - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionDelete : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionDelete m_instance = new ActionDelete(); -#pragma warning restore 612,618 - - public static ActionDelete Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'D'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionDelete()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "delete"; - } - } - - public string Icon - { - get - { - return "delete"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionEmptyTranscan.cs b/src/Umbraco.Web/_Legacy/Actions/ActionEmptyTranscan.cs deleted file mode 100644 index 7f8dd6b03c..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionEmptyTranscan.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when the trash can is emptied - /// - public class ActionEmptyTranscan : IAction - { - //create singleton - private static readonly ActionEmptyTranscan InnerInstance = new ActionEmptyTranscan(); - - public static ActionEmptyTranscan Instance - { - get { return InnerInstance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'N'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionEmptyTranscan()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "emptyRecycleBin"; - } - } - - public string Icon - { - get - { - return "trash"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs b/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs deleted file mode 100644 index df78026ea0..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionExport.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when exporting a document type - /// - public class ActionExport : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionExport m_instance = new ActionExport(); -#pragma warning restore 612,618 - - public static ActionExport Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return '9'; - } - } - - public string JsFunctionName - { - get { return ""; } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "export"; - } - } - - public string Icon - { - get - { - return "download-alt"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionImport.cs b/src/Umbraco.Web/_Legacy/Actions/ActionImport.cs deleted file mode 100644 index 42947cf36e..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionImport.cs +++ /dev/null @@ -1,77 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when importing a document type - /// - public class ActionImport : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionImport m_instance = new ActionImport(); -#pragma warning restore 612,618 - - public static ActionImport Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return '8'; - } - } - - public string JsFunctionName - { - get - { - return ""; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "importDocumentType"; - } - } - - public string Icon - { - get - { - return "page-up"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionMove.cs b/src/Umbraco.Web/_Legacy/Actions/ActionMove.cs deleted file mode 100644 index 80aff5736a..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionMove.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document, media, member - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.StructureCategory)] - public class ActionMove : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionMove m_instance = new ActionMove(); -#pragma warning restore 612,618 - - public static ActionMove Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'M'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionMove()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "move"; - } - } - - public string Icon - { - get - { - - return "enter"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionNew.cs b/src/Umbraco.Web/_Legacy/Actions/ActionNew.cs deleted file mode 100644 index 72e863e38b..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionNew.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionNew : IAction - { - public static ActionNew Instance { get; } = new ActionNew(); - - #region IAction Members - - public char Letter - { - get - { - return 'C'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionNew()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "create"; - } - } - - public string Icon - { - get - { - return "add"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionNotify.cs b/src/Umbraco.Web/_Legacy/Actions/ActionNotify.cs deleted file mode 100644 index ef281eecbe..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionNotify.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a notification is sent - /// - public class ActionNotify : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionNotify m_instance = new ActionNotify(); -#pragma warning restore 612,618 - - public static ActionNotify Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'T'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionNotify()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - return "notify"; - } - } - - public string Icon - { - get - { - return "megaphone"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionNull.cs b/src/Umbraco.Web/_Legacy/Actions/ActionNull.cs deleted file mode 100644 index 78c5175fb6..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionNull.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This permission is assigned to a node when there are no permissions assigned to the node. - /// This is used internally to assign no permissions to a node for a user and shouldn't be used in code. - /// - public class ActionNull : IAction - { - //create singleton - private static readonly ActionNull instance = new ActionNull(); - private ActionNull() { } - public static ActionNull Instance - { - get { return instance; } - } - - #region IAction Members - - public char Letter - { - get { return '-'; } - } - - public bool ShowInNotifier - { - get { return false; } - } - - public bool CanBePermissionAssigned - { - get { return false; } - } - - public string Icon - { - get { return string.Empty; } - } - - public string Alias - { - get { return string.Empty; } - } - - public string JsFunctionName - { - get { return string.Empty; } - } - - public string JsSource - { - get { return string.Empty; } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionPackage.cs b/src/Umbraco.Web/_Legacy/Actions/ActionPackage.cs deleted file mode 100644 index 832e691b48..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionPackage.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document, media, member - /// - public class ActionPackage : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionPackage m_instance = new ActionPackage(); -#pragma warning restore 612,618 - - public static ActionPackage Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'X'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionPackage()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return ""; - } - } - - public string Alias - { - get - { - return "importPackage"; - } - } - - public string Icon - { - get - { - return "gift"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionPackageCreate.cs b/src/Umbraco.Web/_Legacy/Actions/ActionPackageCreate.cs deleted file mode 100644 index f0ccb03d8e..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionPackageCreate.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked upon creation of a document, media, member - /// - public class ActionPackageCreate : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionPackageCreate m_instance = new ActionPackageCreate(); -#pragma warning restore 612,618 - - public static ActionPackageCreate Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'Y'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionPackageCreate()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "createPackage"; - } - } - - public string Icon - { - get - { - return "gift"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionProtect.cs b/src/Umbraco.Web/_Legacy/Actions/ActionProtect.cs deleted file mode 100644 index 357dfe89a4..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionProtect.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a document is protected or unprotected - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionProtect : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionProtect m_instance = new ActionProtect(); -#pragma warning restore 612,618 - - public static ActionProtect Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'P'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionProtect()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "protect"; - } - } - - public string Icon - { - get - { - - return "lock"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs deleted file mode 100644 index 6b54873c43..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a document is being published - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionPublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionPublish m_instance = new ActionPublish(); -#pragma warning restore 612,618 - - public static ActionPublish Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'U'; - } - } - - public string JsFunctionName - { - get - { - return string.Empty; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "publish"; - } - } - - public string Icon - { - get - { - return string.Empty; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRePublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRePublish.cs deleted file mode 100644 index b78af779e4..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRePublish.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when all documents are being republished - /// - public class ActionRePublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionRePublish m_instance = new ActionRePublish(); -#pragma warning restore 612,618 - - public static ActionRePublish Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'B'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRePublish()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "republish"; - } - } - - public string Icon - { - get - { - return "globe"; - } - } - - public bool ShowInNotifier - { - get - { - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - return false; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRefresh.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRefresh.cs deleted file mode 100644 index 07133b4030..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRefresh.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a node reloads its children - /// Concerns only the tree itself and thus you should not handle - /// this action from without umbraco. - /// - [LegacyActionMenuItem("umbracoMenuActions", "RefreshNode")] - public class ActionRefresh : IAction - { - //create singleton - private static readonly ActionRefresh InnerInstance = new ActionRefresh(); - - public static ActionRefresh Instance - { - get { return InnerInstance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'L'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRefresh()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "refreshNode"; - } - } - - public string Icon - { - get - { - - return "refresh"; - } - } - - public bool ShowInNotifier - { - get - { - - return false; - } - } - public bool CanBePermissionAssigned - { - get - { - - return false; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRestore.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRestore.cs deleted file mode 100644 index da70eb1409..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRestore.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when the content/media item is to be restored from the recycle bin - /// - public class ActionRestore : IAction - { - //create singleton - - private ActionRestore() { } - - public static ActionRestore Instance { get; } = new ActionRestore(); - - #region IAction Members - - public char Letter => 'V'; - - public string JsFunctionName => null; - - public string JsSource => null; - - public string Alias => "restore"; - - public string Icon => "undo"; - - public bool ShowInNotifier => true; - - public bool CanBePermissionAssigned => false; - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRights.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRights.cs deleted file mode 100644 index e1ee74e61c..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRights.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when rights are changed on a document - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionRights : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionRights m_instance = new ActionRights(); -#pragma warning restore 612,618 - - public static ActionRights Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'R'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRights()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "rights"; - } - } - - public string Icon - { - get - { - - return "vcard"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionRollback.cs b/src/Umbraco.Web/_Legacy/Actions/ActionRollback.cs deleted file mode 100644 index 59044666f7..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionRollback.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when copying a document is being rolled back - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionRollback : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionRollback m_instance = new ActionRollback(); -#pragma warning restore 612,618 - - public static ActionRollback Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'K'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionRollback()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return ""; - } - } - - public string Alias - { - get - { - - return "rollback"; - } - } - - public string Icon - { - get - { - - return "undo"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionSort.cs b/src/Umbraco.Web/_Legacy/Actions/ActionSort.cs deleted file mode 100644 index b813dcbc8c..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionSort.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when children to a document, media, member is being sorted - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.StructureCategory)] - public class ActionSort : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionSort m_instance = new ActionSort(); -#pragma warning restore 612,618 - - public static ActionSort Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - - return 'S'; - } - } - - public string JsFunctionName - { - get - { - return null; - } - } - - public string JsSource - { - get - { - - return null; - } - } - - public string Alias - { - get - { - - return "sort"; - } - } - - public string Icon - { - get - { - - return "navigation-vertical"; - } - } - - public bool ShowInNotifier - { - get - { - - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionToPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionToPublish.cs deleted file mode 100644 index ff471bc198..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionToPublish.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when children to a document is being sent to published (by an editor without publishrights) - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionToPublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionToPublish m_instance = new ActionToPublish(); -#pragma warning restore 612,618 - - public static ActionToPublish Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'H'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionToPublish()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "sendtopublish"; - } - } - - public string Icon - { - get - { - return "outbox"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - //SD: Changed this to true so that any user may be able to perform this action, not just a writer - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionTranslate.cs b/src/Umbraco.Web/_Legacy/Actions/ActionTranslate.cs deleted file mode 100644 index 0cc5120fd0..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionTranslate.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when a translation occurs - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.AdministrationCategory)] - public class ActionTranslate : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionTranslate m_instance = new ActionTranslate(); -#pragma warning restore 612,618 - - public static ActionTranslate Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return '4'; - } - } - - public string JsFunctionName - { - get - { - return ""; - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "translate"; - } - } - - public string Icon - { - get - { - return "comments"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs deleted file mode 100644 index a61b805859..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionUnPublish.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - - /// - /// This action is invoked when a document is being unpublished - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionUnpublish : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionUnpublish m_instance = new ActionUnpublish(); -#pragma warning restore 612,618 - - public static ActionUnpublish Instance => m_instance; - - public char Letter => 'Z'; - public string JsFunctionName => ""; - public string JsSource => null; - public string Alias => "unpublish"; - public string Icon => "circle-dotted"; - public bool ShowInNotifier => false; - public bool CanBePermissionAssigned => true; - } - -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionUpdate.cs b/src/Umbraco.Web/_Legacy/Actions/ActionUpdate.cs deleted file mode 100644 index 15458e83ad..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ActionUpdate.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Umbraco.Web.UI.Pages; -using Umbraco.Core; -using Umbraco.Core.CodeAnnotations; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// This action is invoked when copying a document or media - /// - [ActionMetadata(Constants.Conventions.PermissionCategories.ContentCategory)] - public class ActionUpdate : IAction - { - //create singleton -#pragma warning disable 612,618 - private static readonly ActionUpdate m_instance = new ActionUpdate(); -#pragma warning restore 612,618 - - public static ActionUpdate Instance - { - get { return m_instance; } - } - - #region IAction Members - - public char Letter - { - get - { - return 'A'; - } - } - - public string JsFunctionName - { - get - { - return string.Format("{0}.actionUpdate()", ClientTools.Scripts.GetAppActions); - } - } - - public string JsSource - { - get - { - return null; - } - } - - public string Alias - { - get - { - return "update"; - } - } - - public string Icon - { - get - { - return "save"; - } - } - - public bool ShowInNotifier - { - get - { - return true; - } - } - public bool CanBePermissionAssigned - { - get - { - return true; - } - } - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/ContextMenuSeperator.cs b/src/Umbraco.Web/_Legacy/Actions/ContextMenuSeperator.cs deleted file mode 100644 index 2c66932a04..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/ContextMenuSeperator.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// Used simply to define context menu seperator items. - /// This should not be used directly in any code except for creating menus. - /// - public class ContextMenuSeperator : IAction - { - //create singleton - private static readonly ContextMenuSeperator instance = new ContextMenuSeperator(); - private ContextMenuSeperator() { } - public static ContextMenuSeperator Instance - { - get { return instance; } - } - - #region IAction Members - - public char Letter - { - get { return ','; } - } - - public string JsFunctionName - { - get { return string.Empty; } - } - public string JsSource - { - get { return string.Empty; } - } - public string Alias - { - get { return string.Empty; } - } - public string Icon - { - get { return string.Empty; } - } - public bool ShowInNotifier - { - get { return false; } - } - public bool CanBePermissionAssigned - { - get { return false; } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/IAction.cs b/src/Umbraco.Web/_Legacy/Actions/IAction.cs deleted file mode 100644 index 410a407517..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/IAction.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Umbraco.Core.Composing; - -namespace Umbraco.Web._Legacy.Actions -{ - public interface IAction : IDiscoverable - { - char Letter { get; } - bool ShowInNotifier { get; } - bool CanBePermissionAssigned { get; } - string Icon { get; } - string Alias { get; } - string JsFunctionName { get; } - /// - /// A path to a supporting JavaScript file for the IAction. A script tag will be rendered out with the reference to the JavaScript file. - /// - string JsSource { get; } - } -} diff --git a/src/Umbraco.Web/_Legacy/Actions/LegacyActionMenuItemAttribute.cs b/src/Umbraco.Web/_Legacy/Actions/LegacyActionMenuItemAttribute.cs deleted file mode 100644 index ca9ace9630..0000000000 --- a/src/Umbraco.Web/_Legacy/Actions/LegacyActionMenuItemAttribute.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.Exceptions; - -namespace Umbraco.Web._Legacy.Actions -{ - /// - /// The attribute to assign to any IAction objects. - /// - /// - /// This is purely used for compatibility reasons for old IActions used in v7 that haven't been upgraded to - /// the new format. - /// - [AttributeUsage(AttributeTargets.Class)] - internal sealed class LegacyActionMenuItemAttribute : Attribute - { - /// - /// This constructor defines both the angular service and method name to use - /// - /// - /// - public LegacyActionMenuItemAttribute(string serviceName, string methodName) - { - if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName)); - if (string.IsNullOrEmpty(methodName)) throw new ArgumentNullOrEmptyException(nameof(methodName)); - - MethodName = methodName; - ServiceName = serviceName; - } - - /// - /// This constructor will assume that the method name equals the type name of the action menu class - /// - /// - public LegacyActionMenuItemAttribute(string serviceName) - { - if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullOrEmptyException(nameof(serviceName)); - - MethodName = ""; - ServiceName = serviceName; - } - - public string MethodName { get; } - public string ServiceName { get; } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx deleted file mode 100644 index 160745ca2d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx +++ /dev/null @@ -1 +0,0 @@ -<%@ WebService Language="C#" CodeBehind="RelationTypesWebService.asmx.cs" Class="umbraco.cms.presentation.developer.RelationTypes.RelationTypesWebService" %> diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx.cs deleted file mode 100644 index 0f8ca29c94..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/RelationTypesWebService.asmx.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Web.Services; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Web; -using Umbraco.Web.Composing; - -namespace umbraco.cms.presentation.developer.RelationTypes -{ - /// - /// Webservice to delete relation types, this allows deletion via a javacscript call hooked into the tree UI - /// - [WebService(Namespace = "http://tempuri.org/")] - [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] - [System.ComponentModel.ToolboxItem(false)] - [System.Web.Script.Services.ScriptService] // Allows this Web Service to be called from script, using ASP.NET AJAX - public class RelationTypesWebService : WebService - { - /// - /// Delete an Umbraco RelationType and all it's associated Relations - /// - /// database id of the relation type to delete - [WebMethod] - public void DeleteRelationType(int relationTypeId) - { - var user = UmbracoContext.Current.Security.CurrentUser; - - if (user.IsAdmin()) - { - var relationService = Current.Services.RelationService; - var relationType = relationService.GetRelationTypeById(relationTypeId); - relationService.Delete(relationType); - } - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.cs deleted file mode 100644 index cf39b17e55..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Umbraco.Web._Legacy.Actions; - -namespace umbraco.cms.presentation.developer.RelationTypes.TreeMenu -{ - /// - /// Delete a Relation Type - an Umbraco tree context menu action - /// - public class ActionDeleteRelationType : IAction - { - /// - /// Private field for the singleton instance - /// - private static readonly ActionDeleteRelationType instance = new ActionDeleteRelationType(); - - /// - /// Gets a singleton instance of this action - /// - public static ActionDeleteRelationType Instance - { - get { return instance; } - } - - #region IAction Members - - /// - /// Gets a string alias used to identify this action - /// - public string Alias - { - get { return "delete"; } - } - - /// - /// Gets a unique char to associate with this action - /// - public char Letter - { - get { return '¤'; } - } - - /// - /// Gets a value indicating whether the Umbraco notification area is used ? - /// - public bool ShowInNotifier - { - get { return false; } - } - - /// - /// Gets a value indicating whether this action can be configured for use only by specific members - /// - public bool CanBePermissionAssigned - { - get { return false; } // Since this tree is in the developer section, no further granular permissions are required - } - - /// - /// Gets an icon to be used for the right click action - /// - public string Icon - { - get { return "delete"; } // delete refers to an existing sprite - } - - /// - /// Gets a string for the javascript source - /// - public string JsSource - { - get { return "developer/RelationTypes/TreeMenu/ActionDeleteRelationType.js"; } - } - - /// - /// Gets a javascript string to execute when this action is fired - /// - public string JsFunctionName - { - get { return "javascript:actionDeleteRelationType(UmbClientMgr.mainTree().getActionNode().nodeId,UmbClientMgr.mainTree().getActionNode().nodeName);"; } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.cs deleted file mode 100644 index 6018539983..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Umbraco.Web._Legacy.Actions; - -namespace umbraco.cms.presentation.developer.RelationTypes.TreeMenu -{ - /// - /// Create new Relation Type - an Umbraco tree context menu action - /// - public class ActionNewRelationType : IAction - { - /// - /// Private field for the singleton instance - /// - private static readonly ActionNewRelationType instance = new ActionNewRelationType(); - - /// - /// Gets a singleton instance of this action - /// - public static ActionNewRelationType Instance - { - get { return instance; } - } - - #region IAction Members - - /// - /// Gets a string alias used to identify this action - /// - public string Alias - { - get { return "create"; } - } - - /// - /// Gets a unique char to associate with this action - /// - public char Letter - { - get { return '®'; } - } - - /// - /// Gets a value indicating whether the Umbraco notification area is used ? - /// - public bool ShowInNotifier - { - get { return false; } - } - - /// - /// Gets a value indicating whether this action can be configured for use only by specific members - /// - public bool CanBePermissionAssigned - { - get { return false; } // Since this tree is in the developer section, no further granular permissions are required - } - - /// - /// Gets an icon to be used for the right click action - /// - public string Icon - { - get { return "add"; } // add refers to an existing sprite - } - - /// - /// Gets a string for the javascript source - /// - public string JsSource - { - get { return "developer/RelationTypes/TreeMenu/ActionNewRelationType.js"; } - } - - /// - /// Gets a javascript string to execute when this action is fired - /// - public string JsFunctionName - { - get { return "javascript:actionNewRelationType();"; } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs index 727af897ca..1f4ba277b5 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/SendPublish.aspx.cs @@ -1,7 +1,9 @@ using System; using Umbraco.Web; using Umbraco.Core; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web.Actions; +using Umbraco.Web.Composing; + namespace umbraco.dialogs { @@ -25,7 +27,7 @@ namespace umbraco.dialogs { //send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here Services.NotificationService.SendNotification( - Services.ContentService.GetById(docId), ActionToPublish.Instance); + Services.ContentService.GetById(docId), Current.Actions.GetAction()); } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs index 89a03a1437..8473341ca8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/templateControls/Item.cs @@ -11,9 +11,10 @@ using Umbraco.Core.Services; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web; +using Umbraco.Web.Actions; using Umbraco.Web.Composing; using Umbraco.Web.Macros; -using Umbraco.Web._Legacy.Actions; + namespace umbraco.presentation.templateControls { @@ -276,7 +277,7 @@ namespace umbraco.presentation.templateControls if (u == null) return false; var permission = Current.Services.UserService.GetPermissions(u, PageElements["path"].ToString()); - return permission.AssignedPermissions.Contains(ActionUpdate.Instance.Letter.ToString(CultureInfo.InvariantCulture), StringComparer.Ordinal); + return permission.AssignedPermissions.Contains(ActionUpdate.ActionLetter.ToString(CultureInfo.InvariantCulture), StringComparer.Ordinal); } #endregion diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs index f82587a413..5e0cb289f0 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs @@ -9,8 +9,9 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Web; +using Umbraco.Web.Actions; using Umbraco.Web.Composing; -using Umbraco.Web._Legacy.Actions; + namespace umbraco.presentation.webservices { @@ -186,7 +187,7 @@ namespace umbraco.presentation.webservices //send notifications! TODO: This should be put somewhere centralized instead of hard coded directly here if (parentId > 0) { - Services.NotificationService.SendNotification(contentService.GetById(parentId), ActionSort.Instance, UmbracoContext, Services.TextService, GlobalSettings); + Services.NotificationService.SendNotification(contentService.GetById(parentId), Current.Actions.GetAction(), UmbracoContext, Services.TextService, GlobalSettings); } } From f4b970e88741fac418aec9692971cae199f30e78 Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 29 Oct 2018 11:21:30 +0100 Subject: [PATCH 098/337] Fix timing-dependent test --- src/Umbraco.Tests/Persistence/LocksTests.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/Persistence/LocksTests.cs b/src/Umbraco.Tests/Persistence/LocksTests.cs index 819dbc89ed..56779ace0f 100644 --- a/src/Umbraco.Tests/Persistence/LocksTests.cs +++ b/src/Umbraco.Tests/Persistence/LocksTests.cs @@ -203,7 +203,14 @@ namespace Umbraco.Tests.Persistence Assert.IsNotNull(e1); Assert.IsInstanceOf(e1); - Assert.IsNull(e2); + // the assertion below depends on timing conditions - on a fast enough environment, + // thread1 dies (deadlock) and frees thread2, which succeeds - however on a slow + // environment (CI) both threads can end up dying due to deadlock - so, cannot test + // that e2 is null - but if it's not, can test that it's a timeout + // + //Assert.IsNull(e2); + if (e2 != null) + Assert.IsInstanceOf(e2); } private void DeadLockTestThread(int id1, int id2, EventWaitHandle myEv, WaitHandle otherEv, ref Exception exception) From db3ae6c27dd2b05ef887bf36ba4025e9971babf1 Mon Sep 17 00:00:00 2001 From: Shyam Jalan Date: Sat, 27 Oct 2018 11:10:24 +0530 Subject: [PATCH 099/337] Added hyphenation to README at desired places --- .github/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/README.md b/.github/README.md index e8a9889916..fc401ecfd2 100644 --- a/.github/README.md +++ b/.github/README.md @@ -30,7 +30,7 @@ As an Open Source platform, Umbraco is more than just a CMS. We are transparent ## Trying out Umbraco CMS -[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and intergrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed. +[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and intergrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14-day trial, no credit card needed. If you want to DIY you can [download Umbraco](https://our.umbraco.com/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host yourself and handling deployments and upgrades is all down to you. @@ -47,4 +47,4 @@ Umbraco is contribution focused and community driven. If you want to contribute Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md). You can comment and report issues on the [github issue tracker](https://github.com/umbraco/Umbraco-CMS/issues). -Since [September 2018](https://umbraco.com/blog/a-second-take-on-umbraco-issue-tracker-hello-github-issues/) the old issue tracker is in read only mode, but can still be found at [http://issues.umbraco.org](http://issues.umbraco.org). +Since [September 2018](https://umbraco.com/blog/a-second-take-on-umbraco-issue-tracker-hello-github-issues/) the old issue tracker is in read-only mode, but can still be found at [http://issues.umbraco.org](http://issues.umbraco.org). From 777d88ed8ff234386e8a5c69172ffb00b687592f Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 29 Oct 2018 12:38:46 +0100 Subject: [PATCH 100/337] Fixed unit test --- src/Umbraco.Tests/UI/LegacyDialogTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/UI/LegacyDialogTests.cs b/src/Umbraco.Tests/UI/LegacyDialogTests.cs index 99391104ab..be9b0d4d7e 100644 --- a/src/Umbraco.Tests/UI/LegacyDialogTests.cs +++ b/src/Umbraco.Tests/UI/LegacyDialogTests.cs @@ -23,7 +23,7 @@ namespace Umbraco.Tests.UI } } - [TestCase(typeof(macroTasks), Constants.Applications.Packages)] + [TestCase(typeof(macroTasks), Constants.Applications.Settings)] [TestCase(typeof(CreatedPackageTasks), Constants.Applications.Packages)] public void Check_Assigned_Apps_For_Tasks(Type taskType, string app) { From cb9843b023ce9ef3afbd58b3973ed76c0bc73b35 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 29 Oct 2018 23:23:21 +1100 Subject: [PATCH 101/337] Removes IActions that shouldn't be IActions --- src/Umbraco.Web/Actions/ActionCollection.cs | 2 +- .../Actions/ActionCollectionBuilder.cs | 13 +++++++++++ .../Actions/ActionEmptyTranscan.cs | 16 ------------- src/Umbraco.Web/Actions/ActionExport.cs | 15 ------------ src/Umbraco.Web/Actions/ActionImport.cs | 15 ------------ src/Umbraco.Web/Actions/ActionNotify.cs | 16 ------------- src/Umbraco.Web/Actions/ActionRePublish.cs | 16 ------------- src/Umbraco.Web/Actions/ActionRefresh.cs | 23 ------------------- .../Models/Trees/ActionMenuItem.cs | 15 +++++++++--- .../Models/Trees/CreateChildEntity.cs | 5 ++-- src/Umbraco.Web/Models/Trees/ExportMember.cs | 9 +++++++- src/Umbraco.Web/Models/Trees/MenuItem.cs | 8 +++++++ src/Umbraco.Web/Models/Trees/MenuItemList.cs | 22 ------------------ src/Umbraco.Web/Models/Trees/RefreshNode.cs | 6 ++--- .../Trees/ContentTreeController.cs | 8 +++++-- .../Trees/ContentTreeControllerBase.cs | 5 +++- .../Trees/ContentTypeTreeController.cs | 12 ++++++++-- src/Umbraco.Web/Trees/MemberTreeController.cs | 7 +----- src/Umbraco.Web/Umbraco.Web.csproj | 6 ----- 19 files changed, 67 insertions(+), 152 deletions(-) delete mode 100644 src/Umbraco.Web/Actions/ActionEmptyTranscan.cs delete mode 100644 src/Umbraco.Web/Actions/ActionExport.cs delete mode 100644 src/Umbraco.Web/Actions/ActionImport.cs delete mode 100644 src/Umbraco.Web/Actions/ActionNotify.cs delete mode 100644 src/Umbraco.Web/Actions/ActionRePublish.cs delete mode 100644 src/Umbraco.Web/Actions/ActionRefresh.cs diff --git a/src/Umbraco.Web/Actions/ActionCollection.cs b/src/Umbraco.Web/Actions/ActionCollection.cs index 70a3b67b02..64cf950c60 100644 --- a/src/Umbraco.Web/Actions/ActionCollection.cs +++ b/src/Umbraco.Web/Actions/ActionCollection.cs @@ -17,7 +17,7 @@ namespace Umbraco.Web.Actions internal T GetAction() where T : IAction { - return this.OfType().SingleOrDefault(); + return this.OfType().FirstOrDefault(); } internal IEnumerable GetByLetters(IEnumerable letters) diff --git a/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs b/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs index 71b1ef48a5..6002c8d2b0 100644 --- a/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs +++ b/src/Umbraco.Web/Actions/ActionCollectionBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using LightInject; using Umbraco.Core.Composing; @@ -14,5 +15,17 @@ namespace Umbraco.Web.Actions { } protected override ActionCollectionBuilder This => this; + + protected override IEnumerable CreateItems(params object[] args) + { + var items = base.CreateItems(args).ToList(); + //validate the items, no actions should exist that do not either expose notifications or permissions + var invalid = items.Where(x => !x.CanBePermissionAssigned && !x.ShowInNotifier).ToList(); + if (invalid.Count > 0) + { + throw new InvalidOperationException($"Invalid actions '{string.Join(", ", invalid.Select(x => x.Alias))}'. All {typeof(IAction)} implementations must be true for either {nameof(IAction.CanBePermissionAssigned)} or {nameof(IAction.ShowInNotifier)}"); + } + return items; + } } } diff --git a/src/Umbraco.Web/Actions/ActionEmptyTranscan.cs b/src/Umbraco.Web/Actions/ActionEmptyTranscan.cs deleted file mode 100644 index db70e2d2b2..0000000000 --- a/src/Umbraco.Web/Actions/ActionEmptyTranscan.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Umbraco.Web.UI.Pages; - - -namespace Umbraco.Web.Actions -{ - //fixme: not needed, remove this - public class ActionEmptyTranscan : IAction - { - public char Letter => 'N'; - public string Alias => "emptyRecycleBin"; - public string Category => null; - public string Icon => "trash"; - public bool ShowInNotifier => false; - public bool CanBePermissionAssigned => false; - } -} diff --git a/src/Umbraco.Web/Actions/ActionExport.cs b/src/Umbraco.Web/Actions/ActionExport.cs deleted file mode 100644 index 8843bee5ea..0000000000 --- a/src/Umbraco.Web/Actions/ActionExport.cs +++ /dev/null @@ -1,15 +0,0 @@ - - -namespace Umbraco.Web.Actions -{ - //fixme: not needed, remove this - public class ActionExport : IAction - { - public char Letter => '9'; - public string Alias => "export"; - public string Category => null; - public string Icon => "download-alt"; - public bool ShowInNotifier => false; - public bool CanBePermissionAssigned => false; - } -} diff --git a/src/Umbraco.Web/Actions/ActionImport.cs b/src/Umbraco.Web/Actions/ActionImport.cs deleted file mode 100644 index 1cd8682735..0000000000 --- a/src/Umbraco.Web/Actions/ActionImport.cs +++ /dev/null @@ -1,15 +0,0 @@ - - -namespace Umbraco.Web.Actions -{ - //fixme: not needed, remove this - public class ActionImport : IAction - { - public char Letter => '8'; - public string Alias => "importDocumentType"; - public string Category => null; - public string Icon => "page-up"; - public bool ShowInNotifier => false; - public bool CanBePermissionAssigned => false; - } -} diff --git a/src/Umbraco.Web/Actions/ActionNotify.cs b/src/Umbraco.Web/Actions/ActionNotify.cs deleted file mode 100644 index 218345a678..0000000000 --- a/src/Umbraco.Web/Actions/ActionNotify.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Umbraco.Web.UI.Pages; - - -namespace Umbraco.Web.Actions -{ - //fixme: not needed, remove this - public class ActionNotify : IAction - { - public char Letter => 'T'; - public string Alias => "notify"; - public string Category => null; - public string Icon => "megaphone"; - public bool ShowInNotifier => false; - public bool CanBePermissionAssigned => false; - } -} diff --git a/src/Umbraco.Web/Actions/ActionRePublish.cs b/src/Umbraco.Web/Actions/ActionRePublish.cs deleted file mode 100644 index c0af369370..0000000000 --- a/src/Umbraco.Web/Actions/ActionRePublish.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Umbraco.Web.UI.Pages; - - -namespace Umbraco.Web.Actions -{ - //fixme: not needed, remove this - public class ActionRePublish : IAction - { - public char Letter => 'B'; - public string Alias => "republish"; - public string Category => null; - public string Icon => "globe"; - public bool ShowInNotifier => false; - public bool CanBePermissionAssigned => false; - } -} diff --git a/src/Umbraco.Web/Actions/ActionRefresh.cs b/src/Umbraco.Web/Actions/ActionRefresh.cs deleted file mode 100644 index 38247f4e4b..0000000000 --- a/src/Umbraco.Web/Actions/ActionRefresh.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Umbraco.Web.Models.Trees; -using Umbraco.Web.UI.Pages; - - -namespace Umbraco.Web.Actions -{ - ///// - ///// This action is invoked when a node reloads its children - ///// Concerns only the tree itself and thus you should not handle - ///// this action from without umbraco. - ///// - //public class ActionRefresh : IAction - //{ - // public static string ActionAlias => "refreshNode"; - - // public char Letter => 'L'; - // public string Alias => ActionAlias; - // public string Icon => "refresh"; - // public bool ShowInNotifier => false; - // public bool CanBePermissionAssigned => false; - // public string Category => null; - //} -} diff --git a/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs b/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs index ed15b82b16..9354417155 100644 --- a/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs +++ b/src/Umbraco.Web/Models/Trees/ActionMenuItem.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using Umbraco.Core; +using Umbraco.Core.Services; namespace Umbraco.Web.Models.Trees { @@ -28,9 +29,17 @@ namespace Umbraco.Web.Models.Trees /// public virtual string AngularServiceMethodName { get; } = null; - [SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")] - protected ActionMenuItem() - : base() + protected ActionMenuItem(string alias, string name) : base(alias, name) + { + Initialize(); + } + + protected ActionMenuItem(string alias, ILocalizedTextService textService) : base(alias, textService) + { + Initialize(); + } + + private void Initialize() { //add the current type to the metadata if (AngularServiceMethodName.IsNullOrWhiteSpace()) diff --git a/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs b/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs index 90d0e9e1cb..022056c35d 100644 --- a/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs +++ b/src/Umbraco.Web/Models/Trees/CreateChildEntity.cs @@ -11,17 +11,16 @@ namespace Umbraco.Web.Models.Trees public override string AngularServiceName => "umbracoMenuActions"; public CreateChildEntity(string name, bool seperatorBefore = false) + : base(ActionNew.ActionAlias, name) { - Alias = ActionNew.ActionAlias; Icon = "add"; Name = name; SeperatorBefore = seperatorBefore; } public CreateChildEntity(ILocalizedTextService textService, bool seperatorBefore = false) + : base(ActionNew.ActionAlias, textService) { - Alias = ActionNew.ActionAlias; Icon = "add"; - Name = textService.Localize($"actions/{Alias}"); SeperatorBefore = seperatorBefore; } } diff --git a/src/Umbraco.Web/Models/Trees/ExportMember.cs b/src/Umbraco.Web/Models/Trees/ExportMember.cs index 5f3eaebd45..558f7c1fa1 100644 --- a/src/Umbraco.Web/Models/Trees/ExportMember.cs +++ b/src/Umbraco.Web/Models/Trees/ExportMember.cs @@ -1,4 +1,6 @@ -namespace Umbraco.Web.Models.Trees +using Umbraco.Core.Services; + +namespace Umbraco.Web.Models.Trees { /// /// Represents the export member menu item @@ -6,5 +8,10 @@ public sealed class ExportMember : ActionMenuItem { public override string AngularServiceName => "umbracoMenuActions"; + + public ExportMember(ILocalizedTextService textService) : base("export", textService) + { + Icon = "download-alt"; + } } } diff --git a/src/Umbraco.Web/Models/Trees/MenuItem.cs b/src/Umbraco.Web/Models/Trees/MenuItem.cs index fb586e02d6..3e8a43e03e 100644 --- a/src/Umbraco.Web/Models/Trees/MenuItem.cs +++ b/src/Umbraco.Web/Models/Trees/MenuItem.cs @@ -31,6 +31,14 @@ namespace Umbraco.Web.Models.Trees Name = name; } + + public MenuItem(string alias, ILocalizedTextService textService) + : this() + { + Alias = alias; + Name = textService.Localize($"actions/{Alias}"); + } + /// /// Create a menu item based on an definition /// diff --git a/src/Umbraco.Web/Models/Trees/MenuItemList.cs b/src/Umbraco.Web/Models/Trees/MenuItemList.cs index 1a8a2dd88c..672750825c 100644 --- a/src/Umbraco.Web/Models/Trees/MenuItemList.cs +++ b/src/Umbraco.Web/Models/Trees/MenuItemList.cs @@ -38,28 +38,6 @@ namespace Umbraco.Web.Models.Trees return item; } - /// - /// Adds a menu item based on an - /// - /// The text to display for the menu item, will default to the IAction alias if not specified - /// - public MenuItem Add(string name) - where T : IAction - { - return Add(name, false); - } - - /// - /// Adds a menu item based on an - /// - /// The used to localize the action name based on it's alias - /// - public MenuItem Add(ILocalizedTextService textService) - where T : IAction - { - return Add(textService, false); - } - /// /// Adds a menu item with a dictionary which is merged to the AdditionalData bag /// diff --git a/src/Umbraco.Web/Models/Trees/RefreshNode.cs b/src/Umbraco.Web/Models/Trees/RefreshNode.cs index 587c51b887..2641baa34f 100644 --- a/src/Umbraco.Web/Models/Trees/RefreshNode.cs +++ b/src/Umbraco.Web/Models/Trees/RefreshNode.cs @@ -11,18 +11,16 @@ namespace Umbraco.Web.Models.Trees public override string AngularServiceName => "umbracoMenuActions"; public RefreshNode(string name, bool seperatorBefore = false) + : base("refreshNode", name) { - Alias = "refreshNode"; Icon = "refresh"; - Name = name; SeperatorBefore = seperatorBefore; } public RefreshNode(ILocalizedTextService textService, bool seperatorBefore = false) + : base("refreshNode", textService) { - Alias = "refreshNode"; Icon = "refresh"; - Name = textService.Localize($"actions/{Alias}"); SeperatorBefore = seperatorBefore; } } diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index a759382854..a7598e5d3a 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -240,8 +240,12 @@ namespace Umbraco.Web.Trees AddActionNode(item, menu); AddActionNode(item, menu); AddActionNode(item, menu, true, true); - - AddActionNode(item, menu, true); + + menu.Items.Add(new MenuItem("notify", Services.TextService) + { + Icon = "megaphone", + SeperatorBefore = true + }); menu.Items.Add(new RefreshNode(Services.TextService, true)); diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index c02f691f14..1398903cfc 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -349,7 +349,10 @@ namespace Umbraco.Web.Trees if (RecycleBinId.ToInvariantString() == id) { var menu = new MenuItemCollection(); - menu.Items.Add(Services.TextService.Localize("actions/emptyTrashcan")); + menu.Items.Add(new MenuItem("emptyRecycleBin", Services.TextService) + { + Icon = "trash" + }); menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } diff --git a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs index 673c5f4168..32367ad02c 100644 --- a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs @@ -82,7 +82,11 @@ namespace Umbraco.Web.Trees // root actions menu.Items.Add(Services.TextService); - menu.Items.Add(Services.TextService, true); + menu.Items.Add(new MenuItem("importDocumentType", Services.TextService) + { + Icon = "page-up", + SeperatorBefore = true + }); menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; @@ -123,7 +127,11 @@ namespace Umbraco.Web.Trees menu.Items.Add(Services.TextService, true); } menu.Items.Add(Services.TextService); - menu.Items.Add(Services.TextService, true); + menu.Items.Add(new MenuItem("export", Services.TextService) + { + Icon = "download-alt", + SeperatorBefore = true + }); menu.Items.Add(Services.TextService, true); if (enableInheritedDocumentTypes) menu.Items.Add(new RefreshNode(Services.TextService, true)); diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index f8bcb47b56..24fc624110 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -185,12 +185,7 @@ namespace Umbraco.Web.Trees if (Security.CurrentUser.HasAccessToSensitiveData()) { - menu.Items.Add(new ExportMember - { - Name = Services.TextService.Localize("actions/export"), - Icon = "download-alt", - Alias = "export" - }); + menu.Items.Add(new ExportMember(Services.TextService)); } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index f7317939dd..ff48b7ab9e 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -538,16 +538,10 @@ - - - - - - From 77f4f0bbad2622a495c6674cb7983ae6a2d56753 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 00:34:43 +1100 Subject: [PATCH 102/337] Refactors how the 'OpensDialog' gets assigned to menu items, fixes permission check on rollback --- src/Umbraco.Web/Actions/ActionRollback.cs | 4 +- src/Umbraco.Web/Editors/ContentController.cs | 1 + src/Umbraco.Web/Models/Trees/MenuItem.cs | 4 +- src/Umbraco.Web/Models/Trees/MenuItemList.cs | 8 ++-- .../Trees/ContentBlueprintTreeController.cs | 6 +-- .../Trees/ContentTreeController.cs | 37 +++++++++---------- .../Trees/ContentTreeControllerBase.cs | 3 +- .../Trees/ContentTypeTreeController.cs | 22 ++++++----- .../Trees/DataTypeTreeController.cs | 10 ++--- .../Trees/DictionaryTreeController.cs | 4 +- .../Trees/FileSystemTreeController.cs | 8 ++-- src/Umbraco.Web/Trees/MacrosTreeController.cs | 4 +- src/Umbraco.Web/Trees/MediaTreeController.cs | 13 ++++--- .../Trees/MediaTypeTreeController.cs | 18 ++++----- src/Umbraco.Web/Trees/MemberTreeController.cs | 11 +++--- .../MemberTypeAndGroupTreeControllerBase.cs | 2 +- .../Trees/PackagesTreeController.cs | 6 +-- .../Trees/RelationTypeTreeController.cs | 4 +- .../Trees/TemplatesTreeController.cs | 4 +- 19 files changed, 89 insertions(+), 80 deletions(-) diff --git a/src/Umbraco.Web/Actions/ActionRollback.cs b/src/Umbraco.Web/Actions/ActionRollback.cs index adfdd752cf..96ce1e7767 100644 --- a/src/Umbraco.Web/Actions/ActionRollback.cs +++ b/src/Umbraco.Web/Actions/ActionRollback.cs @@ -10,7 +10,9 @@ namespace Umbraco.Web.Actions /// public class ActionRollback : IAction { - public char Letter => 'K'; + public const char ActionLetter = 'K'; + + public char Letter => ActionLetter; public string Alias => "rollback"; public string Category => Constants.Conventions.PermissionCategories.AdministrationCategory; public string Icon => "undo"; diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 4a68ca1d91..c1ed76dbc8 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1761,6 +1761,7 @@ namespace Umbraco.Web.Editors : content.Variants.FirstOrDefault(x => x.Language.IsoCode == culture); } + [EnsureUserPermissionForContent("contentId", ActionRollback.ActionLetter)] [HttpPost] public HttpResponseMessage PostRollbackContent(int contentId, int versionId, string culture = "*") { diff --git a/src/Umbraco.Web/Models/Trees/MenuItem.cs b/src/Umbraco.Web/Models/Trees/MenuItem.cs index dfafa7ce41..4170cdb73f 100644 --- a/src/Umbraco.Web/Models/Trees/MenuItem.cs +++ b/src/Umbraco.Web/Models/Trees/MenuItem.cs @@ -52,7 +52,6 @@ namespace Umbraco.Web.Models.Trees SeperatorBefore = false; Icon = action.Icon; Action = action; - OpensDialog = legacyMenu.OpensDialog; } #endregion @@ -87,6 +86,9 @@ namespace Umbraco.Web.Models.Trees [DataMember(Name = "cssclass")] public string Icon { get; set; } + /// + /// Used in the UI to inform the user that the menu item will open a dialog/confirmation + /// [DataMember(Name = "opensDialog")] public bool OpensDialog { get; set; } diff --git a/src/Umbraco.Web/Models/Trees/MenuItemList.cs b/src/Umbraco.Web/Models/Trees/MenuItemList.cs index 672750825c..b34f0b4444 100644 --- a/src/Umbraco.Web/Models/Trees/MenuItemList.cs +++ b/src/Umbraco.Web/Models/Trees/MenuItemList.cs @@ -62,7 +62,8 @@ namespace Umbraco.Web.Models.Trees /// /// /// The used to localize the action name based on it's alias - public MenuItem Add(ILocalizedTextService textService, bool hasSeparator = false) + /// + public MenuItem Add(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) where T : IAction { var item = CreateMenuItem(textService, hasSeparator); @@ -87,7 +88,7 @@ namespace Umbraco.Web.Models.Trees return menuItem; } - internal MenuItem CreateMenuItem(ILocalizedTextService textService, bool hasSeparator = false) + internal MenuItem CreateMenuItem(ILocalizedTextService textService, bool hasSeparator = false, bool opensDialog = false) where T : IAction { var item = Current.Actions.GetAction(); @@ -95,7 +96,8 @@ namespace Umbraco.Web.Models.Trees var menuItem = new MenuItem(item, textService.Localize($"actions/{item.Alias}")) { - SeperatorBefore = hasSeparator + SeperatorBefore = hasSeparator, + OpensDialog = opensDialog }; return menuItem; diff --git a/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs b/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs index 01df73f4af..364c9c391f 100644 --- a/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentBlueprintTreeController.cs @@ -93,7 +93,7 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { // root actions - menu.Items.Add(Services.TextService.Localize($"actions/{ActionNew.ActionAlias}")); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } @@ -102,7 +102,7 @@ namespace Umbraco.Web.Trees if (cte != null) { var ct = Services.ContentTypeService.Get(cte.Id); - var createItem = menu.Items.Add(Services.TextService); + var createItem = menu.Items.Add(Services.TextService, opensDialog: true); createItem.NavigateToRoute("/settings/contentBlueprints/edit/-1?create=true&doctype=" + ct.Alias); menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -110,7 +110,7 @@ namespace Umbraco.Web.Trees return menu; } - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); return menu; } diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index a7598e5d3a..1667299436 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -128,9 +128,8 @@ namespace Umbraco.Web.Trees .Select(x => new MenuItem(x)); //these two are the standard items - //fixme: inject - menu.Items.Add(Services.TextService.Localize("actions", ActionNew.ActionAlias)); - menu.Items.Add(Services.TextService.Localize("actions", Current.Actions.GetAction().Alias), true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, true); //filter the standard items FilterUserAllowedMenuItems(menu, nodeActions); @@ -226,25 +225,22 @@ namespace Umbraco.Web.Trees protected MenuItemCollection GetAllNodeMenuItems(IUmbracoEntity item) { var menu = new MenuItemCollection(); - AddActionNode(item, menu); - AddActionNode(item, menu); - - AddActionNode(item, menu); - - //need to ensure some of these are converted to the legacy system - until we upgrade them all to be angularized. - AddActionNode(item, menu, true); - AddActionNode(item, menu); - + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, true, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); AddActionNode(item, menu, true); - - AddActionNode(item, menu); - AddActionNode(item, menu); - AddActionNode(item, menu, true, true); + AddActionNode(item, menu, opensDialog: true); + AddActionNode(item, menu, opensDialog: true); + //fixme - conver this editor to angular + AddActionNode(item, menu, true, convert: true, opensDialog: true); menu.Items.Add(new MenuItem("notify", Services.TextService) { Icon = "megaphone", - SeperatorBefore = true + SeperatorBefore = true, + OpensDialog = true }); menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -260,8 +256,8 @@ namespace Umbraco.Web.Trees protected MenuItemCollection GetNodeMenuItemsForDeletedContent(IUmbracoEntity item) { var menu = new MenuItemCollection(); - menu.Items.Add(Services.TextService.Localize("actions", ActionRestore.ActionAlias)); - menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.ActionAlias)); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -308,12 +304,13 @@ namespace Umbraco.Web.Trees } //fixme: Remove the need for converting to legacy - private void AddActionNode(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false) + private void AddActionNode(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false, bool opensDialog = false) where TAction : IAction { //fixme: Inject var menuItem = menu.Items.Add(Services.TextService.Localize("actions", Current.Actions.GetAction().Alias), hasSeparator); if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content"); + menuItem.OpensDialog = opensDialog; } ////fixme: Remove the need for converting to legacy diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index 1398903cfc..646f47068b 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -351,7 +351,8 @@ namespace Umbraco.Web.Trees var menu = new MenuItemCollection(); menu.Items.Add(new MenuItem("emptyRecycleBin", Services.TextService) { - Icon = "trash" + Icon = "trash", + OpensDialog = true }); menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; diff --git a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs index 32367ad02c..43e5b03f2f 100644 --- a/src/Umbraco.Web/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTypeTreeController.cs @@ -81,11 +81,12 @@ namespace Umbraco.Web.Trees menu.DefaultMenuAlias = ActionNew.ActionAlias; // root actions - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new MenuItem("importDocumentType", Services.TextService) { Icon = "page-up", - SeperatorBefore = true + SeperatorBefore = true, + OpensDialog = true }); menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -98,9 +99,9 @@ namespace Umbraco.Web.Trees //set the default to create menu.DefaultMenuAlias = ActionNew.ActionAlias; - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); - menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename")) + menu.Items.Add(new MenuItem("rename", Services.TextService) { Icon = "icon icon-edit" }); @@ -108,7 +109,7 @@ namespace Umbraco.Web.Trees if (container.HasChildren == false) { //can delete doc type - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } menu.Items.Add(new RefreshNode(Services.TextService, true)); } @@ -119,20 +120,21 @@ namespace Umbraco.Web.Trees if (enableInheritedDocumentTypes) { - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); } //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new MenuItem("export", Services.TextService) { Icon = "download-alt", - SeperatorBefore = true + SeperatorBefore = true, + OpensDialog = true }); - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); if (enableInheritedDocumentTypes) menu.Items.Add(new RefreshNode(Services.TextService, true)); } diff --git a/src/Umbraco.Web/Trees/DataTypeTreeController.cs b/src/Umbraco.Web/Trees/DataTypeTreeController.cs index 4f9f93f110..6c89f4a1dc 100644 --- a/src/Umbraco.Web/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/DataTypeTreeController.cs @@ -104,7 +104,7 @@ namespace Umbraco.Web.Trees menu.DefaultMenuAlias = ActionNew.ActionAlias; // root actions - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; } @@ -115,7 +115,7 @@ namespace Umbraco.Web.Trees //set the default to create menu.DefaultMenuAlias = ActionNew.ActionAlias; - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename")) { @@ -125,7 +125,7 @@ namespace Umbraco.Web.Trees if (container.HasChildren == false) { //can delete data type - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); } menu.Items.Add(new RefreshNode(Services.TextService, true)); } @@ -134,9 +134,9 @@ namespace Umbraco.Web.Trees var nonDeletableSystemDataTypeIds = GetNonDeletableSystemDataTypeIds(); if (nonDeletableSystemDataTypeIds.Contains(int.Parse(id)) == false) - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); - menu.Items.Add(Services.TextService, hasSeparator: true); + menu.Items.Add(Services.TextService, hasSeparator: true, opensDialog: true); } return menu; diff --git a/src/Umbraco.Web/Trees/DictionaryTreeController.cs b/src/Umbraco.Web/Trees/DictionaryTreeController.cs index a0510acd3e..d0a7fce3ad 100644 --- a/src/Umbraco.Web/Trees/DictionaryTreeController.cs +++ b/src/Umbraco.Web/Trees/DictionaryTreeController.cs @@ -96,10 +96,10 @@ namespace Umbraco.Web.Trees { var menu = new MenuItemCollection(); - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); if (id != Constants.System.Root.ToInvariantString()) - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); menu.Items.Add(new RefreshNode(Services.TextService, true)); diff --git a/src/Umbraco.Web/Trees/FileSystemTreeController.cs b/src/Umbraco.Web/Trees/FileSystemTreeController.cs index a517cd45c2..f1e53ed5d4 100644 --- a/src/Umbraco.Web/Trees/FileSystemTreeController.cs +++ b/src/Umbraco.Web/Trees/FileSystemTreeController.cs @@ -82,7 +82,7 @@ namespace Umbraco.Web.Trees //set the default to create menu.DefaultMenuAlias = ActionNew.ActionAlias; //create action - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); //refresh action menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -96,7 +96,7 @@ namespace Umbraco.Web.Trees //set the default to create menu.DefaultMenuAlias = ActionNew.ActionAlias; //create action - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any(); @@ -104,7 +104,7 @@ namespace Umbraco.Web.Trees if (hasChildren == false) { //delete action - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } //refresh action @@ -118,7 +118,7 @@ namespace Umbraco.Web.Trees var menu = new MenuItemCollection(); //if it's not a directory then we only allow to delete the item - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); return menu; } diff --git a/src/Umbraco.Web/Trees/MacrosTreeController.cs b/src/Umbraco.Web/Trees/MacrosTreeController.cs index 0faa1ce75d..3f925eef8d 100644 --- a/src/Umbraco.Web/Trees/MacrosTreeController.cs +++ b/src/Umbraco.Web/Trees/MacrosTreeController.cs @@ -59,7 +59,7 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { //Create the normal create action - menu.Items.Add(Services.TextService) + menu.Items.Add(Services.TextService, opensDialog: true) //Since we haven't implemented anything for macros in angular, this needs to be converted to //use the legacy format .ConvertLegacyMenuItem(null, "initmacros", queryStrings.GetValue("application")); @@ -75,7 +75,7 @@ namespace Umbraco.Web.Trees if (macro == null) return new MenuItemCollection(); //add delete option for all macros - menu.Items.Add(Services.TextService) + menu.Items.Add(Services.TextService, opensDialog: true) //Since we haven't implemented anything for macros in angular, this needs to be converted to //use the legacy format .ConvertLegacyMenuItem(new EntitySlim diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index d260253218..0292a907fc 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -95,7 +95,7 @@ namespace Umbraco.Web.Trees } // root actions - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(Services.TextService, true); menu.Items.Add(new RefreshNode(Services.TextService, true)); return menu; @@ -119,9 +119,9 @@ namespace Umbraco.Web.Trees } //return a normal node menu: - menu.Items.Add(Services.TextService); - menu.Items.Add(Services.TextService); - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(Services.TextService); menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -129,7 +129,10 @@ namespace Umbraco.Web.Trees if (item.Path.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Contains(RecycleBinId.ToInvariantString())) { menu.DefaultMenuAlias = null; - menu.Items.Insert(2, new MenuItem(Current.Actions.GetAction(), Services.TextService.Localize("actions", ActionRestore.ActionAlias))); + menu.Items.Insert(2, new MenuItem(ActionRestore.ActionAlias, Services.TextService) + { + OpensDialog = true + }); } else { diff --git a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs index a679cefa32..547199676a 100644 --- a/src/Umbraco.Web/Trees/MediaTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTypeTreeController.cs @@ -74,7 +74,7 @@ namespace Umbraco.Web.Trees menu.DefaultMenuAlias = ActionNew.ActionAlias; // root actions - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new RefreshNode(Services.TextService)); return menu; } @@ -85,7 +85,7 @@ namespace Umbraco.Web.Trees //set the default to create menu.DefaultMenuAlias = ActionNew.ActionAlias; - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); menu.Items.Add(new MenuItem("rename", Services.TextService.Localize("actions/rename")) { @@ -95,7 +95,7 @@ namespace Umbraco.Web.Trees if (container.HasChildren == false) { //can delete doc type - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); } menu.Items.Add(new RefreshNode(Services.TextService, true)); } @@ -106,26 +106,26 @@ namespace Umbraco.Web.Trees if (enableInheritedMediaTypes) { - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } } else { - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); //no move action if this is a child doc type if (parent == null) { - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } } - menu.Items.Add(Services.TextService); - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); + menu.Items.Add(Services.TextService, opensDialog: true); if (enableInheritedMediaTypes) menu.Items.Add(new RefreshNode(Services.TextService, true)); } diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index 24fc624110..68819351c0 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -159,17 +159,16 @@ namespace Umbraco.Web.Trees menu.DefaultMenuAlias = ActionNew.ActionAlias; //Create the normal create action - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); } else { //Create a custom create action - this does not launch a dialog, it just navigates to the create screen // we'll create it based on the ActionNew so it maintains the same icon properties, name, etc... - var createMenuItem = new MenuItem + var createMenuItem = new MenuItem(ActionNew.ActionAlias, Services.TextService) { - Name = Services.TextService.Localize($"actions/{ActionNew.ActionAlias}"), - Alias = ActionNew.ActionAlias, - Icon = "add" + Icon = "add", + OpensDialog = true }; //we want to go to this route: /member/member/edit/-1?create=true createMenuItem.NavigateToRoute("/member/member/edit/-1?create=true"); @@ -181,7 +180,7 @@ namespace Umbraco.Web.Trees } //add delete option for all members - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); if (Security.CurrentUser.HasAccessToSensitiveData()) { diff --git a/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs b/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs index 484ea1e2a9..9ea5908891 100644 --- a/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/MemberTypeAndGroupTreeControllerBase.cs @@ -33,7 +33,7 @@ namespace Umbraco.Web.Trees else { //delete member type/group - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); } return menu; diff --git a/src/Umbraco.Web/Trees/PackagesTreeController.cs b/src/Umbraco.Web/Trees/PackagesTreeController.cs index 8f62047941..8158b47985 100644 --- a/src/Umbraco.Web/Trees/PackagesTreeController.cs +++ b/src/Umbraco.Web/Trees/PackagesTreeController.cs @@ -84,12 +84,12 @@ namespace Umbraco.Web.Trees // Root actions if (id == "-1") { - menu.Items.Add(Services.TextService) + menu.Items.Add(Services.TextService, opensDialog: true) .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application")); } else if (id == "created") { - menu.Items.Add(Services.TextService) + menu.Items.Add(Services.TextService, opensDialog: true) .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application")); menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -97,7 +97,7 @@ namespace Umbraco.Web.Trees else { //it's a package node - menu.Items.Add(Services.TextService); + menu.Items.Add(Services.TextService, opensDialog: true); } return menu; diff --git a/src/Umbraco.Web/Trees/RelationTypeTreeController.cs b/src/Umbraco.Web/Trees/RelationTypeTreeController.cs index ab6e9e2dd7..33ccc152c5 100644 --- a/src/Umbraco.Web/Trees/RelationTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/RelationTypeTreeController.cs @@ -25,7 +25,7 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { //Create the normal create action - var addMenuItem = menu.Items.Add(Services.TextService); + var addMenuItem = menu.Items.Add(Services.TextService, opensDialog: true); addMenuItem.LaunchDialogUrl("developer/RelationTypes/NewRelationType.aspx", "Create New RelationType"); //refresh action menu.Items.Add(new RefreshNode(Services.TextService, true)); @@ -37,7 +37,7 @@ namespace Umbraco.Web.Trees if (relationType == null) return new MenuItemCollection(); //add delete option for all macros - menu.Items.Add(Services.TextService) + menu.Items.Add(Services.TextService, opensDialog: true) //Since we haven't implemented anything for relationtypes in angular, this needs to be converted to //use the legacy format .ConvertLegacyMenuItem(new EntitySlim diff --git a/src/Umbraco.Web/Trees/TemplatesTreeController.cs b/src/Umbraco.Web/Trees/TemplatesTreeController.cs index 3ae45a072e..2339d92d96 100644 --- a/src/Umbraco.Web/Trees/TemplatesTreeController.cs +++ b/src/Umbraco.Web/Trees/TemplatesTreeController.cs @@ -70,7 +70,7 @@ namespace Umbraco.Web.Trees var menu = new MenuItemCollection(); //Create the normal create action - var item = menu.Items.Add(Services.TextService); + var item = menu.Items.Add(Services.TextService, opensDialog: true); item.NavigateToRoute($"{queryStrings.GetValue("application")}/templates/edit/{id}?create=true"); if (id == Constants.System.Root.ToInvariantString()) @@ -89,7 +89,7 @@ namespace Umbraco.Web.Trees if (template.IsMasterTemplate == false) { //add delete option if it doesn't have children - menu.Items.Add(Services.TextService, true); + menu.Items.Add(Services.TextService, true, opensDialog: true); } //add refresh From 372f77fde5a16641960fa92b9c9637e9a53b3199 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 00:36:11 +1100 Subject: [PATCH 103/337] reverts accidental change --- src/Umbraco.Web/Editors/ContentController.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index c1ed76dbc8..53e2593fef 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -944,13 +944,13 @@ namespace Umbraco.Web.Editors /// /// [EnsureUserPermissionForContent("id", 'U')] - public HttpResponseMessage PostPublishById(ContentPublish model) + public HttpResponseMessage PostPublishById(int id) { - var foundContent = GetObjectFromRequest(() => Services.ContentService.GetById(model.Id)); + var foundContent = GetObjectFromRequest(() => Services.ContentService.GetById(id)); if (foundContent == null) { - return HandleContentNotFound(model.Id, false); + return HandleContentNotFound(id, false); } var publishResult = Services.ContentService.SavePublishing(foundContent, Security.GetUserId().ResultOr(0)); From 15eaa33e08be55cc43e1cee59b261a7e22b05083 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 01:15:23 +1100 Subject: [PATCH 104/337] updates migration to invariant string check --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index accb755020..64ee2f6b88 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -65,17 +65,17 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 var requiresCacheRebuild = false; switch (dd.EditorAlias) { - case "Umbraco.DropDown": + case string ea when ea.InvariantEquals("Umbraco.DropDown"): UpdateDataType(dd, config, false); break; - case "Umbraco.DropdownlistPublishingKeys": + case string ea when ea.InvariantEquals("Umbraco.DropdownlistPublishingKeys"): UpdateDataType(dd, config, false); requiresCacheRebuild = true; break; - case "Umbraco.DropDownMultiple": + case string ea when ea.InvariantEquals("Umbraco.DropDownMultiple"): UpdateDataType(dd, config, false); break; - case "Umbraco.DropdownlistMultiplePublishKeys": + case string ea when ea.InvariantEquals("Umbraco.DropdownlistMultiplePublishKeys"): UpdateDataType(dd, config, true); requiresCacheRebuild = true; break; From 0d0d26d3e994ad42ecfd9edb77319d15adc0c2dc Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 02:05:43 +1100 Subject: [PATCH 105/337] Fixes converting the Umbraco.DropDownMultiple to a multiple drop down, fixes boolean logic on the js single drop down --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 2 +- .../dropdownFlexible/dropdownFlexible.controller.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 64ee2f6b88..87d7a8c571 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -73,7 +73,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 requiresCacheRebuild = true; break; case string ea when ea.InvariantEquals("Umbraco.DropDownMultiple"): - UpdateDataType(dd, config, false); + UpdateDataType(dd, config, true); break; case string ea when ea.InvariantEquals("Umbraco.DropdownlistMultiplePublishKeys"): UpdateDataType(dd, config, true); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index 23bd2c9a42..f8e02a240a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -77,7 +77,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo // if we run in single mode we'll store the value in a local variable // so we can pass an array as the model as our PropertyValueEditor expects that $scope.model.singleDropdownValue = ""; - if (Object.toBoolean($scope.model.config.multiple)) { + if (!Object.toBoolean($scope.model.config.multiple)) { $scope.model.singleDropdownValue = Array.isArray($scope.model.value) ? $scope.model.value[0] : $scope.model.value; } From f123331d421b4fed7485a3146af10139541bd58c Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 02:11:33 +1100 Subject: [PATCH 106/337] Fixes updating the storage type --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 87d7a8c571..600f952d6a 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Logging; +using Umbraco.Core.Models; namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 { @@ -96,6 +97,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 multiple = isMultiple, items = config.Items }; + dataType.DbType = ValueStorageType.Nvarchar.ToString(); dataType.Configuration = JsonConvert.SerializeObject(flexConfig); Database.Update(dataType); } From 386dd2281ce321666ce07a1b39069dc7227c68ab Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 02:18:07 +1100 Subject: [PATCH 107/337] Fixes log messages --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 600f952d6a..e5cda85168 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -35,7 +35,9 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 } catch (Exception ex) { - Logger.Error(ex, $"Invalid drop down configuration detected: \"{dd.Configuration}\", cannot convert editor, values will be cleared"); + Logger.Error( + ex, "Invalid drop down configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared", + dd.Configuration); dd.Configuration = null; Database.Update(dd); continue; @@ -132,7 +134,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 vals.Add(val.Value); else { - Logger.Warn($"Could not find associated data type configuration for stored Id {id}"); + Logger.Warn( + "Could not find associated data type configuration for stored Id {DataTypeId}", id); canConvert = false; } } From fc39568415f43a1f2cc484fcbf8dd4bc697e207f Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 14:49:25 +1100 Subject: [PATCH 108/337] Updated audit info to include full lang name --- .../Services/Implement/ContentService.cs | 20 ++++++++++++++----- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 6 +++--- .../Umbraco/config/lang/en_us.xml | 6 +++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index f14747cda3..3953e7a640 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -849,7 +849,7 @@ namespace Umbraco.Core.Services.Implement //track the cultures that have changed var culturesChanging = content.ContentType.VariesByCulture() - ? string.Join(",", content.CultureInfos.Where(x => x.Value.IsDirty()).Select(x => x.Key)) + ? content.CultureInfos.Where(x => x.Value.IsDirty()).Select(x => x.Key).ToList() : null; //TODO: Currently there's no way to change track which variant properties have changed, we only have change // tracking enabled on all values on the Property which doesn't allow us to know which variants have changed. @@ -867,7 +867,12 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(TreeChanged, this, new TreeChange(content, changeType).ToEventArgs()); if (culturesChanging != null) - Audit(AuditType.SaveVariant, userId, content.Id, $"Saved cultures: {culturesChanging}", culturesChanging); + { + var langs = string.Join(", ", _languageRepository.GetMany() + .Where(x => culturesChanging.InvariantContains(x.IsoCode)) + .Select(x => x.CultureName)); + Audit(AuditType.SaveVariant, userId, content.Id, $"Saved languagues: {langs}", langs); + } else Audit(AuditType.Save, userId, content.Id); @@ -1057,7 +1062,7 @@ namespace Umbraco.Core.Services.Implement var publishing = content.PublishedState == PublishedState.Publishing; var unpublishing = content.PublishedState == PublishedState.Unpublishing; - string culturesChanging = null; + IEnumerable culturesChanging = null; using (var scope = ScopeProvider.CreateScope()) { @@ -1082,7 +1087,7 @@ namespace Umbraco.Core.Services.Implement } else { - culturesChanging = string.Join(",", content.PublishCultureInfos.Where(x => x.Value.IsDirty()).Select(x => x.Key)); + culturesChanging = content.PublishCultureInfos.Where(x => x.Value.IsDirty()).Select(x => x.Key).ToList(); } } @@ -1193,7 +1198,12 @@ namespace Umbraco.Core.Services.Implement } if (culturesChanging != null) - Audit(AuditType.PublishVariant, userId, content.Id, $"Published cultures: {culturesChanging}", culturesChanging); + { + var langs = string.Join(", ", _languageRepository.GetMany() + .Where(x => culturesChanging.InvariantContains(x.IsoCode)) + .Select(x => x.CultureName)); + Audit(AuditType.PublishVariant, userId, content.Id, $"Published languagues: {langs}", langs); + } else Audit(AuditType.Publish, userId, content.Id); diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 8bc9d190fa..6ee8fc2428 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -143,14 +143,14 @@ Content deleted Content unpublished Content saved and Published - Content cultures %0% saved and published + Content languages: %0% saved and published Content saved - Content cultures %0% saved + Content languages: %0% saved Content moved Content copied Content rolled back Content sent for publishing - Content cultures %0% sent for publishing + Content languages: %0% sent for publishing Sort child items performed by user Copy Publish diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index a2487b2dc8..a710abde5a 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -148,14 +148,14 @@ Content deleted Content unpublished Content saved and Published - Content cultures %0% saved and published + Content languages: %0% saved and published Content saved - Content cultures %0% saved + Content languages: %0% saved Content moved Content copied Content rolled back Content sent for publishing - Content cultures %0% sent for publishing + Content languages: %0% sent for publishing Sort child items performed by user Copy Publish From 9416c5f638d34ed36418a87974bd4b803f52d513 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 14:57:54 +1100 Subject: [PATCH 109/337] fixes up localized text for audit trail --- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 6 +++--- src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 6ee8fc2428..4abfdff0fb 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -143,14 +143,14 @@ Content deleted Content unpublished Content saved and Published - Content languages: %0% saved and published + Content saved and published for languages: %0% Content saved - Content languages: %0% saved + Content saved for languages: %0% Content moved Content copied Content rolled back Content sent for publishing - Content languages: %0% sent for publishing + Content sent for publishing for languages: %0% Sort child items performed by user Copy Publish diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index a710abde5a..87097e0b5e 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -148,14 +148,14 @@ Content deleted Content unpublished Content saved and Published - Content languages: %0% saved and published + Content saved and published for languages: %0% Content saved - Content languages: %0% saved + Content saved for languages: %0% Content moved Content copied Content rolled back Content sent for publishing - Content languages: %0% sent for publishing + Content sent for publishing for languages: %0% Sort child items performed by user Copy Publish From a383309e46912e3f434c3852acf4c2b2d576d1b7 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 17:32:27 +1100 Subject: [PATCH 110/337] Gets indexes updating based on content type changes --- .../Implement/DocumentRepository.cs | 2 +- src/Umbraco.Core/Services/IContentService.cs | 10 +- .../Services/Implement/ContentService.cs | 26 ++---- .../Services/ContentServiceTests.cs | 2 +- .../Services/PerformanceTests.cs | 34 ------- src/Umbraco.Web/Search/ExamineComponent.cs | 91 ++++++++++++++++++- 6 files changed, 105 insertions(+), 60 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs index f3afe99b28..b3a7c31e54 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs @@ -99,7 +99,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement private string VariantNameSqlExpression => SqlContext.VisitDto((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql; - protected virtual Sql GetBaseQuery(QueryType queryType, bool current) + protected Sql GetBaseQuery(QueryType queryType, bool current) { var sql = SqlContext.Sql(); diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 7371686c7c..0cfa0bb601 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -79,9 +79,15 @@ namespace Umbraco.Core.Services IEnumerable GetByIds(IEnumerable ids); /// - /// Gets documents of a given document type. + /// Gets paged documents of a content content /// - IEnumerable GetByType(int documentTypeId); + /// The page number. + /// The page number. + /// The page size. + /// Total number of documents. + /// Search text filter. + /// Ordering infos. + IEnumerable GetPagedOfType(int contentType, long pageIndex, int pageSize, out long totalRecords, IQuery filter = null, Ordering ordering = null); /// /// Gets documents at a given level. diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index 3953e7a640..64c6a23aff 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -405,28 +405,20 @@ namespace Umbraco.Core.Services.Implement } } - /// - /// Gets a collection of objects by the Id of the - /// - /// Id of the - /// An Enumerable list of objects - public IEnumerable GetByType(int id) + public IEnumerable GetPagedOfType(int contentTypeId, long pageIndex, int pageSize, out long totalRecords, IQuery filter, Ordering ordering = null) { - using (var scope = ScopeProvider.CreateScope(autoComplete: true)) - { - scope.ReadLock(Constants.Locks.ContentTree); - var query = Query().Where(x => x.ContentTypeId == id); - return _documentRepository.Get(query); - } - } + if(pageIndex < 0) throw new ArgumentOutOfRangeException(nameof(pageIndex)); + if (pageSize <= 0) throw new ArgumentOutOfRangeException(nameof(pageSize)); + + if (ordering == null) + ordering = Ordering.By("sortOrder"); - internal IEnumerable GetPublishedContentOfContentType(int id) - { using (var scope = ScopeProvider.CreateScope(autoComplete: true)) { scope.ReadLock(Constants.Locks.ContentTree); - var query = Query().Where(x => x.ContentTypeId == id); - return _documentRepository.Get(query); + return _documentRepository.GetPage( + Query().Where(x => x.ContentTypeId == contentTypeId), + pageIndex, pageSize, out totalRecords, filter, ordering); } } diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 5aad7c4d90..5b06037f90 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -1738,7 +1738,7 @@ namespace Umbraco.Tests.Services // Act contentService.DeleteOfType(contentType.Id); var rootContent = contentService.GetRootContent(); - var contents = contentService.GetByType(contentType.Id); + var contents = contentService.GetPagedOfType(contentType.Id, 0, int.MaxValue, out var _); // Assert Assert.That(rootContent.Any(), Is.False); diff --git a/src/Umbraco.Tests/Services/PerformanceTests.cs b/src/Umbraco.Tests/Services/PerformanceTests.cs index 9b0117c266..900a466a1d 100644 --- a/src/Umbraco.Tests/Services/PerformanceTests.cs +++ b/src/Umbraco.Tests/Services/PerformanceTests.cs @@ -108,40 +108,6 @@ namespace Umbraco.Tests.Services } } - [Test] - public void Get_All_Published_Content_Of_Type() - { - var result = PrimeDbWithLotsOfContent(); - var contentSvc = (ContentService)ServiceContext.ContentService; - - var countOfPublished = result.Count(x => x.Published); - var contentTypeId = result.First().ContentTypeId; - - var proflog = GetTestProfilingLogger(); - using (proflog.DebugDuration("Getting published content of type normally")) - { - //do this 10x! - for (var i = 0; i < 10; i++) - { - - //get all content items that are published of this type - var published = contentSvc.GetByType(contentTypeId).Where(content => content.Published); - Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId)); - } - } - - using (proflog.DebugDuration("Getting published content of type optimized")) - { - - //do this 10x! - for (var i = 0; i < 10; i++) - { - //get all content items that are published of this type - var published = contentSvc.GetPublishedContentOfContentType(contentTypeId); - Assert.AreEqual(countOfPublished, published.Count(x => x.ContentTypeId == contentTypeId)); - } - } - } [Test] public void Truncate_Insert_Vs_Update_Insert() diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index ff7d0c8dc4..530e8ba449 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -102,13 +102,10 @@ namespace Umbraco.Web.Search // bind to distributed cache events - this ensures that this logic occurs on ALL servers // that are taking part in a load balanced environment. ContentCacheRefresher.CacheUpdated += ContentCacheRefresherUpdated; + ContentTypeCacheRefresher.CacheUpdated += ContentTypeCacheRefresherUpdated; ; MediaCacheRefresher.CacheUpdated += MediaCacheRefresherUpdated; MemberCacheRefresher.CacheUpdated += MemberCacheRefresherUpdated; - // fixme - content type? - // events handling removed in ef013f9d3b945d0a48a306ff1afbd49c10c3fff8 - // because, could not make sense of it? - EnsureUnlocked(profilingLogger.Logger, examineManager); RebuildIndexesOnStartup(profilingLogger.Logger); @@ -317,6 +314,88 @@ namespace Umbraco.Web.Search } } + private void ContentTypeCacheRefresherUpdated(ContentTypeCacheRefresher sender, CacheRefresherEventArgs args) + { + + //before content type changes just caused full blown re-indexing: + // https://github.com/umbraco/Umbraco-CMS/commit/ef013f9d3b945d0a48a306ff1afbd49c10c3fff8 + + + if (Suspendable.ExamineEvents.CanIndex == false) + return; + + if (args.MessageType != MessageType.RefreshByPayload) + throw new NotSupportedException(); + + var contentService = _services.ContentService; + + var removedIds = new List(); + var refreshedIds = new List(); + + //TODO: What do we do about these? + var otherIds = new List(); + + foreach (var payload in (ContentTypeCacheRefresher.JsonPayload[])args.MessageObject) + { + if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.Remove)) + removedIds.Add(payload.Id); + else if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.RefreshMain)) + refreshedIds.Add(payload.Id); + else if (payload.ChangeTypes.HasType(ContentTypeChangeTypes.RefreshOther)) + otherIds.Add(payload.Id); + } + + const int pageSize = 500; + + //Re-index all content of these types + foreach(var id in refreshedIds) + { + var page = 0; + var total = long.MaxValue; + while (page * pageSize < total) + { + var contentToRefresh = _services.ContentService.GetPagedOfType(id, page++, pageSize, out total); + foreach(var c in contentToRefresh) + { + //TODO: We might have to order by Path ascending or something since we're going to need to check + // contentService.IsPathPublished(content) but we don't want to make that check for every content item + IContent published = null; + if (c.Published && contentService.IsPathPublished(c)) + published = c; + + ReIndexForContent(c, published); + } + } + } + + //Delete all content of this content type that is in any content indexer by looking up matched examine docs + foreach(var id in removedIds) + { + foreach(var index in _examineManager.IndexProviders.Values.OfType()) + { + var searcher = index.GetSearcher(); + + var page = 0; + var total = long.MaxValue; + while (page * pageSize < total) + { + //paging with examine, see https://shazwazza.com/post/paging-with-examine/ + var results = searcher.Search( + searcher.CreateCriteria().Field("nodeType", id).Compile(), + maxResults: pageSize * (page + 1)); + total = results.TotalItemCount; + var paged = results.Skip(page * pageSize); + + foreach(var item in paged) + if (int.TryParse(item.Id, out var contentId)) + DeleteIndexForEntity(contentId, false); + } + } + + + } + } + private void ContentCacheRefresherUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args) { if (Suspendable.ExamineEvents.CanIndex == false) @@ -340,6 +419,8 @@ namespace Umbraco.Web.Search // ExamineEvents does not support RefreshAll // just ignore that payload // so what?! + + //fixme: Rebuild the index at this point? } else // RefreshNode or RefreshBranch (maybe trashed) { @@ -355,7 +436,7 @@ namespace Umbraco.Web.Search } IContent published = null; - if (content.Published && ((ContentService)contentService).IsPathPublished(content)) + if (content.Published && contentService.IsPathPublished(content)) published = content; // just that content From 0a0dd025bfa32cf05531be3724d8e5130fa90d64 Mon Sep 17 00:00:00 2001 From: Pranjal Vyas <11768143+vyaspranjal33@users.noreply.github.com> Date: Tue, 30 Oct 2018 14:18:03 +0530 Subject: [PATCH 111/337] Update footer.tmpl.partial (#3481) --- apidocs/umbracotemplate/partials/footer.tmpl.partial | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apidocs/umbracotemplate/partials/footer.tmpl.partial b/apidocs/umbracotemplate/partials/footer.tmpl.partial index 69f51a101f..7aac413bfd 100644 --- a/apidocs/umbracotemplate/partials/footer.tmpl.partial +++ b/apidocs/umbracotemplate/partials/footer.tmpl.partial @@ -7,7 +7,7 @@ Back to top - Copyright © 2016 Umbraco
Generated by DocFX
+ Copyright © 2016-present Umbraco
Generated by DocFX
From 9b6204eb7b51220fdb4b909d53edd1afad497701 Mon Sep 17 00:00:00 2001 From: sweta jena <38930598+swetajena98@users.noreply.github.com> Date: Tue, 30 Oct 2018 14:18:28 +0530 Subject: [PATCH 112/337] add a comma (#3480) --- .github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 51f9b1dd68..50d18ca1f9 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -16,9 +16,9 @@ This document gives you a quick overview on how to get started, we will link to ## Guidelines for contributions we welcome -Not all changes are wanted so on occassion we might close a PR without merging it. We will give you feedback why we can't accept your changes and we'll be nice about it, thanking you for spending your valueable time. +Not all changes are wanted, so on occassion we might close a PR without merging it. We will give you feedback why we can't accept your changes and we'll be nice about it, thanking you for spending your valueable time. -We have [documented what we consider small and large changes](CONTRIBUTION_GUIDELINES.md), make sure to talk to us before making large changes. +We have [documented what we consider small and large changes](CONTRIBUTION_GUIDELINES.md). Make sure to talk to us before making large changes. Remember, if an issue is in the `Up for grabs` list or you've asked for some feedback before you sent us a PR, your PR will not be closed as unwanted. From 8ed3a95a56313e2fef2ea7377032586741683ae2 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Sun, 28 Oct 2018 21:18:53 +0100 Subject: [PATCH 113/337] Fix #3204 and do some refactoring to avoid duplicate code --- .../Services/NotificationService.cs | 60 ++++--------------- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/src/Umbraco.Core/Services/NotificationService.cs b/src/Umbraco.Core/Services/NotificationService.cs index cd94fd7ca7..07d6e4e9e5 100644 --- a/src/Umbraco.Core/Services/NotificationService.cs +++ b/src/Umbraco.Core/Services/NotificationService.cs @@ -58,54 +58,7 @@ namespace Umbraco.Core.Services if (entity is IContent == false) throw new NotSupportedException(); - var content = (IContent) entity; - - // lazily get previous version - IContentBase prevVersion = null; - - // do not load *all* users in memory at once - // do not load notifications *per user* (N+1 select) - // cannot load users & notifications in 1 query (combination btw User2AppDto and User2NodeNotifyDto) - // => get batches of users, get all their notifications in 1 query - // re. users: - // users being (dis)approved = not an issue, filtered in memory not in SQL - // users being modified or created = not an issue, ordering by ID, as long as we don't *insert* low IDs - // users being deleted = not an issue for GetNextUsers - var id = 0; - var nodeIds = content.Path.Split(',').Select(int.Parse).ToArray(); - const int pagesz = 400; // load batches of 400 users - do - { - // users are returned ordered by id, notifications are returned ordered by user id - var users = ((UserService) _userService).GetNextUsers(id, pagesz).Where(x => x.IsApproved).ToList(); - var notifications = GetUsersNotifications(users.Select(x => x.Id), action, nodeIds, Constants.ObjectTypes.DocumentGuid).ToList(); - if (notifications.Count == 0) break; - - var i = 0; - foreach (var user in users) - { - // continue if there's no notification for this user - if (notifications[i].UserId != user.Id) continue; // next user - - // lazy load prev version - if (prevVersion == null) - { - prevVersion = GetPreviousVersion(entity.Id); - } - - // queue notification - var req = CreateNotificationRequest(operatingUser, user, content, prevVersion, actionName, http, createSubject, createBody); - Enqueue(req); - - // skip other notifications for this user - while (i < notifications.Count && notifications[i++].UserId == user.Id) ; - if (i >= notifications.Count) break; // break if no more notifications - } - - // load more users if any - id = users.Count == pagesz ? users.Last().Id + 1 : -1; - - } while (id > 0); + SendNotifications(operatingUser, new[] { (IContent)entity }, action, actionName, http, createSubject, createBody); } /// @@ -154,7 +107,14 @@ namespace Umbraco.Core.Services // lazily get versions var prevVersionDictionary = new Dictionary(); - // see notes above + // do not load *all* users in memory at once + // do not load notifications *per user* (N+1 select) + // cannot load users & notifications in 1 query (combination btw User2AppDto and User2NodeNotifyDto) + // => get batches of users, get all their notifications in 1 query + // re. users: + // users being (dis)approved = not an issue, filtered in memory not in SQL + // users being modified or created = not an issue, ordering by ID, as long as we don't *insert* low IDs + // users being deleted = not an issue for GetNextUsers var id = 0; const int pagesz = 400; // load batches of 400 users do @@ -656,4 +616,4 @@ namespace Umbraco.Core.Services #endregion } -} \ No newline at end of file +} From 4e85ede436f36319b284d4bb1139201b7786545a Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Sun, 28 Oct 2018 20:36:37 +0100 Subject: [PATCH 114/337] Fix the notifications footer --- .../src/views/content/notify.html | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/content/notify.html b/src/Umbraco.Web.UI.Client/src/views/content/notify.html index ec9b3d2b0d..cb12d92f08 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/notify.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/notify.html @@ -1,44 +1,46 @@
-
-
-
-
-
{{vm.saveError.errorMsg}}
-
{{vm.saveError.data.message}}
+
+
+ +
+
+
{{vm.saveError.errorMsg}}
+
{{vm.saveError.data.message}}
+
-
-
-
- {{currentNode.name}} +
+
+ {{currentNode.name}} +
-
-
-
-
Set your notification for {{ currentNode.name }}
- - - - +
+
+
Set your notification for {{ currentNode.name }}
+ + + + +
-
- - + +
+
+
From 5537163c9f1bf4a1ae34b787d9ef742077f11fc7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 30 Oct 2018 15:19:48 +0100 Subject: [PATCH 115/337] remove debug data in colorpicker prevalue editor --- .../src/views/prevalueeditors/colorpicker.controller.js | 2 -- .../src/views/prevalueeditors/colorpicker.html | 4 ---- 2 files changed, 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js index c588893d7c..b4381b699b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.controller.js @@ -56,8 +56,6 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.ColorPickerControl } function isValidHex(str) { - console.log("str", str); - console.log("test", /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str)); return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str); } diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html index b5f77269b8..7f3e6f0b05 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/colorpicker.html @@ -10,9 +10,5 @@ use-label="model.config.useLabel"> - {{model.items | json}} -

- {{model.value}} -
From 299af13c4208f22651dd4352c493e30e348d096e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 30 Oct 2018 15:51:32 +0100 Subject: [PATCH 116/337] fixes the context menu node highlight bug --- .../components/tree/umbtreeitem.directive.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js index 93ea0d9ced..6d9ee31643 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js @@ -135,11 +135,19 @@ angular.module("umbraco.directives") } //is this the current action node (this is not the same as the current selected node!) - var actionNode = appState.getMenuState("currentNode"); + var actionNode = appState.getMenuState("currentNode"); if(actionNode) { - if(actionNode.id === node.id) { + + if(actionNode.id === node.id && actionNode.id !== "-1") { css.push("active"); - } + } + + // special handling of root nodes with id -1 + // as there can be many nodes with id -1 in a tree we need to check the treeAlias instead + if(actionNode.id === "-1" && actionNode.metaData.treeAlias === node.metaData.treeAlias) { + css.push("active"); + } + } return css.join(" "); From 115de5854e5a5e88000837ea72fc523daa7f895b Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Thu, 25 Oct 2018 19:22:56 +0200 Subject: [PATCH 117/337] Added new "CssClass" property to the "Tab" class --- src/Umbraco.Web/Models/ContentEditing/Tab.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/ContentEditing/Tab.cs b/src/Umbraco.Web/Models/ContentEditing/Tab.cs index dd1c73b418..bf276ec2b4 100644 --- a/src/Umbraco.Web/Models/ContentEditing/Tab.cs +++ b/src/Umbraco.Web/Models/ContentEditing/Tab.cs @@ -23,5 +23,8 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "properties")] public IEnumerable Properties { get; set; } + + [DataMember(Name = "cssClass")] + public string CssClass { get; set; } } -} \ No newline at end of file +} From 092d84a49d40bfc7557cb31d83bb2b4b04770811 Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Thu, 25 Oct 2018 19:25:00 +0200 Subject: [PATCH 118/337] Exposed the "cssClass " property in the view --- .../src/views/components/tabs/umb-tabs-nav.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html b/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html index 96c4adf783..8a823ee69c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/tabs/umb-tabs-nav.html @@ -1,5 +1,5 @@ From 1d87ceaacfa41acda0e93a6f7dfca6de9be3c19b Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Fri, 26 Oct 2018 19:22:50 +0200 Subject: [PATCH 119/337] Fix user email validation in IE and Edge by using ng-required instead of required on input type=email. --- .../src/views/users/views/user/details.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html index d0acec1522..1cd81f3d1c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html @@ -19,7 +19,7 @@ name="email" id="email" val-email - required + ng-required="true" val-server-field="Email" /> Required From 44b837a9ec69960405e978f0f01a9a0fe98d0c09 Mon Sep 17 00:00:00 2001 From: Dave Woestenborghs Date: Wed, 24 Oct 2018 16:35:43 +0200 Subject: [PATCH 120/337] #3373 fixes error when going to forms section when forms is not installed --- src/Umbraco.Web/Trees/ApplicationTreeController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Trees/ApplicationTreeController.cs b/src/Umbraco.Web/Trees/ApplicationTreeController.cs index be77cc67f9..31272363ae 100644 --- a/src/Umbraco.Web/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web/Trees/ApplicationTreeController.cs @@ -43,7 +43,7 @@ namespace Umbraco.Web.Trees //find all tree definitions that have the current application alias var appTrees = Services.ApplicationTreeService.GetApplicationTrees(application, onlyInitialized).ToArray(); - if (string.IsNullOrEmpty(tree) == false || appTrees.Length == 1 || appTrees.Any() == false) + if (string.IsNullOrEmpty(tree) == false || appTrees.Length == 1) { var apptree = string.IsNullOrEmpty(tree) == false ? appTrees.SingleOrDefault(x => x.Alias == tree) From a27cf7fb1be56befa7469e6eef936fe84080541c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 30 Oct 2018 20:56:10 +0100 Subject: [PATCH 121/337] dont collapse color in color picker prevalues --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 0a3807e7e6..678db3f798 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -152,6 +152,7 @@ div.umb-codeeditor .umb-btn-toolbar { border-radius: 3px; margin-top: auto; margin-bottom: auto; + flex: 0 0 auto; } .handle { From 6b0f393a6519c49cdbffb8d4909be763b39fd4c4 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 30 Oct 2018 21:02:24 +0100 Subject: [PATCH 122/337] use opacity instead of gray to set border color for color swatches so colors don't look blurry --- .../src/less/components/umb-color-swatches.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less index 26a735508e..b396ebf860 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less @@ -3,7 +3,7 @@ flex-flow: row wrap; .umb-color-box { - border: 1px solid @gray-8; + border: 1px solid rgba(0,0,0,0.15); color: @white; cursor: pointer; padding: 1px; From 72f3739430fee37fcc4db220633b2ec9b7fc8ce5 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 30 Oct 2018 21:15:29 +0100 Subject: [PATCH 123/337] add pointer to list view content templates dropdown --- .../src/views/propertyeditors/listview/listview.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html index cdd7e9cab2..a39228ef71 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html @@ -43,11 +43,11 @@