diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..edc68d462 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +src/js/polyfills.js \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..1fe2e17f2 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,114 @@ +{ + "rules": { + "no-empty": [ + 2, + { + "allowEmptyCatch": true + } + ], + "brace-style": [ + 2, + "1tbs", + { + "allowSingleLine": true + } + ], + "no-mixed-spaces-and-tabs": 2, + "no-multiple-empty-lines": 2, + "no-multi-str": 2, + "no-multi-spaces": 2, + "space-unary-ops": [ + 2, + { + "words": false, + "nonwords": false + } + ], + "key-spacing": [ + 2, + { + "beforeColon": false, + "afterColon": true + } + ], + "no-spaced-func": 2, + "space-before-function-paren": [ + 2, + "always" + ], + "array-bracket-spacing": [ + 2, + "never", + { + "objectsInArrays": false + } + ], + "space-in-parens": [ + 2, + "never" + ], + "comma-dangle": [ + 2, + "never" + ], + "no-trailing-spaces": 2, + "camelcase": [ + 2, + { + "properties": "never" + } + ], + "comma-style": [ + 2, + "last" + ], + "curly": [ + 2, + "all" + ], + "one-var": [ + 2, + "consecutive" + ], + "operator-linebreak": [ + 2, + "after" + ], + "semi": [ + 2, + "always" + ], + "space-infix-ops": 2, + "keyword-spacing": [ + 2, + { + "overrides": { + "else": { + "before": true + }, + "while": { + "before": true + }, + "catch": { + "before": true + } + } + } + ], + "space-before-blocks": [ + 2, + "always" + ], + "indent": [ + 2, + 4, + { + "SwitchCase": 1 + } + ], + "quotes": [ + 2, + "single" + ] + } +} diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index d2a8313e3..000000000 --- a/.jscsrc +++ /dev/null @@ -1,134 +0,0 @@ -{ - "disallowEmptyBlocks": true, - "disallowKeywordsOnNewLine": [ - "else" - ], - "disallowMixedSpacesAndTabs": true, - "disallowMultipleLineBreaks": true, - "disallowMultipleLineStrings": true, - "disallowMultipleSpaces": true, - "disallowNewlineBeforeBlockStatements": true, - "disallowSpaceAfterPrefixUnaryOperators": [ - "++", - "--", - "+", - "-", - "~", - "!" - ], - "disallowSpaceAfterObjectKeys": true, - "disallowSpaceBeforePostfixUnaryOperators": [ - "++", - "--" - ], - "disallowSpacesInCallExpression": true, - "disallowSpacesInFunctionDeclaration": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInsideArrayBrackets": true, - "disallowSpacesInsideBrackets": true, - "disallowSpacesInsideParentheses": true, - "disallowTrailingComma": true, - "disallowTrailingWhitespace": true, - "requireBlocksOnNewline": true, - "requireCamelCaseOrUpperCaseIdentifiers": true, - "requireCapitalizedConstructors": true, - "requireCommaBeforeLineBreak": true, - "requireCurlyBraces": [ - "if", - "else", - "for", - "while", - "do", - "try", - "catch" - ], - "requireLineBreakAfterVariableAssignment": true, - "requireMultipleVarDecl": true, - "requireOperatorBeforeLineBreak": [ - "?", - "=", - "+", - "-", - "/", - "*", - "==", - "===", - "!=", - "!==", - ">", - ">=", - "<", - "<=" - ], - "requireSemicolons": true, - "requireSpaceAfterBinaryOperators": [ - "=", - ",", - "+", - "-", - "/", - "*", - "==", - "===", - "!=", - "!==" - ], - "requireSpaceAfterKeywords": [ - "do", - "for", - "if", - "else", - "switch", - "case", - "try", - "catch", - "void", - "while", - "with", - "return", - "typeof", - "function" - ], - "requireSpaceBeforeBinaryOperators": [ - "=", - "+", - "-", - "/", - "*", - "==", - "===", - "!=", - "!==" - ], - "requireSpaceBeforeBlockStatements": true, - "requireSpaceBeforeKeywords": [ - "else", - "while", - "catch" - ], - "requireSpaceBetweenArguments": true, - "requireSpacesInAnonymousFunctionExpression": { - "beforeOpeningRoundBrace": true, - "beforeOpeningCurlyBrace": true - }, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInForStatement": true, - "requireSpacesInFunctionDeclaration": { - "beforeOpeningCurlyBrace": true - }, - "requireSpacesInFunction": { - "beforeOpeningCurlyBrace": true - }, - "requireSpacesInsideObjectBrackets": { - "allExcept": [ "}", ")" ] - }, - "validateIndentation": 4, - "validateParameterSeparator": ", ", - "validateQuoteMarks": "'" -} diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 000000000..21504fcd6 --- /dev/null +++ b/.jshintignore @@ -0,0 +1,5 @@ +demo/ +dist/ +spec/vendor/*.js +src/js/polyfills.js +index.js \ No newline at end of file diff --git a/.jshintrc b/.jshintrc index 09b469916..0de71e5b5 100644 --- a/.jshintrc +++ b/.jshintrc @@ -14,5 +14,6 @@ "sub": true, "undef": true, "unused": true, - "validthis": true + "validthis": true, + "esversion": 6 } diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 000000000..f97c1549c --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,4 @@ +{ + "rules": { + } +} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3edcf551..cbb685de6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,9 +20,9 @@ To help create consistent looking code throughout the project, we use a few tool We use [JSHint](http://jshint.com/) on each build to find easy-to-catch errors and potential problems in our js. You can find our JSHint settings in the `.jshintrc` file in the root of the project. -#### jscs +#### ESLint -We use [jscs](http://jscs.info/) on each build to enforce some code style rules we have for our project. You can find our jscs settings in the `.jscsrc` file in the root of the project. +We use [ESLint](https://eslint.org/) on each build to enforce some code style rules we have for our project. You can find our ESLint settings in the `.eslintrc` file in the root of the project. #### EditorConfig @@ -48,8 +48,8 @@ grunt These are the other available grunt tasks: * __js__: runs jslint and jasmine tests and creates minified and concatenated versions of the script; -* __css__: runs autoprefixer and csslint -* __test__: runs jasmine tests, jslint and csslint +* __css__: runs autoprefixer and stylelint +* __test__: runs jasmine tests, jslint and stylelint * __watch__: watch for modifications on script/scss files * __spec__: runs a task against a specified file diff --git a/Gruntfile.js b/Gruntfile.js index 8544542de..8045c7de8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -93,7 +93,6 @@ module.exports = function (grunt) { // TODO: build check with debug and devel false gruntConfig.jshint = { options: { - ignores: ['src/js/polyfills.js'], jshintrc: true, reporter: require('jshint-stylish') }, @@ -106,16 +105,14 @@ module.exports = function (grunt) { } }; - // TODO: "maximumLineLength": 120 - gruntConfig.jscs = { + gruntConfig.eslint = { src: [ 'src/js/**/*.js', 'spec/*.spec.js', - 'Gruntfile.js', - '!src/js/polyfills.js' + 'Gruntfile.js' ], options: { - config: '.jscsrc' + config: '.eslintrc' } }; @@ -126,7 +123,7 @@ module.exports = function (grunt) { specs: ['spec/*.spec.js'], helpers: 'spec/helpers/*.js', vendor: [ - 'node_modules/lodash/index.js', + 'node_modules/lodash/lodash.js', 'spec/vendor/jasmine-jsreporter.js', 'spec/vendor/jasmine-jsreporter-script.js' ], @@ -172,20 +169,10 @@ module.exports = function (grunt) { } }; - gruntConfig.csslint = { - strict: { - options: { - 'box-sizing': false, - 'compatible-vendor-prefixes': false, - 'fallback-colors': false, - 'gradients': false, - 'important': false, - 'import': 2, - 'outline-none': false, - 'adjoining-classes': false - }, - src: 'dist/css/**/*.css' - } + gruntConfig.stylelint = { + all: [ + 'dist/css/**/*.css' + ] }; gruntConfig.sass = { @@ -333,16 +320,16 @@ module.exports = function (grunt) { }); if (parseInt(process.env.TRAVIS_PULL_REQUEST, 10) > 0) { - grunt.registerTask('travis', ['jshint', 'jscs', 'jasmine:suite', 'csslint', 'coveralls']); + grunt.registerTask('travis', ['jshint', 'eslint', 'jasmine:suite', 'stylelint', 'coveralls']); } else { - grunt.registerTask('travis', ['connect', 'jshint', 'jscs', 'jasmine:suite', 'csslint', 'saucelabs-jasmine', 'coveralls']); + grunt.registerTask('travis', ['connect', 'jshint', 'eslint', 'jasmine:suite', 'stylelint', 'saucelabs-jasmine', 'coveralls']); } - grunt.registerTask('test', ['jshint', 'jscs', 'concat', 'jasmine:suite', 'csslint']); + grunt.registerTask('test', ['jshint', 'eslint', 'concat', 'jasmine:suite', 'stylelint']); grunt.registerTask('sauce', ['connect', 'saucelabs-jasmine']); - grunt.registerTask('js', ['jshint', 'jscs', 'concat', 'jasmine:suite', 'uglify']); - grunt.registerTask('css', ['sass', 'autoprefixer', 'cssmin', 'csslint']); - grunt.registerTask('default', ['js', 'css']); + grunt.registerTask('js', ['jshint', 'eslint', 'concat', 'jasmine:suite', 'uglify']); + grunt.registerTask('css', ['sass', 'autoprefixer', 'cssmin', 'stylelint']); + grunt.registerTask('default', ['css', 'js']); grunt.registerTask('spec', 'Runs a task on a specified file', function (taskName, fileName) { globalConfig.file = fileName; diff --git a/OPTIONS.md b/OPTIONS.md index 9739e1b52..1e752672b 100644 --- a/OPTIONS.md +++ b/OPTIONS.md @@ -333,7 +333,6 @@ var editor = new MediumEditor('.editable', { hideDelay: 500, previewValueSelector: 'a' } -} }); ``` @@ -435,7 +434,6 @@ var editor = new MediumEditor('.editable', { targetCheckbox: false, targetCheckboxText: 'Open in new window' } -} }); ``` diff --git a/README.md b/README.md index 0db7945e1..1ac5fb6d3 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,6 @@ var editor = new MediumEditor('.editable', { hideDelay: 500, previewValueSelector: 'a' } -} }); ``` @@ -320,7 +319,6 @@ var editor = new MediumEditor('.editable', { targetCheckbox: false, targetCheckboxText: 'Open in new window' } -} }); ``` @@ -677,8 +675,8 @@ grunt These are the other available grunt tasks: * __js__: runs jslint and jasmine tests and creates minified and concatenated versions of the script; -* __css__: runs autoprefixer and csslint -* __test__: runs jasmine tests, jslint and csslint +* __css__: runs autoprefixer and stylelint +* __test__: runs jasmine tests, jslint and stylelint * __watch__: watch for modifications on script/scss files * __spec__: runs a task against a specified file @@ -704,9 +702,9 @@ To help create consistent looking code throughout the project, we use a few tool We use [JSHint](http://jshint.com/) on each build to find easy-to-catch errors and potential problems in our js. You can find our JSHint settings in the `.jshintrc` file in the root of the project. -#### jscs +#### ESLint -We use [jscs](http://jscs.info/) on each build to enforce some code style rules we have for our project. You can find our jscs settings in the `.jscsrc` file in the root of the project. +We use [ESLint](https://eslint.org/) on each build to enforce some code style rules we have for our project. You can find our ESLint settings in the `.eslintrc` file in the root of the project. #### EditorConfig diff --git a/dist/css/medium-editor.css b/dist/css/medium-editor.css index de9813251..a1c058acf 100644 --- a/dist/css/medium-editor.css +++ b/dist/css/medium-editor.css @@ -1,52 +1,21 @@ -@-webkit-keyframes medium-editor-image-loading { - 0% { - -webkit-transform: scale(0); - transform: scale(0); } - 100% { - -webkit-transform: scale(1); - transform: scale(1); } } - @keyframes medium-editor-image-loading { 0% { - -webkit-transform: scale(0); - transform: scale(0); } - 100% { - -webkit-transform: scale(1); - transform: scale(1); } } - -@-webkit-keyframes medium-editor-pop-upwards { - 0% { - opacity: 0; - -webkit-transform: matrix(0.97, 0, 0, 1, 0, 12); - transform: matrix(0.97, 0, 0, 1, 0, 12); } - 20% { - opacity: .7; - -webkit-transform: matrix(0.99, 0, 0, 1, 0, 2); - transform: matrix(0.99, 0, 0, 1, 0, 2); } - 40% { - opacity: 1; - -webkit-transform: matrix(1, 0, 0, 1, 0, -1); - transform: matrix(1, 0, 0, 1, 0, -1); } + transform: scale(0); } 100% { - -webkit-transform: matrix(1, 0, 0, 1, 0, 0); - transform: matrix(1, 0, 0, 1, 0, 0); } } + transform: scale(1); } } @keyframes medium-editor-pop-upwards { 0% { opacity: 0; - -webkit-transform: matrix(0.97, 0, 0, 1, 0, 12); - transform: matrix(0.97, 0, 0, 1, 0, 12); } + transform: matrix(0.97, 0, 0, 1, 0, 12); } 20% { opacity: .7; - -webkit-transform: matrix(0.99, 0, 0, 1, 0, 2); - transform: matrix(0.99, 0, 0, 1, 0, 2); } + transform: matrix(0.99, 0, 0, 1, 0, 2); } 40% { opacity: 1; - -webkit-transform: matrix(1, 0, 0, 1, 0, -1); - transform: matrix(1, 0, 0, 1, 0, -1); } + transform: matrix(1, 0, 0, 1, 0, -1); } 100% { - -webkit-transform: matrix(1, 0, 0, 1, 0, 0); - transform: matrix(1, 0, 0, 1, 0, 0); } } + transform: matrix(1, 0, 0, 1, 0, 0); } } .medium-editor-anchor-preview { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; @@ -57,9 +26,9 @@ position: absolute; text-align: center; top: 0; + visibility: hidden; word-break: break-all; word-wrap: break-word; - visibility: hidden; z-index: 2000; } .medium-editor-anchor-preview a { color: #fff; @@ -73,8 +42,7 @@ background: #ddd; } .medium-editor-image-loading { - -webkit-animation: medium-editor-image-loading 1s infinite ease-in-out; - animation: medium-editor-image-loading 1s infinite ease-in-out; + animation: medium-editor-image-loading 1s infinite ease-in-out; background-color: #333; border-radius: 100%; display: inline-block; @@ -86,22 +54,22 @@ .medium-editor-placeholder:after { content: attr(data-placeholder) !important; font-style: italic; - position: absolute; left: 0; - top: 0; - white-space: pre; + margin: inherit; padding: inherit; - margin: inherit; } + position: absolute; + top: 0; + white-space: pre; } .medium-editor-placeholder-relative { position: relative; } .medium-editor-placeholder-relative:after { content: attr(data-placeholder) !important; font-style: italic; - position: relative; - white-space: pre; + margin: inherit; padding: inherit; - margin: inherit; } + position: relative; + white-space: pre; } .medium-toolbar-arrow-under:after, .medium-toolbar-arrow-over:before { border-style: solid; @@ -166,8 +134,7 @@ position: relative; } .medium-editor-toolbar-active.medium-editor-stalker-toolbar { - -webkit-animation: medium-editor-pop-upwards 160ms forwards linear; - animation: medium-editor-pop-upwards 160ms forwards linear; } + animation: medium-editor-pop-upwards 160ms forwards linear; } .medium-editor-action-bold { font-weight: bolder; } @@ -188,11 +155,11 @@ .medium-editor-toolbar-form label { border: none; box-sizing: border-box; + display: inline-block; font-size: 14px; margin: 0; padding: 6px; - width: 316px; - display: inline-block; } + width: 316px; } .medium-editor-toolbar-form .medium-editor-toolbar-input:focus, .medium-editor-toolbar-form label:focus { -webkit-appearance: none; @@ -217,8 +184,8 @@ display: table; } .medium-editor-element { - word-wrap: break-word; - min-height: 30px; } + min-height: 30px; + word-wrap: break-word; } .medium-editor-element img { max-width: 100%; } .medium-editor-element sub { diff --git a/dist/css/medium-editor.min.css b/dist/css/medium-editor.min.css index e46f81c02..697afe214 100644 --- a/dist/css/medium-editor.min.css +++ b/dist/css/medium-editor.min.css @@ -1 +1 @@ -.medium-editor-anchor-preview,.medium-editor-toolbar{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;z-index:2000}@-webkit-keyframes medium-editor-image-loading{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes medium-editor-image-loading{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes medium-editor-pop-upwards{0%{opacity:0;-webkit-transform:matrix(.97,0,0,1,0,12);transform:matrix(.97,0,0,1,0,12)}20%{opacity:.7;-webkit-transform:matrix(.99,0,0,1,0,2);transform:matrix(.99,0,0,1,0,2)}40%{opacity:1;-webkit-transform:matrix(1,0,0,1,0,-1);transform:matrix(1,0,0,1,0,-1)}100%{-webkit-transform:matrix(1,0,0,1,0,0);transform:matrix(1,0,0,1,0,0)}}@keyframes medium-editor-pop-upwards{0%{opacity:0;-webkit-transform:matrix(.97,0,0,1,0,12);transform:matrix(.97,0,0,1,0,12)}20%{opacity:.7;-webkit-transform:matrix(.99,0,0,1,0,2);transform:matrix(.99,0,0,1,0,2)}40%{opacity:1;-webkit-transform:matrix(1,0,0,1,0,-1);transform:matrix(1,0,0,1,0,-1)}100%{-webkit-transform:matrix(1,0,0,1,0,0);transform:matrix(1,0,0,1,0,0)}}.medium-editor-anchor-preview{left:0;line-height:1.4;max-width:280px;position:absolute;text-align:center;top:0;word-break:break-all;word-wrap:break-word;visibility:hidden}.medium-editor-anchor-preview a{color:#fff;display:inline-block;margin:5px 5px 10px}.medium-editor-placeholder-relative:after,.medium-editor-placeholder:after{content:attr(data-placeholder)!important;white-space:pre;padding:inherit;margin:inherit;font-style:italic}.medium-editor-anchor-preview-active{visibility:visible}.medium-editor-dragover{background:#ddd}.medium-editor-image-loading{-webkit-animation:medium-editor-image-loading 1s infinite ease-in-out;animation:medium-editor-image-loading 1s infinite ease-in-out;background-color:#333;border-radius:100%;display:inline-block;height:40px;width:40px}.medium-editor-placeholder{position:relative}.medium-editor-placeholder:after{position:absolute;left:0;top:0}.medium-editor-placeholder-relative,.medium-editor-placeholder-relative:after{position:relative}.medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{border-style:solid;content:'';display:block;height:0;left:50%;margin-left:-8px;position:absolute;width:0}.medium-toolbar-arrow-under:after{border-width:8px 8px 0}.medium-toolbar-arrow-over:before{border-width:0 8px 8px;top:-8px}.medium-editor-toolbar{left:0;position:absolute;top:0;visibility:hidden}.medium-editor-toolbar ul{margin:0;padding:0}.medium-editor-toolbar li{float:left;list-style:none;margin:0;padding:0}.medium-editor-toolbar li button{box-sizing:border-box;cursor:pointer;display:block;font-size:14px;line-height:1.33;margin:0;padding:15px;text-decoration:none}.medium-editor-toolbar li button:focus{outline:0}.medium-editor-toolbar li .medium-editor-action-underline{text-decoration:underline}.medium-editor-toolbar li .medium-editor-action-pre{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;font-weight:100;padding:15px 0}.medium-editor-toolbar-active{visibility:visible}.medium-editor-sticky-toolbar{position:fixed;top:1px}.medium-editor-relative-toolbar{position:relative}.medium-editor-toolbar-active.medium-editor-stalker-toolbar{-webkit-animation:medium-editor-pop-upwards 160ms forwards linear;animation:medium-editor-pop-upwards 160ms forwards linear}.medium-editor-action-bold{font-weight:bolder}.medium-editor-action-italic{font-style:italic}.medium-editor-toolbar-form{display:none}.medium-editor-toolbar-form a,.medium-editor-toolbar-form input{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.medium-editor-toolbar-form .medium-editor-toolbar-form-row{line-height:14px;margin-left:5px;padding-bottom:5px}.medium-editor-toolbar-form .medium-editor-toolbar-input,.medium-editor-toolbar-form label{border:none;box-sizing:border-box;font-size:14px;margin:0;padding:6px;width:316px;display:inline-block}.medium-editor-toolbar-form .medium-editor-toolbar-input:focus,.medium-editor-toolbar-form label:focus{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;box-shadow:none;outline:0}.medium-editor-toolbar-form a{display:inline-block;font-size:24px;font-weight:bolder;margin:0 10px;text-decoration:none}.medium-editor-toolbar-form-active{display:block}.medium-editor-toolbar-actions:after{clear:both;content:"";display:table}.medium-editor-element{word-wrap:break-word;min-height:30px}.medium-editor-element img{max-width:100%}.medium-editor-element sub{vertical-align:sub}.medium-editor-element sup{vertical-align:super}.medium-editor-hidden{display:none} \ No newline at end of file +@keyframes medium-editor-image-loading{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes medium-editor-pop-upwards{0%{opacity:0;transform:matrix(.97,0,0,1,0,12)}20%{opacity:.7;transform:matrix(.99,0,0,1,0,2)}40%{opacity:1;transform:matrix(1,0,0,1,0,-1)}100%{transform:matrix(1,0,0,1,0,0)}}.medium-editor-anchor-preview{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;left:0;line-height:1.4;max-width:280px;position:absolute;text-align:center;top:0;visibility:hidden;word-break:break-all;word-wrap:break-word;z-index:2000}.medium-editor-anchor-preview a{color:#fff;display:inline-block;margin:5px 5px 10px}.medium-editor-anchor-preview-active{visibility:visible}.medium-editor-dragover{background:#ddd}.medium-editor-image-loading{animation:medium-editor-image-loading 1s infinite ease-in-out;background-color:#333;border-radius:100%;display:inline-block;height:40px;width:40px}.medium-editor-placeholder{position:relative}.medium-editor-placeholder:after{content:attr(data-placeholder)!important;font-style:italic;left:0;margin:inherit;padding:inherit;position:absolute;top:0;white-space:pre}.medium-editor-placeholder-relative{position:relative}.medium-editor-placeholder-relative:after{content:attr(data-placeholder)!important;font-style:italic;margin:inherit;padding:inherit;position:relative;white-space:pre}.medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{border-style:solid;content:'';display:block;height:0;left:50%;margin-left:-8px;position:absolute;width:0}.medium-toolbar-arrow-under:after{border-width:8px 8px 0 8px}.medium-toolbar-arrow-over:before{border-width:0 8px 8px 8px;top:-8px}.medium-editor-toolbar{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;left:0;position:absolute;top:0;visibility:hidden;z-index:2000}.medium-editor-toolbar ul{margin:0;padding:0}.medium-editor-toolbar li{float:left;list-style:none;margin:0;padding:0}.medium-editor-toolbar li button{box-sizing:border-box;cursor:pointer;display:block;font-size:14px;line-height:1.33;margin:0;padding:15px;text-decoration:none}.medium-editor-toolbar li button:focus{outline:0}.medium-editor-toolbar li .medium-editor-action-underline{text-decoration:underline}.medium-editor-toolbar li .medium-editor-action-pre{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;font-weight:100;padding:15px 0}.medium-editor-toolbar-active{visibility:visible}.medium-editor-sticky-toolbar{position:fixed;top:1px}.medium-editor-relative-toolbar{position:relative}.medium-editor-toolbar-active.medium-editor-stalker-toolbar{animation:medium-editor-pop-upwards 160ms forwards linear}.medium-editor-action-bold{font-weight:bolder}.medium-editor-action-italic{font-style:italic}.medium-editor-toolbar-form{display:none}.medium-editor-toolbar-form a,.medium-editor-toolbar-form input{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.medium-editor-toolbar-form .medium-editor-toolbar-form-row{line-height:14px;margin-left:5px;padding-bottom:5px}.medium-editor-toolbar-form .medium-editor-toolbar-input,.medium-editor-toolbar-form label{border:none;box-sizing:border-box;display:inline-block;font-size:14px;margin:0;padding:6px;width:316px}.medium-editor-toolbar-form .medium-editor-toolbar-input:focus,.medium-editor-toolbar-form label:focus{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;box-shadow:none;outline:0}.medium-editor-toolbar-form a{display:inline-block;font-size:24px;font-weight:bolder;margin:0 10px;text-decoration:none}.medium-editor-toolbar-form-active{display:block}.medium-editor-toolbar-actions:after{clear:both;content:"";display:table}.medium-editor-element{min-height:30px;word-wrap:break-word}.medium-editor-element img{max-width:100%}.medium-editor-element sub{vertical-align:sub}.medium-editor-element sup{vertical-align:super}.medium-editor-hidden{display:none} \ No newline at end of file diff --git a/dist/css/themes/beagle.css b/dist/css/themes/beagle.css index edab17ee9..1135bf85c 100644 --- a/dist/css/themes/beagle.css +++ b/dist/css/themes/beagle.css @@ -17,8 +17,7 @@ height: 40px; min-width: 40px; padding: 5px 12px; - -webkit-transition: background-color .2s ease-in, color .2s ease-in; - transition: background-color .2s ease-in, color .2s ease-in; } + transition: background-color .2s ease-in, color .2s ease-in; } .medium-editor-toolbar li button:hover { background-color: #000; color: #a2d7c7; } @@ -63,8 +62,7 @@ color: rgba(248, 245, 243, 0.8); } .medium-editor-toolbar-form a { color: #ccc; - -webkit-transform: translateY(2px); - transform: translateY(2px); } + transform: translateY(2px); } .medium-editor-toolbar-form .medium-editor-toolbar-close { margin-right: 16px; } diff --git a/dist/css/themes/beagle.min.css b/dist/css/themes/beagle.min.css index 5afbb9743..86489ff7f 100644 --- a/dist/css/themes/beagle.min.css +++ b/dist/css/themes/beagle.min.css @@ -1 +1 @@ -.medium-toolbar-arrow-under:after{border-color:#000 transparent transparent;top:40px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #000}.medium-editor-toolbar{background-color:#000;border:none;border-radius:50px}.medium-editor-toolbar li button{background-color:transparent;border:none;box-sizing:border-box;color:#ccc;height:40px;min-width:40px;padding:5px 12px;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li .medium-editor-button-active,.medium-editor-toolbar li button:hover{background-color:#000;color:#a2d7c7}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:50px;border-top-left-radius:50px;padding-left:24px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:50px;border-right:none;border-top-right-radius:50px;padding-right:24px}.medium-editor-toolbar-form{background:#000;border-radius:50px;color:#ccc;overflow:hidden}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#000;box-sizing:border-box;color:#ccc;height:40px;padding-left:16px;width:220px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form a{color:#ccc;-webkit-transform:translateY(2px);transform:translateY(2px)}.medium-editor-toolbar-form .medium-editor-toolbar-close{margin-right:16px}.medium-editor-toolbar-anchor-preview{background:#000;border-radius:50px;padding:5px 12px}.medium-editor-anchor-preview a{color:#ccc;text-decoration:none}.medium-editor-toolbar-actions button,.medium-editor-toolbar-actions li{border-radius:50px} \ No newline at end of file +.medium-toolbar-arrow-under:after{border-color:#000 transparent transparent transparent;top:40px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #000 transparent}.medium-editor-toolbar{background-color:#000;border:none;border-radius:50px}.medium-editor-toolbar li button{background-color:transparent;border:none;box-sizing:border-box;color:#ccc;height:40px;min-width:40px;padding:5px 12px;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#000;color:#a2d7c7}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:50px;border-top-left-radius:50px;padding-left:24px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:50px;border-right:none;border-top-right-radius:50px;padding-right:24px}.medium-editor-toolbar li .medium-editor-button-active{background-color:#000;color:#a2d7c7}.medium-editor-toolbar-form{background:#000;border-radius:50px;color:#ccc;overflow:hidden}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#000;box-sizing:border-box;color:#ccc;height:40px;padding-left:16px;width:220px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#f8f5f3;color:rgba(248,245,243,.8)}.medium-editor-toolbar-form a{color:#ccc;transform:translateY(2px)}.medium-editor-toolbar-form .medium-editor-toolbar-close{margin-right:16px}.medium-editor-toolbar-anchor-preview{background:#000;border-radius:50px;padding:5px 12px}.medium-editor-anchor-preview a{color:#ccc;text-decoration:none}.medium-editor-toolbar-actions button,.medium-editor-toolbar-actions li{border-radius:50px} \ No newline at end of file diff --git a/dist/css/themes/bootstrap.css b/dist/css/themes/bootstrap.css index a1f4ef28a..929f1faaa 100644 --- a/dist/css/themes/bootstrap.css +++ b/dist/css/themes/bootstrap.css @@ -17,8 +17,7 @@ color: #fff; height: 60px; min-width: 60px; - -webkit-transition: background-color .2s ease-in, color .2s ease-in; - transition: background-color .2s ease-in, color .2s ease-in; } + transition: background-color .2s ease-in, color .2s ease-in; } .medium-editor-toolbar li button:hover { background-color: #3276b1; color: #fff; } diff --git a/dist/css/themes/bootstrap.min.css b/dist/css/themes/bootstrap.min.css index 4063c7505..f36daf480 100644 --- a/dist/css/themes/bootstrap.min.css +++ b/dist/css/themes/bootstrap.min.css @@ -1 +1 @@ -.medium-toolbar-arrow-under:after{border-color:#428bca transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #428bca}.medium-editor-toolbar{background-color:#428bca;border:1px solid #357ebd;border-radius:4px}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #357ebd;box-sizing:border-box;color:#fff;height:60px;min-width:60px;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li .medium-editor-button-active,.medium-editor-toolbar li button:hover{background-color:#3276b1;color:#fff}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:4px;border-top-left-radius:4px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:4px;border-right:none;border-top-right-radius:4px}.medium-editor-toolbar-form{background:#428bca;border-radius:4px;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#428bca;color:#fff;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#428bca;border-radius:4px;color:#fff}.medium-editor-placeholder:after{color:#357ebd} \ No newline at end of file +.medium-toolbar-arrow-under:after{border-color:#428bca transparent transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #428bca transparent}.medium-editor-toolbar{background-color:#428bca;border:1px solid #357ebd;border-radius:4px}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #357ebd;box-sizing:border-box;color:#fff;height:60px;min-width:60px;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#3276b1;color:#fff}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:4px;border-top-left-radius:4px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:4px;border-right:none;border-top-right-radius:4px}.medium-editor-toolbar li .medium-editor-button-active{background-color:#3276b1;color:#fff}.medium-editor-toolbar-form{background:#428bca;border-radius:4px;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#428bca;color:#fff;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#428bca;border-radius:4px;color:#fff}.medium-editor-placeholder:after{color:#357ebd} \ No newline at end of file diff --git a/dist/css/themes/default.css b/dist/css/themes/default.css index 02668c6b9..a30157655 100644 --- a/dist/css/themes/default.css +++ b/dist/css/themes/default.css @@ -7,26 +7,23 @@ top: -8px; } .medium-editor-toolbar { - background-color: #242424; - background: -webkit-linear-gradient(top, #242424, rgba(36, 36, 36, 0.75)); background: linear-gradient(to bottom, #242424, rgba(36, 36, 36, 0.75)); + background-color: #242424; border: 1px solid #000; border-radius: 5px; box-shadow: 0 0 3px #000; } .medium-editor-toolbar li button { - background-color: #242424; - background: -webkit-linear-gradient(top, #242424, rgba(36, 36, 36, 0.89)); background: linear-gradient(to bottom, #242424, rgba(36, 36, 36, 0.89)); + background-color: #242424; border: 0; - border-right: 1px solid #000; border-left: 1px solid #333; border-left: 1px solid rgba(255, 255, 255, 0.1); + border-right: 1px solid #000; box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3); color: #fff; height: 50px; min-width: 50px; - -webkit-transition: background-color .2s ease-in; - transition: background-color .2s ease-in; } + transition: background-color .2s ease-in; } .medium-editor-toolbar li button:hover { background-color: #000; color: yellow; } @@ -37,9 +34,8 @@ border-bottom-right-radius: 5px; border-top-right-radius: 5px; } .medium-editor-toolbar li .medium-editor-button-active { - background-color: #000; - background: -webkit-linear-gradient(top, #242424, rgba(0, 0, 0, 0.89)); background: linear-gradient(to bottom, #242424, rgba(0, 0, 0, 0.89)); + background-color: #000; color: #fff; } .medium-editor-toolbar-form { diff --git a/dist/css/themes/default.min.css b/dist/css/themes/default.min.css index ac5847843..bad2e21bd 100644 --- a/dist/css/themes/default.min.css +++ b/dist/css/themes/default.min.css @@ -1 +1 @@ -.medium-toolbar-arrow-under:after{border-color:#242424 transparent transparent;top:50px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #242424;top:-8px}.medium-editor-toolbar{background-color:#242424;background:-webkit-linear-gradient(top,#242424,rgba(36,36,36,.75));background:linear-gradient(to bottom,#242424,rgba(36,36,36,.75));border:1px solid #000;border-radius:5px;box-shadow:0 0 3px #000}.medium-editor-toolbar li button{background-color:#242424;background:-webkit-linear-gradient(top,#242424,rgba(36,36,36,.89));background:linear-gradient(to bottom,#242424,rgba(36,36,36,.89));border:0;border-right:1px solid #000;border-left:1px solid #333;border-left:1px solid rgba(255,255,255,.1);box-shadow:0 2px 2px rgba(0,0,0,.3);color:#fff;height:50px;min-width:50px;-webkit-transition:background-color .2s ease-in;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#000;color:#ff0}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:5px;border-top-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:5px;border-top-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{background-color:#000;background:-webkit-linear-gradient(top,#242424,rgba(0,0,0,.89));background:linear-gradient(to bottom,#242424,rgba(0,0,0,.89));color:#fff}.medium-editor-toolbar-form{background:#242424;border-radius:5px;color:#999}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#242424;box-sizing:border-box;color:#ccc;height:50px}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#242424;border-radius:5px;color:#fff}.medium-editor-placeholder:after{color:#b3b3b1} \ No newline at end of file +.medium-toolbar-arrow-under:after{border-color:#242424 transparent transparent transparent;top:50px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #242424 transparent;top:-8px}.medium-editor-toolbar{background:linear-gradient(to bottom,#242424,rgba(36,36,36,.75));background-color:#242424;border:1px solid #000;border-radius:5px;box-shadow:0 0 3px #000}.medium-editor-toolbar li button{background:linear-gradient(to bottom,#242424,rgba(36,36,36,.89));background-color:#242424;border:0;border-left:1px solid #333;border-left:1px solid rgba(255,255,255,.1);border-right:1px solid #000;box-shadow:0 2px 2px rgba(0,0,0,.3);color:#fff;height:50px;min-width:50px;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#000;color:#ff0}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:5px;border-top-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:5px;border-top-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{background:linear-gradient(to bottom,#242424,rgba(0,0,0,.89));background-color:#000;color:#fff}.medium-editor-toolbar-form{background:#242424;border-radius:5px;color:#999}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#242424;box-sizing:border-box;color:#ccc;height:50px}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#242424;border-radius:5px;color:#fff}.medium-editor-placeholder:after{color:#b3b3b1} \ No newline at end of file diff --git a/dist/css/themes/flat.css b/dist/css/themes/flat.css index ae809d489..fdd608133 100644 --- a/dist/css/themes/flat.css +++ b/dist/css/themes/flat.css @@ -1,24 +1,23 @@ .medium-toolbar-arrow-under:after { - top: 60px; - border-color: #57ad68 transparent transparent transparent; } + border-color: #57ad68 transparent transparent transparent; + top: 60px; } .medium-toolbar-arrow-over:before { - top: -8px; - border-color: transparent transparent #57ad68 transparent; } + border-color: transparent transparent #57ad68 transparent; + top: -8px; } .medium-editor-toolbar { background-color: #57ad68; } .medium-editor-toolbar li { padding: 0; } .medium-editor-toolbar li button { - min-width: 60px; - height: 60px; + background-color: transparent; border: none; border-right: 1px solid #9ccea6; - background-color: transparent; color: #fff; - -webkit-transition: background-color .2s ease-in, color .2s ease-in; - transition: background-color .2s ease-in, color .2s ease-in; } + height: 60px; + min-width: 60px; + transition: background-color .2s ease-in, color .2s ease-in; } .medium-editor-toolbar li button:hover { background-color: #346a3f; color: #fff; } @@ -29,9 +28,9 @@ border-right: none; } .medium-editor-toolbar-form .medium-editor-toolbar-input { - height: 60px; background: #57ad68; - color: #fff; } + color: #fff; + height: 60px; } .medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder { color: #fff; color: rgba(255, 255, 255, 0.8); } diff --git a/dist/css/themes/flat.min.css b/dist/css/themes/flat.min.css index b97ec7d97..ccfeb5da3 100644 --- a/dist/css/themes/flat.min.css +++ b/dist/css/themes/flat.min.css @@ -1 +1 @@ -.medium-toolbar-arrow-under:after{top:60px;border-color:#57ad68 transparent transparent}.medium-toolbar-arrow-over:before{top:-8px;border-color:transparent transparent #57ad68}.medium-editor-toolbar{background-color:#57ad68}.medium-editor-toolbar li{padding:0}.medium-editor-toolbar li button{min-width:60px;height:60px;border:none;border-right:1px solid #9ccea6;background-color:transparent;color:#fff;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#346a3f;color:#fff}.medium-editor-toolbar li .medium-editor-button-active{background-color:#23482a;color:#fff}.medium-editor-toolbar li .medium-editor-button-last{border-right:none}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:60px;background:#57ad68;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#57ad68;color:#fff}.medium-editor-placeholder:after{color:#9ccea6} \ No newline at end of file +.medium-toolbar-arrow-under:after{border-color:#57ad68 transparent transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #57ad68 transparent;top:-8px}.medium-editor-toolbar{background-color:#57ad68}.medium-editor-toolbar li{padding:0}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #9ccea6;color:#fff;height:60px;min-width:60px;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#346a3f;color:#fff}.medium-editor-toolbar li .medium-editor-button-active{background-color:#23482a;color:#fff}.medium-editor-toolbar li .medium-editor-button-last{border-right:none}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#57ad68;color:#fff;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#57ad68;color:#fff}.medium-editor-placeholder:after{color:#9ccea6} \ No newline at end of file diff --git a/dist/css/themes/mani.css b/dist/css/themes/mani.css index 1b1567de8..498db2ab1 100644 --- a/dist/css/themes/mani.css +++ b/dist/css/themes/mani.css @@ -3,55 +3,52 @@ display: none; } .medium-editor-toolbar { - border: 1px solid #cdd6e0; + background: linear-gradient(to top, #dee7f0, white); background-color: #dee7f0; background-color: rgba(222, 231, 240, 0.95); - background: -webkit-linear-gradient(bottom, #dee7f0, white); - background: linear-gradient(to top, #dee7f0, white); + border: 1px solid #cdd6e0; border-radius: 2px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); } .medium-editor-toolbar li button { - min-width: 50px; - height: 50px; + background-color: transparent; border: none; border-right: 1px solid #cdd6e0; - background-color: transparent; color: #40648a; - -webkit-transition: background-color .2s ease-in, color .2s ease-in; - transition: background-color .2s ease-in, color .2s ease-in; } + height: 50px; + min-width: 50px; + transition: background-color .2s ease-in, color .2s ease-in; } .medium-editor-toolbar li button:hover { background-color: #5c90c7; background-color: rgba(92, 144, 199, 0.45); color: #fff; } .medium-editor-toolbar li .medium-editor-button-first { - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; } + border-bottom-left-radius: 2px; + border-top-left-radius: 2px; } .medium-editor-toolbar li .medium-editor-button-last { - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; } + border-bottom-right-radius: 2px; + border-top-right-radius: 2px; } .medium-editor-toolbar li .medium-editor-button-active { + background: linear-gradient(to bottom, #dee7f0, rgba(0, 0, 0, 0.1)); background-color: #5c90c7; background-color: rgba(92, 144, 199, 0.45); - color: #000; - background: -webkit-linear-gradient(top, #dee7f0, rgba(0, 0, 0, 0.1)); - background: linear-gradient(to bottom, #dee7f0, rgba(0, 0, 0, 0.1)); } + color: #000; } .medium-editor-toolbar-form { background: #dee7f0; - color: #999; - border-radius: 2px; } + border-radius: 2px; + color: #999; } .medium-editor-toolbar-form .medium-editor-toolbar-input { - height: 50px; background: #dee7f0; + box-sizing: border-box; color: #40648a; - box-sizing: border-box; } + height: 50px; } .medium-editor-toolbar-form a { color: #40648a; } .medium-editor-toolbar-anchor-preview { background: #dee7f0; - color: #40648a; - border-radius: 2px; } + border-radius: 2px; + color: #40648a; } .medium-editor-placeholder:after { color: #cdd6e0; } diff --git a/dist/css/themes/mani.min.css b/dist/css/themes/mani.min.css index 7a10b7a5d..3911e304a 100644 --- a/dist/css/themes/mani.min.css +++ b/dist/css/themes/mani.min.css @@ -1 +1 @@ -.medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{border:1px solid #cdd6e0;background-color:#dee7f0;background-color:rgba(222,231,240,.95);background:-webkit-linear-gradient(bottom,#dee7f0,#fff);background:linear-gradient(to top,#dee7f0,#fff);border-radius:2px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{min-width:50px;height:50px;border:none;border-right:1px solid #cdd6e0;background-color:transparent;color:#40648a;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#5c90c7;background-color:rgba(92,144,199,.45);color:#fff}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:2px;border-bottom-left-radius:2px}.medium-editor-toolbar li .medium-editor-button-last{border-top-right-radius:2px;border-bottom-right-radius:2px}.medium-editor-toolbar li .medium-editor-button-active{background-color:#5c90c7;background-color:rgba(92,144,199,.45);color:#000;background:-webkit-linear-gradient(top,#dee7f0,rgba(0,0,0,.1));background:linear-gradient(to bottom,#dee7f0,rgba(0,0,0,.1))}.medium-editor-toolbar-form{background:#dee7f0;color:#999;border-radius:2px}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:50px;background:#dee7f0;color:#40648a;box-sizing:border-box}.medium-editor-toolbar-form a{color:#40648a}.medium-editor-toolbar-anchor-preview{background:#dee7f0;color:#40648a;border-radius:2px}.medium-editor-placeholder:after{color:#cdd6e0} \ No newline at end of file +.medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{background:linear-gradient(to top,#dee7f0,#fff);background-color:#dee7f0;background-color:rgba(222,231,240,.95);border:1px solid #cdd6e0;border-radius:2px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #cdd6e0;color:#40648a;height:50px;min-width:50px;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#5c90c7;background-color:rgba(92,144,199,.45);color:#fff}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:2px;border-top-left-radius:2px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:2px;border-top-right-radius:2px}.medium-editor-toolbar li .medium-editor-button-active{background:linear-gradient(to bottom,#dee7f0,rgba(0,0,0,.1));background-color:#5c90c7;background-color:rgba(92,144,199,.45);color:#000}.medium-editor-toolbar-form{background:#dee7f0;border-radius:2px;color:#999}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#dee7f0;box-sizing:border-box;color:#40648a;height:50px}.medium-editor-toolbar-form a{color:#40648a}.medium-editor-toolbar-anchor-preview{background:#dee7f0;border-radius:2px;color:#40648a}.medium-editor-placeholder:after{color:#cdd6e0} \ No newline at end of file diff --git a/dist/css/themes/roman.css b/dist/css/themes/roman.css index 1929119fb..136b15c00 100644 --- a/dist/css/themes/roman.css +++ b/dist/css/themes/roman.css @@ -8,51 +8,48 @@ border-radius: 5px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); } .medium-editor-toolbar li button { - min-width: 50px; - height: 50px; + background: linear-gradient(to bottom, #fff, rgba(0, 0, 0, 0.2)); + background-color: transparent; border: none; border-right: 1px solid #a8a8a8; - background-color: transparent; - color: #889aac; box-shadow: inset 0 0 3px #f8f8e6; - background: -webkit-linear-gradient(top, #fff, rgba(0, 0, 0, 0.2)); - background: linear-gradient(to bottom, #fff, rgba(0, 0, 0, 0.2)); + color: #889aac; + height: 50px; + min-width: 50px; text-shadow: 1px 4px 6px #def, 0 0 0 #000, 1px 4px 6px #def; - -webkit-transition: background-color .2s ease-in; - transition: background-color .2s ease-in; } + transition: background-color .2s ease-in; } .medium-editor-toolbar li button:hover { background-color: #fff; color: #fff; color: rgba(0, 0, 0, 0.8); } .medium-editor-toolbar li .medium-editor-button-first { - border-top-left-radius: 5px; - border-bottom-left-radius: 5px; } + border-bottom-left-radius: 5px; + border-top-left-radius: 5px; } .medium-editor-toolbar li .medium-editor-button-last { - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; } + border-bottom-right-radius: 5px; + border-top-right-radius: 5px; } .medium-editor-toolbar li .medium-editor-button-active { + background: linear-gradient(to top, #fff, rgba(0, 0, 0, 0.1)); background-color: #ccc; color: #000; - color: rgba(0, 0, 0, 0.8); - background: -webkit-linear-gradient(bottom, #fff, rgba(0, 0, 0, 0.1)); - background: linear-gradient(to top, #fff, rgba(0, 0, 0, 0.1)); } + color: rgba(0, 0, 0, 0.8); } .medium-editor-toolbar-form { background: #fff; - color: #999; - border-radius: 5px; } + border-radius: 5px; + color: #999; } .medium-editor-toolbar-form .medium-editor-toolbar-input { - margin: 0; - height: 50px; background: #fff; - color: #a8a8a8; } + color: #a8a8a8; + height: 50px; + margin: 0; } .medium-editor-toolbar-form a { color: #889aac; } .medium-editor-toolbar-anchor-preview { background: #fff; - color: #889aac; - border-radius: 5px; } + border-radius: 5px; + color: #889aac; } .medium-editor-placeholder:after { color: #a8a8a8; } diff --git a/dist/css/themes/roman.min.css b/dist/css/themes/roman.min.css index 1568f684c..ca567eeb3 100644 --- a/dist/css/themes/roman.min.css +++ b/dist/css/themes/roman.min.css @@ -1 +1 @@ -.medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{background-color:#fff;background-color:rgba(255,255,255,.95);border-radius:5px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{min-width:50px;height:50px;border:none;border-right:1px solid #a8a8a8;background-color:transparent;color:#889aac;box-shadow:inset 0 0 3px #f8f8e6;background:-webkit-linear-gradient(top,#fff,rgba(0,0,0,.2));background:linear-gradient(to bottom,#fff,rgba(0,0,0,.2));text-shadow:1px 4px 6px #def,0 0 0 #000,1px 4px 6px #def;-webkit-transition:background-color .2s ease-in;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#fff;color:#fff;color:rgba(0,0,0,.8)}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:5px;border-bottom-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-top-right-radius:5px;border-bottom-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{background-color:#ccc;color:#000;color:rgba(0,0,0,.8);background:-webkit-linear-gradient(bottom,#fff,rgba(0,0,0,.1));background:linear-gradient(to top,#fff,rgba(0,0,0,.1))}.medium-editor-toolbar-form{background:#fff;color:#999;border-radius:5px}.medium-editor-toolbar-form .medium-editor-toolbar-input{margin:0;height:50px;background:#fff;color:#a8a8a8}.medium-editor-toolbar-form a{color:#889aac}.medium-editor-toolbar-anchor-preview{background:#fff;color:#889aac;border-radius:5px}.medium-editor-placeholder:after{color:#a8a8a8} \ No newline at end of file +.medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{background-color:#fff;background-color:rgba(255,255,255,.95);border-radius:5px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{background:linear-gradient(to bottom,#fff,rgba(0,0,0,.2));background-color:transparent;border:none;border-right:1px solid #a8a8a8;box-shadow:inset 0 0 3px #f8f8e6;color:#889aac;height:50px;min-width:50px;text-shadow:1px 4px 6px #def,0 0 0 #000,1px 4px 6px #def;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#fff;color:#fff;color:rgba(0,0,0,.8)}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:5px;border-top-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:5px;border-top-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{background:linear-gradient(to top,#fff,rgba(0,0,0,.1));background-color:#ccc;color:#000;color:rgba(0,0,0,.8)}.medium-editor-toolbar-form{background:#fff;border-radius:5px;color:#999}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#fff;color:#a8a8a8;height:50px;margin:0}.medium-editor-toolbar-form a{color:#889aac}.medium-editor-toolbar-anchor-preview{background:#fff;border-radius:5px;color:#889aac}.medium-editor-placeholder:after{color:#a8a8a8} \ No newline at end of file diff --git a/dist/css/themes/tim.css b/dist/css/themes/tim.css index a3576bd0f..0e122d3e6 100644 --- a/dist/css/themes/tim.css +++ b/dist/css/themes/tim.css @@ -17,8 +17,7 @@ color: #ffedd5; height: 60px; min-width: 60px; - -webkit-transition: background-color .2s ease-in, color .2s ease-in; - transition: background-color .2s ease-in, color .2s ease-in; } + transition: background-color .2s ease-in, color .2s ease-in; } .medium-editor-toolbar li button:hover { background-color: #030200; color: #ffedd5; } diff --git a/dist/css/themes/tim.min.css b/dist/css/themes/tim.min.css index 882dfe3f6..c6f62d257 100644 --- a/dist/css/themes/tim.min.css +++ b/dist/css/themes/tim.min.css @@ -1 +1 @@ -.medium-toolbar-arrow-under:after{border-color:#2f1e07 transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #2f1e07}.medium-editor-toolbar{background-color:#2f1e07;border:1px solid #5b3a0e;border-radius:6px}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #5b3a0e;box-sizing:border-box;color:#ffedd5;height:60px;min-width:60px;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li .medium-editor-button-active,.medium-editor-toolbar li button:hover{background-color:#030200;color:#ffedd5}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:6px;border-top-left-radius:6px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:6px;border-right:none;border-top-right-radius:6px}.medium-editor-toolbar-form{background:#2f1e07;border-radius:6px;color:#ffedd5}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#2f1e07;color:#ffedd5;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form a{color:#ffedd5}.medium-editor-toolbar-anchor-preview{background:#2f1e07;border-radius:6px;color:#ffedd5}.medium-editor-placeholder:after{color:#5b3a0e} \ No newline at end of file +.medium-toolbar-arrow-under:after{border-color:#2f1e07 transparent transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #2f1e07 transparent}.medium-editor-toolbar{background-color:#2f1e07;border:1px solid #5b3a0e;border-radius:6px}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #5b3a0e;box-sizing:border-box;color:#ffedd5;height:60px;min-width:60px;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#030200;color:#ffedd5}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:6px;border-top-left-radius:6px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:6px;border-right:none;border-top-right-radius:6px}.medium-editor-toolbar li .medium-editor-button-active{background-color:#030200;color:#ffedd5}.medium-editor-toolbar-form{background:#2f1e07;border-radius:6px;color:#ffedd5}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#2f1e07;color:#ffedd5;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#ffedd5;color:rgba(255,237,213,.8)}.medium-editor-toolbar-form a{color:#ffedd5}.medium-editor-toolbar-anchor-preview{background:#2f1e07;border-radius:6px;color:#ffedd5}.medium-editor-placeholder:after{color:#5b3a0e} \ No newline at end of file diff --git a/dist/js/medium-editor.js b/dist/js/medium-editor.js index 568fa893c..1fbad845c 100644 --- a/dist/js/medium-editor.js +++ b/dist/js/medium-editor.js @@ -182,7 +182,7 @@ if (!("classList" in document.createElement("_"))) { */ /*global self, unescape */ -/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, +/*jslint bitwise: true, regexp: true, confusion: true, vars: true, white: true, plusplus: true */ /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ @@ -399,7 +399,7 @@ if (!("classList" in document.createElement("_"))) { 'use strict'; -function MediumEditor(elements, options) { +function MediumEditor (elements, options) { 'use strict'; return this.init(elements, options); } @@ -409,7 +409,7 @@ MediumEditor.extensions = {}; (function (window) { 'use strict'; - function copyInto(overwrite, dest) { + function copyInto (overwrite, dest) { var prop, sources = Array.prototype.slice.call(arguments, 2); dest = dest || {}; @@ -438,13 +438,14 @@ MediumEditor.extensions = {}; testText = document.createTextNode(' '); testParent.appendChild(testText); nodeContainsWorksWithTextNodes = testParent.contains(testText); - } catch (exc) {} + } catch (exc) { + } var Util = { // http://stackoverflow.com/questions/17907445/how-to-detect-ie11#comment30165888_17907562 // by rg89 - isIE: ((navigator.appName === 'Microsoft Internet Explorer') || ((navigator.appName === 'Netscape') && (new RegExp('Trident/.*rv:([0-9]{1,}[.0-9]{0,})').exec(navigator.userAgent) !== null))), + isIE: ((navigator.appName === 'Microsoft Internet Explorer') || ((navigator.appName === 'Netscape') && (new RegExp('Trident/.*rv:([0-9]+[.0-9]*)').exec(navigator.userAgent) !== null))), isEdge: (/Edge\/\d+/).exec(navigator.userAgent) !== null, @@ -473,11 +474,7 @@ MediumEditor.extensions = {}; * See #591 */ isMetaCtrlKey: function (event) { - if ((Util.isMac && event.metaKey) || (!Util.isMac && event.ctrlKey)) { - return true; - } - - return false; + return !!((Util.isMac && event.metaKey) || (!Util.isMac && event.ctrlKey)); }, /** @@ -494,11 +491,7 @@ MediumEditor.extensions = {}; return keyCode === keys; } - if (-1 === keys.indexOf(keyCode)) { - return false; - } - - return true; + return -1 !== keys.indexOf(keyCode); }, getKeyCode: function (event) { @@ -524,12 +517,12 @@ MediumEditor.extensions = {}; emptyElementNames: ['br', 'col', 'colgroup', 'hr', 'img', 'input', 'source', 'wbr'], - extend: function extend(/* dest, source1, source2, ...*/) { + extend: function extend (/* dest, source1, source2, ...*/) { var args = [true].concat(Array.prototype.slice.call(arguments)); return copyInto.apply(this, args); }, - defaults: function defaults(/*dest, source1, source2, ...*/) { + defaults: function defaults (/*dest, source1, source2, ...*/) { var args = [false].concat(Array.prototype.slice.call(arguments)); return copyInto.apply(this, args); }, @@ -633,12 +626,12 @@ MediumEditor.extensions = {}; var textIndexOfEndOfFarthestNode, endSplitPoint; textIndexOfEndOfFarthestNode = currentTextIndex + currentNode.nodeValue.length + - (newNode ? newNode.nodeValue.length : 0) - 1; + (newNode ? newNode.nodeValue.length : 0) - 1; endSplitPoint = matchEndIndex - currentTextIndex - - (newNode ? currentNode.nodeValue.length : 0); + (newNode ? currentNode.nodeValue.length : 0); if (textIndexOfEndOfFarthestNode >= matchEndIndex && - currentTextIndex !== textIndexOfEndOfFarthestNode && - endSplitPoint !== 0) { + currentTextIndex !== textIndexOfEndOfFarthestNode && + endSplitPoint !== 0) { (newNode || currentNode).splitText(endSplitPoint); } }, @@ -648,7 +641,7 @@ MediumEditor.extensions = {}; * 1) All text content of the elements are in separate blocks. No piece of text content should span * across multiple blocks. This means no element return by this function should have * any blocks as children. - * 2) The union of the textcontent of all of the elements returned here covers all + * 2) The union of the text content of all of the elements returned here covers all * of the text within the element. * * @@ -706,7 +699,7 @@ MediumEditor.extensions = {}; // - A descendant of a sibling element // - A sibling text node of an ancestor // - A descendant of a sibling element of an ancestor - findAdjacentTextNodeWithContent: function findAdjacentTextNodeWithContent(rootNode, targetNode, ownerDocument) { + findAdjacentTextNodeWithContent: function findAdjacentTextNodeWithContent (rootNode, targetNode, ownerDocument) { var pastTarget = false, nextNode, nodeIterator = ownerDocument.createNodeIterator(rootNode, NodeFilter.SHOW_TEXT, null, false); @@ -744,7 +737,7 @@ MediumEditor.extensions = {}; return previousSibling; }, - isDescendant: function isDescendant(parent, child, checkEquality) { + isDescendant: function isDescendant (parent, child, checkEquality) { if (!parent || !child) { return false; } @@ -769,7 +762,7 @@ MediumEditor.extensions = {}; }, // https://github.com/jashkenas/underscore - isElement: function isElement(obj) { + isElement: function isElement (obj) { return !!(obj && obj.nodeType === 1); }, @@ -861,7 +854,8 @@ MediumEditor.extensions = {}; if (!MediumEditor.util.isEdge && doc.queryCommandSupported('insertHTML')) { try { return doc.execCommand.apply(doc, ecArgs); - } catch (ignore) {} + } catch (ignore) { + } } selection = doc.getSelection(); @@ -875,13 +869,13 @@ MediumEditor.extensions = {}; if (Util.isMediumEditorElement(toReplace) && !toReplace.firstChild) { range.selectNode(toReplace.appendChild(doc.createTextNode(''))); } else if ((toReplace.nodeType === 3 && range.startOffset === 0 && range.endOffset === toReplace.nodeValue.length) || - (toReplace.nodeType !== 3 && toReplace.innerHTML === range.toString())) { + (toReplace.nodeType !== 3 && toReplace.innerHTML === range.toString())) { // Ensure range covers maximum amount of nodes as possible // By moving up the DOM and selecting ancestors whose only child is the range while (!Util.isMediumEditorElement(toReplace) && - toReplace.parentNode && - toReplace.parentNode.childNodes.length === 1 && - !Util.isMediumEditorElement(toReplace.parentNode)) { + toReplace.parentNode && + toReplace.parentNode.childNodes.length === 1 && + !Util.isMediumEditorElement(toReplace.parentNode)) { toReplace = toReplace.parentNode; } range.selectNode(toReplace); @@ -954,7 +948,7 @@ MediumEditor.extensions = {}; tagName = '<' + tagName + '>'; } - // When FF, IE and Edge, we have to handle blockquote node seperately as 'formatblock' does not work. + // When FF, IE and Edge, we have to handle blockquote node separately as 'formatblock' does not work. // https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand#Commands if (blockContainer && blockContainer.nodeName.toLowerCase() === 'blockquote') { // For IE, just use outdent @@ -1079,19 +1073,90 @@ MediumEditor.extensions = {}; return false; }, + findFirstTextNodeInSelection: function (selection) { + if (selection.anchorNode.nodeType === 3) { + return selection.anchorNode; + } + + var node = selection.anchorNode.firstChild; + + while (node) { + if (selection.containsNode(node, true)) { + if (node.nodeType === 3) { + return node; + } else { + node = node.firstChild; + } + } else { + node = node.nextSibling; + } + } + + return null; + }, + cleanListDOM: function (ownerDocument, element) { if (element.nodeName.toLowerCase() !== 'li') { - return; - } + if (this.isIE || this.isEdge) { + return; + } - var list = element.parentElement; + var selection = ownerDocument.getSelection(), + newRange = ownerDocument.createRange(), + oldRange = selection.getRangeAt(0), + startContainer = oldRange.startContainer, + startOffset = oldRange.startOffset, + endContainer = oldRange.endContainer, + endOffset = oldRange.endOffset, + node, newNode, nextNode, moveEndOffset; + + if (element.nodeName.toLowerCase() === 'span') { + // Chrome & Safari unwraps removed li elements into a span + node = element; + moveEndOffset = false; + } else { + // FF leaves them as text nodes + node = this.findFirstTextNodeInSelection(selection); + moveEndOffset = startContainer.nodeType !== 3; + } + + while (node) { + if (node.nodeName.toLowerCase() !== 'span' && node.nodeType !== 3) { + break; + } + + if (node.nextSibling && node.nextSibling.nodeName.toLowerCase() === 'br') { + node.nextSibling.remove(); - if (list.parentElement.nodeName.toLowerCase() === 'p') { // yes we need to clean up - Util.unwrap(list.parentElement, ownerDocument); + if (moveEndOffset) { + endOffset--; + } + } - // move cursor at the end of the text inside the list - // for some unknown reason, the cursor is moved to end of the "visual" line - MediumEditor.selection.moveCursor(ownerDocument, element.firstChild, element.firstChild.textContent.length); + nextNode = node.nextSibling; + + newNode = ownerDocument.createElement('p'); + node.parentNode.replaceChild(newNode, node); + newNode.appendChild(node); + + node = nextNode; + } + + // Restore selection + newRange.setStart(startContainer, startOffset); + newRange.setEnd(endContainer, endOffset); + selection.removeAllRanges(); + selection.addRange(newRange); + } else { + var list = element.parentElement; + + if (list.parentElement.nodeName.toLowerCase() === 'p') { // yes we need to clean up + Util.unwrap(list.parentElement, ownerDocument); + + // move cursor at the end of the text inside the list + // for some unknown reason, the cursor is moved to end of the "visual" line + MediumEditor.selection.moveCursor(ownerDocument, element.firstChild, element.firstChild.textContent.length); + } } }, @@ -1483,7 +1548,7 @@ MediumEditor.extensions = {}; }, guid: function () { - function _s4() { + function _s4 () { return Math .floor((1 + Math.random()) * 0x10000) .toString(16) @@ -1572,11 +1637,12 @@ MediumEditor.extensions = {}; * current instance of MediumEditor when this is called. * All helper methods will exist as well */ - init: function () {}, + init: function () { + }, /* base: [MediumEditor instance] * - * If not overriden, this will be set to the current instance + * If not overridden, this will be set to the current instance * of MediumEditor, before the init method is called */ base: undefined, @@ -1666,7 +1732,7 @@ MediumEditor.extensions = {}; /* setInactive: [function ()] * * If implemented, this function is called when MediumEditor knows - * that this extension is currently disabled. Curently, this + * that this extension is currently disabled. Currently, this * is called at the beginning of each state change for * the editor & toolbar. After calling this, MediumEditor * will attempt to update the extension, either via checkState() @@ -1697,7 +1763,7 @@ MediumEditor.extensions = {}; /* window: [Window] * - * If not overriden, this will be set to the window object + * If not overridden, this will be set to the window object * to be used by MediumEditor and its extensions. This is * passed via the 'contentWindow' option to MediumEditor * and is the global 'window' object by default @@ -1706,7 +1772,7 @@ MediumEditor.extensions = {}; /* document: [Document] * - * If not overriden, this will be set to the document object + * If not overridden, this will be set to the document object * to be used by MediumEditor and its extensions. This is * passed via the 'ownerDocument' optin to MediumEditor * and is the global 'document' object by default @@ -1773,7 +1839,7 @@ MediumEditor.extensions = {}; (function () { 'use strict'; - function filterOnlyParentElements(node) { + function filterOnlyParentElements (node) { if (MediumEditor.util.isBlockContainer(node)) { return NodeFilter.FILTER_ACCEPT; } else { @@ -1917,12 +1983,11 @@ MediumEditor.extensions = {}; if (allowRangeToStartAtEndOfNode || selectionState.start < nextCharIndex) { range.setStart(node, selectionState.start - charIndex); foundStart = true; - } - // We're at the end of a text node where the selection could start but we shouldn't - // make the selection start here because allowRangeToStartAtEndOfNode is false. - // However, we should keep a reference to this node in case there aren't any more - // text nodes after this, so that we have somewhere to import the selection to - else { + } else { + // We're at the end of a text node where the selection could start but we shouldn't + // make the selection start here because allowRangeToStartAtEndOfNode is false. + // However, we should keep a reference to this node in case there aren't any more + // text nodes after this, so that we have somewhere to import the selection to lastTextNode = node; } } @@ -1994,9 +2059,9 @@ MediumEditor.extensions = {}; return node.nodeName.toLowerCase() === 'a'; }; if (selectionState.start === selectionState.end && - range.startContainer.nodeType === 3 && - range.startOffset === range.startContainer.nodeValue.length && - MediumEditor.util.traverseUp(range.startContainer, nodeInsideAnchorTagFunction)) { + range.startContainer.nodeType === 3 && + range.startOffset === range.startContainer.nodeValue.length && + MediumEditor.util.traverseUp(range.startContainer, nodeInsideAnchorTagFunction)) { var prevNode = range.startContainer, currentNode = range.startContainer.parentNode; while (currentNode !== null && currentNode.nodeName.toLowerCase() !== 'a') { @@ -2074,7 +2139,7 @@ MediumEditor.extensions = {}; }, // Returns -1 unless the cursor is at the beginning of a paragraph/block - // If the paragraph/block is preceeded by empty paragraphs/block (with no text) + // If the paragraph/block is preceded by empty paragraphs/block (with no text) // it will return the number of empty paragraphs before the cursor. // Otherwise, it will return 0, which indicates the cursor is at the beginning // of a paragraph/block, and not at the end of the paragraph/block before it @@ -2099,9 +2164,8 @@ MediumEditor.extensions = {}; // If there is no previous sibling, this is the first text element in the editor if (!previousSibling) { return -1; - } - // If the previous sibling has text, then there are no empty blocks before this - else if (previousSibling.nodeValue) { + } else if (previousSibling.nodeValue) { + // If the previous sibling has text, then there are no empty blocks before this return -1; } } @@ -2151,7 +2215,7 @@ MediumEditor.extensions = {}; if (next === img) { break; } - // If we haven't hit the iamge, but found text that contains content + // If we haven't hit the image, but found text that contains content // then the range doesn't start with an image if (next.nodeValue) { return false; @@ -2236,7 +2300,7 @@ MediumEditor.extensions = {}; selectionContainsContent: function (doc) { var sel = doc.getSelection(); - // collapsed selection or selection withour range doesn't contain content + // collapsed selection or selection without range doesn't contain content if (!sel || sel.isCollapsed || !sel.rangeCount) { return false; } @@ -2277,7 +2341,7 @@ MediumEditor.extensions = {}; // http://stackoverflow.com/questions/4176923/html-of-selected-text // by Tim Down - getSelectionHtml: function getSelectionHtml(doc) { + getSelectionHtml: function getSelectionHtml (doc) { var i, html = '', sel = doc.getSelection(), @@ -2298,9 +2362,9 @@ MediumEditor.extensions = {}; * * @param {DOMElement} An element containing the cursor to find offsets relative to. * @param {Range} A Range representing cursor position. Will window.getSelection if none is passed. - * @return {Object} 'left' and 'right' attributes contain offsets from begining and end of Element + * @return {Object} 'left' and 'right' attributes contain offsets from beginning and end of Element */ - getCaretOffsets: function getCaretOffsets(element, range) { + getCaretOffsets: function getCaretOffsets (element, range) { var preCaretRange, postCaretRange; if (!range) { @@ -2451,7 +2515,7 @@ MediumEditor.extensions = {}; (function () { 'use strict'; - function isElementDescendantOfExtension(extensions, element) { + function isElementDescendantOfExtension (extensions, element) { if (!extensions) { return false; } @@ -2676,17 +2740,17 @@ MediumEditor.extensions = {}; // Helper method to call all listeners to execCommand var callListeners = function (args, result) { - if (doc.execCommand.listeners) { - doc.execCommand.listeners.forEach(function (listener) { - listener({ - command: args[0], - value: args[2], - args: args, - result: result + if (doc.execCommand.listeners) { + doc.execCommand.listeners.forEach(function (listener) { + listener({ + command: args[0], + value: args[2], + args: args, + result: result + }); }); - }); - } - }, + } + }, // Create a wrapper method for execCommand which will: // 1) Call document.execCommand with the correct arguments @@ -2916,7 +2980,7 @@ MediumEditor.extensions = {}; if (!this.contentCache) { return; } - // An event triggered which signifies that the user may have changed someting + // An event triggered which signifies that the user may have changed something // Look in our cache of input for the contenteditables to see if something changed var index = target.getAttribute('medium-editor-index'), html = target.innerHTML; @@ -3593,7 +3657,7 @@ MediumEditor.extensions = {}; return false; }, - /* hideForm: [function ()] + /* showForm: [function ()] * * This function should show the form element inside * the toolbar container @@ -3772,7 +3836,7 @@ MediumEditor.extensions = {}; if (this.targetCheckbox) { // fixme: ideally, this targetCheckboxText would be a formLabel too, - // figure out how to deprecate? also consider `fa-` icon default implcations. + // figure out how to deprecate? also consider `fa-` icon default implications. template.push( '
', '', @@ -3788,8 +3852,8 @@ MediumEditor.extensions = {}; // and provide similar access to a `fa-` icon default. template.push( '
', - '', - '
' @@ -3816,7 +3880,7 @@ MediumEditor.extensions = {}; buttonCheckbox = this.getAnchorButtonCheckbox(); opts = opts || { value: '' }; - // TODO: This is for backwards compatability + // TODO: This is for backwards compatibility // We don't need to support the 'string' argument in 6.0.0 if (typeof opts === 'string') { opts = { @@ -3921,11 +3985,11 @@ MediumEditor.extensions = {}; // Matches protocol relative "//" // Matches common external protocols "mailto:" "tel:" "maps:" // Matches relative hash link, begins with "#" - var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):|^\#/i, + var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):|^#/i, hasScheme = urlSchemeRegex.test(value), scheme = '', // telRegex is a regex for checking if the string is a telephone number - telRegex = /^\+?\s?\(?(?:\d\s?\-?\)?){3,20}$/, + telRegex = /^\+?\s?\(?(?:\d\s?-?\)?){3,20}$/, urlParts = value.match(/^(.*?)(?:\?(.*?))?(?:#(.*))?$/), path = urlParts[1], query = urlParts[2], @@ -3938,7 +4002,7 @@ MediumEditor.extensions = {}; if (!hasScheme) { var host = path.split('/')[0]; // if the host part of the path looks like a hostname - if (host.match(/.+(\.|:).+/) || host === 'localhost') { + if (host.match(/.+([.:]).+/) || host === 'localhost') { scheme = 'http://'; } } @@ -4120,7 +4184,7 @@ MediumEditor.extensions = {}; showPreview: function (anchorEl) { if (this.anchorPreview.classList.contains('medium-editor-anchor-preview-active') || - anchorEl.getAttribute('data-disable-preview')) { + anchorEl.getAttribute('data-disable-preview')) { return true; } @@ -4356,7 +4420,7 @@ MediumEditor.extensions = {}; LINK_REGEXP; WHITESPACE_CHARS = [' ', '\t', '\n', '\r', '\u00A0', '\u2000', '\u2001', '\u2002', '\u2003', - '\u2028', '\u2029']; + '\u2028', '\u2029']; KNOWN_TLDS_FRAGMENT = 'com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|' + 'xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|' + 'bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|' + @@ -4377,7 +4441,7 @@ MediumEditor.extensions = {}; LINK_REGEXP = new RegExp(LINK_REGEXP_TEXT, 'gi'); - function nodeIsNotInsideAnchorTag(node) { + function nodeIsNotInsideAnchorTag (node) { return !MediumEditor.util.getClosestTag(node, 'a'); } @@ -4536,7 +4600,7 @@ MediumEditor.extensions = {}; for (var matchIndex = 0; matchIndex < matches.length; matchIndex++) { var matchingTextNodes = MediumEditor.util.findOrCreateMatchingTextNodes(this.document, element, - matches[matchIndex]); + matches[matchIndex]); if (this.shouldNotLink(matchingTextNodes)) { continue; } @@ -4605,7 +4669,7 @@ MediumEditor.extensions = {}; var CLASS_DRAG_OVER = 'medium-editor-dragover'; - function clearClassNames(element) { + function clearClassNames (element) { var editable = MediumEditor.util.getContainerEditorElement(element), existing = Array.prototype.slice.call(editable.parentElement.querySelectorAll('.' + CLASS_DRAG_OVER)); @@ -4760,16 +4824,15 @@ MediumEditor.extensions = {}; if (data.meta === isMeta && data.shift === isShift && (data.alt === isAlt || - undefined === data.alt)) { // TODO deprecated: remove check for undefined === data.alt when jumping to 6.0.0 + undefined === data.alt)) { // TODO deprecated: remove check for undefined === data.alt when jumping to 6.0.0 event.preventDefault(); event.stopPropagation(); // command can be a function to execute if (typeof data.command === 'function') { data.command.apply(this); - } - // command can be false so the shortcut is just disabled - else if (false !== data.command) { + } else if (false !== data.command) { + // command can be false so the shortcut is just disabled this.execAction(data.command); } } @@ -4885,7 +4948,7 @@ MediumEditor.extensions = {}; this.on(form, 'click', this.handleFormClick.bind(this)); // Add font names - for (var i = 0; i' : - '✓'; + '' : + '✓'; form.appendChild(save); // Handle save button clicks (capture) @@ -4911,10 +4974,10 @@ MediumEditor.extensions = {}; // Add close button close.setAttribute('href', '#'); - close.className = 'medium-editor-toobar-close'; + close.className = 'medium-editor-toolbar-close'; close.innerHTML = this.getEditorOption('buttonLabels') === 'fontawesome' ? - '' : - '×'; + '' : + '×'; form.appendChild(close); // Handle close button clicks @@ -5076,12 +5139,12 @@ MediumEditor.extensions = {}; // Handle typing in the textbox this.on(input, 'change', this.handleSliderChange.bind(this)); - // Add save buton + // Add save button save.setAttribute('href', '#'); - save.className = 'medium-editor-toobar-save'; + save.className = 'medium-editor-toolbar-save'; save.innerHTML = this.getEditorOption('buttonLabels') === 'fontawesome' ? - '' : - '✓'; + '' : + '✓'; form.appendChild(save); // Handle save button clicks (capture) @@ -5089,10 +5152,10 @@ MediumEditor.extensions = {}; // Add close button close.setAttribute('href', '#'); - close.className = 'medium-editor-toobar-close'; + close.className = 'medium-editor-toolbar-close'; close.innerHTML = this.getEditorOption('buttonLabels') === 'fontawesome' ? - '' : - '×'; + '' : + '×'; form.appendChild(close); // Handle close button clicks @@ -5155,13 +5218,12 @@ MediumEditor.extensions = {}; }; /*jslint regexp: true*/ - /* - jslint does not allow character negation, because the negation - will not match any unicode characters. In the regexes in this - block, negation is used specifically to match the end of an html - tag, and in fact unicode characters *should* be allowed. - */ - function createReplacements() { + + // jslint does not allow character negation, because the negation + // will not match any unicode characters. In the regexes in this + // block, negation is used specifically to match the end of an html + // tag, and in fact unicode characters *should* be allowed. + function createReplacements () { return [ // Remove anything but the contents within the BODY element [new RegExp(/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g), ''], @@ -5176,7 +5238,7 @@ MediumEditor.extensions = {}; [new RegExp(/<[^>]*docs-internal-guid[^>]*>/gi), ''], [new RegExp(/<\/b>(]*>)?$/gi), ''], - // un-html spaces and newlines inserted by OS X + // un-html spaces and newlines inserted by OS X [new RegExp(/\s+<\/span>/g), ' '], [new RegExp(/
/g), '
'], @@ -5189,10 +5251,10 @@ MediumEditor.extensions = {}; //[replace google docs bolds with a span to be replaced once the html is inserted [new RegExp(/]*font-weight:(bold|700)[^>]*>/gi), ''], - // replace manually entered b/i/a tags with real ones - [new RegExp(/<(\/?)(i|b|a)>/gi), '<$1$2>'], + // replace manually entered b/i/a tags with real ones + [new RegExp(/<(\/?)([iba])>/gi), '<$1$2>'], - // replace manually a tags with real ones, converting smart-quotes from google docs + // replace manually a tags with real ones, converting smart-quotes from google docs [new RegExp(/<a(?:(?!href).)+href=(?:"|”|“|"|“|”)(((?!"|”|“|"|“|”).)*)(?:"|”|“|"|“|”)(?:(?!>).)*>/gi), ''], // Newlines between paragraphs in html have no syntactic value, @@ -5204,9 +5266,10 @@ MediumEditor.extensions = {}; [new RegExp(/<\/?o:[a-z]*>/gi), ''], // Microsoft Word adds some special elements around list items - [new RegExp(/(((?!/gi), '$1'] + [new RegExp(/(((?!/gi), '$1'] ]; } + /*jslint regexp: false*/ /** @@ -5218,7 +5281,7 @@ MediumEditor.extensions = {}; * @param {doc} reference to document * @return {Object} Object with mime types and data for those mime types. */ - function getClipboardContent(event, win, doc) { + function getClipboardContent (event, win, doc) { var dataTransfer = event.clipboardData || win.clipboardData || doc.dataTransfer, data = {}; @@ -5972,7 +6035,7 @@ MediumEditor.extensions = {}; } // If the button already exists as an extension, it'll be returned - // othwerise it'll create the default built-in button + // otherwise it'll create the default built-in button extension = this.base.addBuiltInExtension(buttonName, buttonOpts); if (extension && typeof extension.getButton === 'function') { @@ -6069,8 +6132,8 @@ MediumEditor.extensions = {}; handleDocumentMouseup: function (event) { // Do not trigger checkState when mouseup fires over the toolbar if (event && - event.target && - MediumEditor.util.isDescendant(this.getToolbarElement(), event.target)) { + event.target && + MediumEditor.util.isDescendant(this.getToolbarElement(), event.target)) { return false; } this.checkState(); @@ -6162,7 +6225,7 @@ MediumEditor.extensions = {}; // Responding to changes in user selection - // Checks for existance of multiple block elements in the current selection + // Checks for existence of multiple block elements in the current selection multipleBlockElementsSelected: function () { var regexEmptyHTMLTags = /<[^\/>][^>]*><\/[^>]+>/gim, // http://stackoverflow.com/questions/3129738/remove-empty-tags-using-regex regexBlockElements = new RegExp('<(' + MediumEditor.util.blockContainerElementNames.join('|') + ')[^>]*>', 'g'), @@ -6193,8 +6256,8 @@ MediumEditor.extensions = {}; * adjacent text node that actually has content in it, and move the selectionRange start there. */ if (this.standardizeSelectionStart && - selectionRange.startContainer.nodeValue && - (selectionRange.startOffset === selectionRange.startContainer.nodeValue.length)) { + selectionRange.startContainer.nodeValue && + (selectionRange.startOffset === selectionRange.startContainer.nodeValue.length)) { var adjacentNode = MediumEditor.util.findAdjacentTextNodeWithContent(MediumEditor.selection.getSelectionElement(this.window), selectionRange.startContainer, this.document); if (adjacentNode) { var offset = 0; @@ -6215,7 +6278,7 @@ MediumEditor.extensions = {}; // If no editable has focus OR selection is inside contenteditable = false // hide toolbar if (!this.base.getFocusedElement() || - MediumEditor.selection.selectionInContentEditableFalse(this.window)) { + MediumEditor.selection.selectionInContentEditableFalse(this.window)) { return this.hideToolbar(); } @@ -6224,8 +6287,8 @@ MediumEditor.extensions = {}; // hide toolbar var selectionElement = MediumEditor.selection.getSelectionElement(this.window); if (!selectionElement || - this.getEditorElements().indexOf(selectionElement) === -1 || - selectionElement.getAttribute('data-disable-toolbar')) { + this.getEditorElements().indexOf(selectionElement) === -1 || + selectionElement.getAttribute('data-disable-toolbar')) { return this.hideToolbar(); } @@ -6275,8 +6338,8 @@ MediumEditor.extensions = {}; if (typeof extension.checkState === 'function') { extension.checkState(parentNode); } else if (typeof extension.isActive === 'function' && - typeof extension.isAlreadyApplied === 'function' && - typeof extension.setActive === 'function') { + typeof extension.isAlreadyApplied === 'function' && + typeof extension.setActive === 'function') { if (!extension.isActive() && extension.isAlreadyApplied(parentNode)) { extension.setActive(); } @@ -6309,8 +6372,8 @@ MediumEditor.extensions = {}; // Make sure the selection parent isn't outside of the contenteditable if (!this.getEditorElements().some(function (element) { - return MediumEditor.util.isDescendant(element, parentNode, true); - })) { + return MediumEditor.util.isDescendant(element, parentNode, true); + })) { return; } @@ -6380,11 +6443,11 @@ MediumEditor.extensions = {}; if (scrollTop > (containerTop + container.offsetHeight - toolbarHeight - this.stickyTopOffset)) { toolbarElement.style.top = (containerTop + container.offsetHeight - toolbarHeight) + 'px'; toolbarElement.classList.remove('medium-editor-sticky-toolbar'); - // Stick the toolbar to the top of the window + // Stick the toolbar to the top of the window } else if (scrollTop > (containerTop - toolbarHeight - this.stickyTopOffset)) { toolbarElement.classList.add('medium-editor-sticky-toolbar'); toolbarElement.style.top = this.stickyTopOffset + 'px'; - // Normal static toolbar position + // Normal static toolbar position } else { toolbarElement.classList.remove('medium-editor-sticky-toolbar'); toolbarElement.style.top = containerTop - toolbarHeight + 'px'; @@ -6565,7 +6628,7 @@ MediumEditor.extensions = {}; // Event handlers that shouldn't be exposed externally - function handleDisableExtraSpaces(event) { + function handleDisableExtraSpaces (event) { var node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), textContent = node.textContent, caretPositions = MediumEditor.selection.getCaretOffsets(node); @@ -6575,7 +6638,7 @@ MediumEditor.extensions = {}; } } - function handleDisabledEnterKeydown(event, element) { + function handleDisabledEnterKeydown (event, element) { if (this.options.disableReturn || element.getAttribute('data-disable-return')) { event.preventDefault(); } else if (this.options.disableDoubleReturn || element.getAttribute('data-disable-double-return')) { @@ -6584,13 +6647,13 @@ MediumEditor.extensions = {}; // if current text selection is empty OR previous sibling text is empty OR it is not a list if ((node && node.textContent.trim() === '' && node.nodeName.toLowerCase() !== 'li') || (node.previousElementSibling && node.previousElementSibling.nodeName.toLowerCase() !== 'br' && - node.previousElementSibling.textContent.trim() === '')) { + node.previousElementSibling.textContent.trim() === '')) { event.preventDefault(); } } } - function handleTabKeydown(event) { + function handleTabKeydown (event) { // Override tab only for pre nodes var node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), tag = node && node.nodeName.toLowerCase(); @@ -6613,27 +6676,27 @@ MediumEditor.extensions = {}; } } - function handleBlockDeleteKeydowns(event) { + function handleBlockDeleteKeydowns (event) { var p, node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), tagName = node.nodeName.toLowerCase(), isEmpty = /^(\s+|)?$/i, isHeader = /h\d/i; if (MediumEditor.util.isKey(event, [MediumEditor.util.keyCode.BACKSPACE, MediumEditor.util.keyCode.ENTER]) && - // has a preceeding sibling - node.previousElementSibling && - // in a header - isHeader.test(tagName) && - // at the very end of the block - MediumEditor.selection.getCaretOffsets(node).left === 0) { + // has a preceding sibling + node.previousElementSibling && + // in a header + isHeader.test(tagName) && + // at the very end of the block + MediumEditor.selection.getCaretOffsets(node).left === 0) { if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && isEmpty.test(node.previousElementSibling.innerHTML)) { - // backspacing the begining of a header into an empty previous element will + // backspacing the beginning of a header into an empty previous element will // change the tagName of the current node to prevent one // instead delete previous node and cancel the event. node.previousElementSibling.parentNode.removeChild(node.previousElementSibling); event.preventDefault(); } else if (!this.options.disableDoubleReturn && MediumEditor.util.isKey(event, MediumEditor.util.keyCode.ENTER)) { - // hitting return in the begining of a header will create empty header elements before the current one + // hitting return in the beginning of a header will create empty header elements before the current one // instead, make "


" element, which are what happens if you hit return in an empty paragraph p = this.options.ownerDocument.createElement('p'); p.innerHTML = '
'; @@ -6641,19 +6704,19 @@ MediumEditor.extensions = {}; event.preventDefault(); } } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.DELETE) && - // between two sibling elements - node.nextElementSibling && - node.previousElementSibling && - // not in a header - !isHeader.test(tagName) && - // in an empty tag - isEmpty.test(node.innerHTML) && - // when the next tag *is* a header - isHeader.test(node.nextElementSibling.nodeName.toLowerCase())) { + // between two sibling elements + node.nextElementSibling && + node.previousElementSibling && + // not in a header + !isHeader.test(tagName) && + // in an empty tag + isEmpty.test(node.innerHTML) && + // when the next tag *is* a header + isHeader.test(node.nextElementSibling.nodeName.toLowerCase())) { // hitting delete in an empty element preceding a header, ex: //

[CURSOR]

Header

// Will cause the h1 to become a paragraph. - // Instead, delete the paragraph node and move the cursor to the begining of the h1 + // Instead, delete the paragraph node and move the cursor to the beginning of the h1 // remove node and move cursor to start of header MediumEditor.selection.moveCursor(this.options.ownerDocument, node.nextElementSibling); @@ -6662,16 +6725,16 @@ MediumEditor.extensions = {}; event.preventDefault(); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && - tagName === 'li' && - // hitting backspace inside an empty li - isEmpty.test(node.innerHTML) && - // is first element (no preceeding siblings) - !node.previousElementSibling && - // parent also does not have a sibling - !node.parentElement.previousElementSibling && - // is not the only li in a list - node.nextElementSibling && - node.nextElementSibling.nodeName.toLowerCase() === 'li') { + tagName === 'li' && + // hitting backspace inside an empty li + isEmpty.test(node.innerHTML) && + // is first element (no preceding siblings) + !node.previousElementSibling && + // parent also does not have a sibling + !node.parentElement.previousElementSibling && + // is not the only li in a list + node.nextElementSibling && + node.nextElementSibling.nodeName.toLowerCase() === 'li') { // backspacing in an empty first list element in the first list (with more elements) ex: //
  • [CURSOR]
  • List Item 2
// will remove the first
  • but add some extra element before (varies based on browser) @@ -6693,16 +6756,16 @@ MediumEditor.extensions = {}; event.preventDefault(); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && - (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && - MediumEditor.selection.getCaretOffsets(node).left === 0) { + (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && + MediumEditor.selection.getCaretOffsets(node).left === 0) { - // when cursor is at the begining of the element and the element is
    + // when cursor is at the beginning of the element and the element is
    // then pressing backspace key should change the
    to a

    tag event.preventDefault(); MediumEditor.util.execFormatBlock(this.options.ownerDocument, 'p'); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.ENTER) && - (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && - MediumEditor.selection.getCaretOffsets(node).right === 0) { + (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && + MediumEditor.selection.getCaretOffsets(node).right === 0) { // when cursor is at the end of

    , // then pressing enter key should create

    tag, not

    @@ -6715,10 +6778,10 @@ MediumEditor.extensions = {}; event.preventDefault(); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && - MediumEditor.util.isMediumEditorElement(node.parentElement) && - !node.previousElementSibling && - node.nextElementSibling && - isEmpty.test(node.innerHTML)) { + MediumEditor.util.isMediumEditorElement(node.parentElement) && + !node.previousElementSibling && + node.nextElementSibling && + isEmpty.test(node.innerHTML)) { // when cursor is in the first element, it's empty and user presses backspace, // do delete action instead to get rid of the first element and move caret to 2nd @@ -6728,7 +6791,7 @@ MediumEditor.extensions = {}; } } - function handleKeyup(event) { + function handleKeyup (event) { var node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), tagName; @@ -6742,6 +6805,12 @@ MediumEditor.extensions = {}; this.options.ownerDocument.execCommand('formatBlock', false, 'p'); } + // https://github.com/yabwe/medium-editor/issues/1455 + // if somehow we have the BR as the selected element, typing does nothing, so move the cursor + if (node.nodeName === 'BR') { + MediumEditor.selection.moveCursor(this.options.ownerDocument, node.parentElement); + } + // https://github.com/yabwe/medium-editor/issues/834 // https://github.com/yabwe/medium-editor/pull/382 // Don't call format block if this is a block element (ie h1, figCaption, etc.) @@ -6755,11 +6824,19 @@ MediumEditor.extensions = {}; this.options.ownerDocument.execCommand('unlink', false, null); } else if (!event.shiftKey && !event.ctrlKey) { this.options.ownerDocument.execCommand('formatBlock', false, 'p'); + // https://github.com/yabwe/medium-editor/issues/1455 + // firefox puts the focus on the br - so we need to move the cursor to the newly created p + if (MediumEditor.util.isFF) { + var newParagraph = node.querySelector('p'); + if (newParagraph) { + MediumEditor.selection.moveCursor(this.options.ownerDocument, newParagraph); + } + } } } } - function handleEditableInput(event, editable) { + function handleEditableInput (event, editable) { var textarea = editable.parentNode.querySelector('textarea[medium-editor-textarea-id="' + editable.getAttribute('medium-editor-textarea-id') + '"]'); if (textarea) { textarea.value = editable.innerHTML.trim(); @@ -6768,7 +6845,7 @@ MediumEditor.extensions = {}; // Internal helper methods which shouldn't be exposed externally - function addToEditors(win) { + function addToEditors (win) { if (!win._mediumEditors) { // To avoid breaking users who are assuming that the unique id on // medium-editor elements will start at 1, inserting a 'null' in the @@ -6784,7 +6861,7 @@ MediumEditor.extensions = {}; win._mediumEditors[this.id] = this; } - function removeFromEditors(win) { + function removeFromEditors (win) { if (!win._mediumEditors || !win._mediumEditors[this.id]) { return; } @@ -6799,7 +6876,7 @@ MediumEditor.extensions = {}; win._mediumEditors[this.id] = null; } - function createElementsArray(selector, doc, filterEditorElements) { + function createElementsArray (selector, doc, filterEditorElements) { var elements = []; if (!selector) { @@ -6833,7 +6910,7 @@ MediumEditor.extensions = {}; return elements; } - function cleanupTextareaElement(element) { + function cleanupTextareaElement (element) { var textarea = element.parentNode.querySelector('textarea[medium-editor-textarea-id="' + element.getAttribute('medium-editor-textarea-id') + '"]'); if (textarea) { // Un-hide the textarea @@ -6845,7 +6922,7 @@ MediumEditor.extensions = {}; } } - function setExtensionDefaults(extension, defaults) { + function setExtensionDefaults (extension, defaults) { Object.keys(defaults).forEach(function (prop) { if (extension[prop] === undefined) { extension[prop] = defaults[prop]; @@ -6854,7 +6931,7 @@ MediumEditor.extensions = {}; return extension; } - function initExtension(extension, name, instance) { + function initExtension (extension, name, instance) { var extensionDefaults = { 'window': instance.options.contentWindow, 'document': instance.options.ownerDocument, @@ -6876,19 +6953,19 @@ MediumEditor.extensions = {}; return extension; } - function isToolbarEnabled() { + function isToolbarEnabled () { // If any of the elements don't have the toolbar disabled // We need a toolbar if (this.elements.every(function (element) { - return !!element.getAttribute('data-disable-toolbar'); - })) { + return !!element.getAttribute('data-disable-toolbar'); + })) { return false; } return this.options.toolbar !== false; } - function isAnchorPreviewEnabled() { + function isAnchorPreviewEnabled () { // If toolbar is disabled, don't add if (!isToolbarEnabled.call(this)) { return false; @@ -6897,34 +6974,34 @@ MediumEditor.extensions = {}; return this.options.anchorPreview !== false; } - function isPlaceholderEnabled() { + function isPlaceholderEnabled () { return this.options.placeholder !== false; } - function isAutoLinkEnabled() { + function isAutoLinkEnabled () { return this.options.autoLink !== false; } - function isImageDraggingEnabled() { + function isImageDraggingEnabled () { return this.options.imageDragging !== false; } - function isKeyboardCommandsEnabled() { + function isKeyboardCommandsEnabled () { return this.options.keyboardCommands !== false; } - function shouldUseFileDraggingExtension() { + function shouldUseFileDraggingExtension () { // Since the file-dragging extension replaces the image-dragging extension, - // we need to check if the user passed an overrided image-dragging extension. + // we need to check if the user passed an overridden image-dragging extension. // If they have, to avoid breaking users, we won't use file-dragging extension. return !this.options.extensions['imageDragging']; } - function createContentEditable(textarea) { + function createContentEditable (textarea) { var div = this.options.ownerDocument.createElement('div'), now = Date.now(), uniqueId = 'medium-editor-' + now, - atts = textarea.attributes; + attributes = textarea.attributes; // Some browsers can move pretty fast, since we're using a timestamp // to make a unique-id, ensure that the id is actually unique on the page @@ -6939,11 +7016,11 @@ MediumEditor.extensions = {}; textarea.setAttribute('medium-editor-textarea-id', uniqueId); - // re-create all attributes from the textearea to the new created div - for (var i = 0, n = atts.length; i < n; i++) { + // re-create all attributes from the textarea to the new created div + for (var i = 0, n = attributes.length; i < n; i++) { // do not re-create existing attributes - if (!div.hasAttribute(atts[i].nodeName)) { - div.setAttribute(atts[i].nodeName, atts[i].value); + if (!div.hasAttribute(attributes[i].nodeName)) { + div.setAttribute(attributes[i].nodeName, attributes[i].value); } } @@ -6966,7 +7043,9 @@ MediumEditor.extensions = {}; return div; } - function initElement(element, editorId) { + var initialContent = {}; + + function initElement (element, editorId) { if (!element.getAttribute('data-medium-editor-element')) { if (element.nodeName.toLowerCase() === 'textarea') { element = createContentEditable.call(this, element); @@ -7016,7 +7095,7 @@ MediumEditor.extensions = {}; return element; } - function attachHandlers() { + function attachHandlers () { // attach to tabs this.subscribe('editableKeydownTab', handleTabKeydown.bind(this)); @@ -7039,7 +7118,7 @@ MediumEditor.extensions = {}; } } - function initExtensions() { + function initExtensions () { this.extensions = []; @@ -7051,7 +7130,7 @@ MediumEditor.extensions = {}; } }, this); - // 4 Cases for imageDragging + fileDragging extensons: + // 4 Cases for imageDragging + fileDragging extensions: // // 1. ImageDragging ON + No Custom Image Dragging Extension: // * Use fileDragging extension (default options) @@ -7094,7 +7173,7 @@ MediumEditor.extensions = {}; // just create the default toolbar var toolbarExtension = this.options.extensions['toolbar']; if (!toolbarExtension && isToolbarEnabled.call(this)) { - // Backwards compatability + // Backwards compatibility var toolbarOptions = MediumEditor.util.extend({}, this.options.toolbar, { allowMultiParagraphSelection: this.options.allowMultiParagraphSelection // deprecated }); @@ -7108,7 +7187,7 @@ MediumEditor.extensions = {}; } } - function mergeOptions(defaults, options) { + function mergeOptions (defaults, options) { var deprecatedProperties = [ ['allowMultiParagraphSelection', 'toolbar.allowMultiParagraphSelection'] ]; @@ -7124,7 +7203,7 @@ MediumEditor.extensions = {}; return MediumEditor.util.defaults({}, options, defaults); } - function execActionInternal(action, opts) { + function execActionInternal (action, opts) { /*jslint regexp: true*/ var appendAction = /^append-(.+)$/gi, justifyAction = /justify([A-Za-z]*)$/g, /* Detecting if is justifyCenter|Right|Left */ @@ -7191,7 +7270,7 @@ MediumEditor.extensions = {}; * Chrome may have removed
    elements and instead wrapped lines in
    elements * with a text-align property. If so, we want to fix this */ - function cleanupJustifyDivFragments(blockContainer) { + function cleanupJustifyDivFragments (blockContainer) { if (!blockContainer) { return; } @@ -7232,10 +7311,8 @@ MediumEditor.extensions = {}; } } - var initialContent = {}; - MediumEditor.prototype = { - // NOT DOCUMENTED - exposed for backwards compatability + // NOT DOCUMENTED - exposed for backwards compatibility init: function (elements, options) { this.options = mergeOptions.call(this, this.defaults, options); this.origElements = elements; @@ -7504,6 +7581,12 @@ MediumEditor.extensions = {}; MediumEditor.util.cleanListDOM(this.options.ownerDocument, this.getSelectedParentElement()); } + // https://github.com/yabwe/medium-editor/issues/1496 + // ensure the focus remains in the editor for Firefox + if (MediumEditor.util.isFF) { + MediumEditor.util.getContainerEditorElement(this.getSelectedParentElement()).focus(); + } + this.checkSelection(); return result; }, @@ -7642,7 +7725,7 @@ MediumEditor.extensions = {}; // since we are going to create a link from an extracted text, // be sure that if we are updating a link, we won't let an empty link behind (see #754) - // (Workaroung for Chrome) + // (Workaround for Chrome) this.execAction('unlink'); exportedSelection = this.exportSelection(); @@ -7653,7 +7736,7 @@ MediumEditor.extensions = {}; // as our reference inside this.elements gets detached from the page when insertHTML runs. // If we just use [parentElement, 0] and [parentElement, parentElement.childNodes.length] // as the range boundaries, this happens whenever parentElement === currentEditor. - // The tradeoff to this workaround is that a orphaned tag can sometimes be left behind at + // The trade-off to this workaround is that a orphaned tag can sometimes be left behind at // the end of the editor's content. // In Gecko: // as an empty if parentElement.lastChild is a tag. @@ -7665,7 +7748,7 @@ MediumEditor.extensions = {}; 0, parentElement.lastChild, parentElement.lastChild.nodeType === 3 ? - parentElement.lastChild.nodeValue.length : parentElement.lastChild.childNodes.length + parentElement.lastChild.nodeValue.length : parentElement.lastChild.childNodes.length ); } else { MediumEditor.selection.select( diff --git a/dist/js/medium-editor.min.js b/dist/js/medium-editor.min.js index 386781608..d0fb0f8d2 100644 --- a/dist/js/medium-editor.min.js +++ b/dist/js/medium-editor.min.js @@ -1,4 +1 @@ -"classList"in document.createElement("_")||!function(a){"use strict";if("Element"in a){var b="classList",c="prototype",d=a.Element[c],e=Object,f=String[c].trim||function(){return this.replace(/^\s+|\s+$/g,"")},g=Array[c].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},h=function(a,b){this.name=a,this.code=DOMException[a],this.message=b},i=function(a,b){if(""===b)throw new h("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(b))throw new h("INVALID_CHARACTER_ERR","String contains an invalid character");return g.call(a,b)},j=function(a){for(var b=f.call(a.getAttribute("class")||""),c=b?b.split(/\s+/):[],d=0,e=c.length;e>d;d++)this.push(c[d]);this._updateClassName=function(){a.setAttribute("class",this.toString())}},k=j[c]=[],l=function(){return new j(this)};if(h[c]=Error[c],k.item=function(a){return this[a]||null},k.contains=function(a){return a+="",-1!==i(this,a)},k.add=function(){var a,b=arguments,c=0,d=b.length,e=!1;do a=b[c]+"",-1===i(this,a)&&(this.push(a),e=!0);while(++ci;i++)e+=String.fromCharCode(f[i]);c.push(e)}else if("Blob"===b(a)||"File"===b(a)){if(!g)throw new h("NOT_READABLE_ERR");var k=new g;c.push(k.readAsBinaryString(a))}else a instanceof d?"base64"===a.encoding&&p?c.push(p(a.data)):"URI"===a.encoding?c.push(decodeURIComponent(a.data)):"raw"===a.encoding&&c.push(a.data):("string"!=typeof a&&(a+=""),c.push(unescape(encodeURIComponent(a))))},e.getBlob=function(a){return arguments.length||(a=null),new d(this.data.join(""),a,"raw")},e.toString=function(){return"[object BlobBuilder]"},f.slice=function(a,b,c){var e=arguments.length;return 3>e&&(c=null),new d(this.data.slice(a,e>1?b:this.data.length),c,this.encoding)},f.toString=function(){return"[object Blob]"},f.close=function(){this.size=0,delete this.data},c}(a);a.Blob=function(a,b){var d=b?b.type||"":"",e=new c;if(a)for(var f=0,g=a.length;g>f;f++)Uint8Array&&a[f]instanceof Uint8Array?e.append(a[f].buffer):e.append(a[f]);var h=e.getBlob(d);return!h.slice&&h.webkitSlice&&(h.slice=h.webkitSlice),h};var d=Object.getPrototypeOf||function(a){return a.__proto__};a.Blob.prototype=d(new a.Blob)}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this),function(a,b){"use strict";var c="object"==typeof module&&"undefined"!=typeof process&&process&&process.versions&&process.versions.electron;c||"object"!=typeof module?"function"==typeof define&&define.amd?define(function(){return b}):a.MediumEditor=b:module.exports=b}(this,function(){"use strict";function a(a,b){return this.init(a,b)}return a.extensions={},function(b){function c(a,b){var c,d=Array.prototype.slice.call(arguments,2);b=b||{};for(var e=0;e-1,isMac:b.navigator.platform.toUpperCase().indexOf("MAC")>=0,keyCode:{BACKSPACE:8,TAB:9,ENTER:13,ESCAPE:27,SPACE:32,DELETE:46,K:75,M:77,V:86},isMetaCtrlKey:function(a){return!!(h.isMac&&a.metaKey||!h.isMac&&a.ctrlKey)},isKey:function(a,b){var c=h.getKeyCode(a);return!1===Array.isArray(b)?c===b:-1!==b.indexOf(c)},getKeyCode:function(a){var b=a.which;return null===b&&(b=null!==a.charCode?a.charCode:a.keyCode),b},blockContainerElementNames:["p","h1","h2","h3","h4","h5","h6","blockquote","pre","ul","li","ol","address","article","aside","audio","canvas","dd","dl","dt","fieldset","figcaption","figure","footer","form","header","hgroup","main","nav","noscript","output","section","video","table","thead","tbody","tfoot","tr","th","td"],emptyElementNames:["br","col","colgroup","hr","img","input","source","wbr"],extend:function(){var a=[!0].concat(Array.prototype.slice.call(arguments));return c.apply(this,a)},defaults:function(){var a=[!1].concat(Array.prototype.slice.call(arguments));return c.apply(this,a)},createLink:function(a,b,c,d){var e=a.createElement("a");return h.moveTextRangeIntoElement(b[0],b[b.length-1],e),e.setAttribute("href",c),d&&("_blank"===d&&e.setAttribute("rel","noopener noreferrer"),e.setAttribute("target",d)),e},findOrCreateMatchingTextNodes:function(a,b,c){for(var d=a.createTreeWalker(b,NodeFilter.SHOW_ALL,null,!1),e=[],f=0,g=!1,i=null,j=null;null!==(i=d.nextNode());)if(!(i.nodeType>3))if(3===i.nodeType){if(!g&&c.startc.end+1)throw new Error("PerformLinking overshot the target!");g&&e.push(j||i),f+=i.nodeValue.length,null!==j&&(f+=j.nodeValue.length,d.nextNode()),j=null}else"img"===i.tagName.toLowerCase()&&(!g&&c.start<=f&&(g=!0),g&&e.push(i));return e},splitStartNodeIfNeeded:function(a,b,c){return b!==c?a.splitText(b-c):null},splitEndNodeIfNeeded:function(a,b,c,d){var e,f;e=d+a.nodeValue.length+(b?b.nodeValue.length:0)-1,f=c-d-(b?a.nodeValue.length:0),e>=c&&d!==e&&0!==f&&(b||a).splitText(f)},splitByBlockElements:function(b){if(3!==b.nodeType&&1!==b.nodeType)return[];var c=[],d=a.util.blockContainerElementNames.join(",");if(3===b.nodeType||0===b.querySelectorAll(d).length)return[b];for(var e=0;e0)break;d=f.nextNode()}return d},findPreviousSibling:function(a){if(!a||h.isMediumEditorElement(a))return!1;for(var b=a.previousSibling;!b&&!h.isMediumEditorElement(a.parentNode);)a=a.parentNode,b=a.previousSibling;return b},isDescendant:function(a,b,c){if(!a||!b)return!1;if(a===b)return!!c;if(1!==a.nodeType)return!1;if(d||3!==b.nodeType)return a.contains(b);for(var e=b.parentNode;null!==e;){if(e===a)return!0;e=e.parentNode}return!1},isElement:function(a){return!(!a||1!==a.nodeType)},throttle:function(a,b){var c,d,e,f=50,g=null,h=0,i=function(){h=Date.now(),g=null,e=a.apply(c,d),g||(c=d=null)};return b||0===b||(b=f),function(){var f=Date.now(),j=b-(f-h);return c=this,d=arguments,0>=j||j>b?(g&&(clearTimeout(g),g=null),h=f,e=a.apply(c,d),g||(c=d=null)):g||(g=setTimeout(i,j)),e}},traverseUp:function(a,b){if(!a)return!1;do{if(1===a.nodeType){if(b(a))return a;if(h.isMediumEditorElement(a))return!1}a=a.parentNode}while(a);return!1},htmlEntities:function(a){return String(a).replace(/&/g,"&").replace(//g,">").replace(/"/g,""")},insertHTMLCommand:function(b,c){var d,e,f,g,i,j,k,l=!1,m=["insertHTML",!1,c];if(!a.util.isEdge&&b.queryCommandSupported("insertHTML"))try{return b.execCommand.apply(b,m)}catch(n){}if(d=b.getSelection(),d.rangeCount){if(e=d.getRangeAt(0),k=e.commonAncestorContainer,h.isMediumEditorElement(k)&&!k.firstChild)e.selectNode(k.appendChild(b.createTextNode("")));else if(3===k.nodeType&&0===e.startOffset&&e.endOffset===k.nodeValue.length||3!==k.nodeType&&k.innerHTML===e.toString()){for(;!h.isMediumEditorElement(k)&&k.parentNode&&1===k.parentNode.childNodes.length&&!h.isMediumEditorElement(k.parentNode);)k=k.parentNode;e.selectNode(k)}for(e.deleteContents(),f=b.createElement("div"),f.innerHTML=c,g=b.createDocumentFragment();f.firstChild;)i=f.firstChild,j=g.appendChild(i);e.insertNode(g),j&&(e=e.cloneRange(),e.setStartAfter(j),e.collapse(!0),a.selection.selectRange(b,e)),l=!0}return b.execCommand.callListeners&&b.execCommand.callListeners(m,l),l},execFormatBlock:function(b,c){var d,e=h.getTopBlockContainer(a.selection.getSelectionStart(b));if("blockquote"===c){if(e&&(d=Array.prototype.slice.call(e.childNodes),d.some(function(a){return h.isBlockContainer(a)})))return b.execCommand("outdent",!1,null);if(h.isIE)return b.execCommand("indent",!1,c)}if(e&&c===e.nodeName.toLowerCase()&&(c="p"),h.isIE&&(c="<"+c+">"),e&&"blockquote"===e.nodeName.toLowerCase()){if(h.isIE&&"
    ','','","
    "),this.customClassOption&&a.push('
    ','',"","
    "),a.join("")},isDisplayed:function(){return a.extensions.form.prototype.isDisplayed.apply(this)},hideForm:function(){a.extensions.form.prototype.hideForm.apply(this),this.getInput().value=""},showForm:function(b){var c=this.getInput(),d=this.getAnchorTargetCheckbox(),e=this.getAnchorButtonCheckbox();if(b=b||{value:""},"string"==typeof b&&(b={value:b}),this.base.saveSelection(),this.hideToolbarDefaultActions(),a.extensions.form.prototype.showForm.apply(this),this.setToolbarPosition(),c.value=b.value,c.focus(),d&&(d.checked="_blank"===b.target),e){var f=b.buttonClass?b.buttonClass.split(" "):[];e.checked=-1!==f.indexOf(this.customClassOption)}},destroy:function(){return this.form?(this.form.parentNode&&this.form.parentNode.removeChild(this.form),void delete this.form):!1},getFormOpts:function(){var a=this.getAnchorTargetCheckbox(),b=this.getAnchorButtonCheckbox(),c={value:this.getInput().value.trim()};return this.linkValidation&&(c.value=this.checkLinkFormat(c.value)),c.target="_self",a&&a.checked&&(c.target="_blank"),b&&b.checked&&(c.buttonClass=this.customClassOption),c},doFormSave:function(){var a=this.getFormOpts();this.completeFormSave(a)},completeFormSave:function(a){this.base.restoreSelection(),this.execAction(this.action,a),this.base.checkSelection()},ensureEncodedUri:function(a){return a===decodeURI(a)?encodeURI(a):a},ensureEncodedUriComponent:function(a){return a===decodeURIComponent(a)?encodeURIComponent(a):a},ensureEncodedParam:function(a){var b=a.split("="),c=b[0],d=b[1];return c+(void 0===d?"":"="+this.ensureEncodedUriComponent(d))},ensureEncodedQuery:function(a){return a.split("&").map(this.ensureEncodedParam.bind(this)).join("&")},checkLinkFormat:function(a){var b=/^([a-z]+:)?\/\/|^(mailto|tel|maps):|^\#/i,c=b.test(a),d="",e=/^\+?\s?\(?(?:\d\s?\-?\)?){3,20}$/,f=a.match(/^(.*?)(?:\?(.*?))?(?:#(.*))?$/),g=f[1],h=f[2],i=f[3];if(e.test(a))return"tel:"+a;if(!c){var j=g.split("/")[0];(j.match(/.+(\.|:).+/)||"localhost"===j)&&(d="http://")}return d+this.ensureEncodedUri(g)+(void 0===h?"":"?"+this.ensureEncodedQuery(h))+(void 0===i?"":"#"+i)},doFormCancel:function(){this.base.restoreSelection(),this.base.checkSelection()},attachFormEvents:function(a){var b=a.querySelector(".medium-editor-toolbar-close"),c=a.querySelector(".medium-editor-toolbar-save"),d=a.querySelector(".medium-editor-toolbar-input");this.on(a,"click",this.handleFormClick.bind(this)),this.on(d,"keyup",this.handleTextboxKeyup.bind(this)),this.on(b,"click",this.handleCloseClick.bind(this)),this.on(c,"click",this.handleSaveClick.bind(this),!0)},createForm:function(){var a=this.document,b=a.createElement("div");return b.className="medium-editor-toolbar-form",b.id="medium-editor-toolbar-form-anchor-"+this.getEditorId(),b.innerHTML=this.getTemplate(),this.attachFormEvents(b),b},getInput:function(){return this.getForm().querySelector("input.medium-editor-toolbar-input")},getAnchorTargetCheckbox:function(){return this.getForm().querySelector(".medium-editor-toolbar-anchor-target")},getAnchorButtonCheckbox:function(){return this.getForm().querySelector(".medium-editor-toolbar-anchor-button")},handleTextboxKeyup:function(b){return b.keyCode===a.util.keyCode.ENTER?(b.preventDefault(),void this.doFormSave()):void(b.keyCode===a.util.keyCode.ESCAPE&&(b.preventDefault(),this.doFormCancel()))},handleFormClick:function(a){a.stopPropagation()},handleSaveClick:function(a){a.preventDefault(),this.doFormSave()},handleCloseClick:function(a){a.preventDefault(),this.doFormCancel()}});a.extensions.anchor=b}(),function(){var b=a.Extension.extend({name:"anchor-preview",hideDelay:500,previewValueSelector:"a",showWhenToolbarIsVisible:!1,showOnEmptyLinks:!0,init:function(){this.anchorPreview=this.createPreview(),this.getEditorOption("elementsContainer").appendChild(this.anchorPreview),this.attachToEditables()},getInteractionElements:function(){return this.getPreviewElement()},getPreviewElement:function(){return this.anchorPreview},createPreview:function(){var a=this.document.createElement("div");return a.id="medium-editor-anchor-preview-"+this.getEditorId(),a.className="medium-editor-anchor-preview",a.innerHTML=this.getTemplate(),this.on(a,"click",this.handleClick.bind(this)),a},getTemplate:function(){return'
    '},destroy:function(){this.anchorPreview&&(this.anchorPreview.parentNode&&this.anchorPreview.parentNode.removeChild(this.anchorPreview),delete this.anchorPreview)},hidePreview:function(){this.anchorPreview&&this.anchorPreview.classList.remove("medium-editor-anchor-preview-active"),this.activeAnchor=null},showPreview:function(a){return this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")||a.getAttribute("data-disable-preview")?!0:(this.previewValueSelector&&(this.anchorPreview.querySelector(this.previewValueSelector).textContent=a.attributes.href.value,this.anchorPreview.querySelector(this.previewValueSelector).href=a.attributes.href.value),this.anchorPreview.classList.add("medium-toolbar-arrow-over"),this.anchorPreview.classList.remove("medium-toolbar-arrow-under"),this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")||this.anchorPreview.classList.add("medium-editor-anchor-preview-active"),this.activeAnchor=a,this.positionPreview(),this.attachPreviewHandlers(),this)},positionPreview:function(a){a=a||this.activeAnchor;var b,c,d,e,f,g=this.window.innerWidth,h=this.anchorPreview.offsetHeight,i=a.getBoundingClientRect(),j=this.diffLeft,k=this.diffTop,l=this.getEditorOption("elementsContainer"),m=["absolute","fixed"].indexOf(window.getComputedStyle(l).getPropertyValue("position"))>-1,n={};b=this.anchorPreview.offsetWidth/2;var o=this.base.getExtensionByName("toolbar");o&&(j=o.diffLeft,k=o.diffTop),c=j-b,m?(e=l.getBoundingClientRect(),["top","left"].forEach(function(a){n[a]=i[a]-e[a]}),n.width=i.width,n.height=i.height,i=n,g=e.width,f=l.scrollTop):f=this.window.pageYOffset,d=i.left+i.width/2,f+=h+i.top+i.height-k-this.anchorPreview.offsetHeight,this.anchorPreview.style.top=Math.round(f)+"px",this.anchorPreview.style.right="initial",b>d?(this.anchorPreview.style.left=c+b+"px",this.anchorPreview.style.right="initial"):b>g-d?(this.anchorPreview.style.left="auto",this.anchorPreview.style.right=0):(this.anchorPreview.style.left=c+d+"px",this.anchorPreview.style.right="initial")},attachToEditables:function(){this.subscribe("editableMouseover",this.handleEditableMouseover.bind(this)),this.subscribe("positionedToolbar",this.handlePositionedToolbar.bind(this))},handlePositionedToolbar:function(){this.showWhenToolbarIsVisible||this.hidePreview()},handleClick:function(a){var b=this.base.getExtensionByName("anchor"),c=this.activeAnchor;b&&c&&(a.preventDefault(),this.base.selectElement(this.activeAnchor),this.base.delay(function(){if(c){var a={value:c.attributes.href.value,target:c.getAttribute("target"),buttonClass:c.getAttribute("class")};b.showForm(a),c=null}}.bind(this))),this.hidePreview()},handleAnchorMouseout:function(){this.anchorToPreview=null,this.off(this.activeAnchor,"mouseout",this.instanceHandleAnchorMouseout),this.instanceHandleAnchorMouseout=null},handleEditableMouseover:function(b){var c=a.util.getClosestTag(b.target,"a");if(!1!==c){if(!this.showOnEmptyLinks&&(!/href=["']\S+["']/.test(c.outerHTML)||/href=["']#\S+["']/.test(c.outerHTML)))return!0;var d=this.base.getExtensionByName("toolbar");if(!this.showWhenToolbarIsVisible&&d&&d.isDisplayed&&d.isDisplayed())return!0;this.activeAnchor&&this.activeAnchor!==c&&this.detachPreviewHandlers(),this.anchorToPreview=c,this.instanceHandleAnchorMouseout=this.handleAnchorMouseout.bind(this),this.on(this.anchorToPreview,"mouseout",this.instanceHandleAnchorMouseout),this.base.delay(function(){this.anchorToPreview&&this.showPreview(this.anchorToPreview)}.bind(this))}},handlePreviewMouseover:function(){this.lastOver=(new Date).getTime(),this.hovering=!0},handlePreviewMouseout:function(a){a.relatedTarget&&/anchor-preview/.test(a.relatedTarget.className)||(this.hovering=!1)},updatePreview:function(){if(this.hovering)return!0;var a=(new Date).getTime()-this.lastOver;a>this.hideDelay&&this.detachPreviewHandlers()},detachPreviewHandlers:function(){clearInterval(this.intervalTimer),this.instanceHandlePreviewMouseover&&(this.off(this.anchorPreview,"mouseover",this.instanceHandlePreviewMouseover),this.off(this.anchorPreview,"mouseout",this.instanceHandlePreviewMouseout),this.activeAnchor&&(this.off(this.activeAnchor,"mouseover",this.instanceHandlePreviewMouseover),this.off(this.activeAnchor,"mouseout",this.instanceHandlePreviewMouseout))),this.hidePreview(),this.hovering=this.instanceHandlePreviewMouseover=this.instanceHandlePreviewMouseout=null},attachPreviewHandlers:function(){this.lastOver=(new Date).getTime(),this.hovering=!0,this.instanceHandlePreviewMouseover=this.handlePreviewMouseover.bind(this),this.instanceHandlePreviewMouseout=this.handlePreviewMouseout.bind(this),this.intervalTimer=setInterval(this.updatePreview.bind(this),200),this.on(this.anchorPreview,"mouseover",this.instanceHandlePreviewMouseover),this.on(this.anchorPreview,"mouseout",this.instanceHandlePreviewMouseout),this.on(this.activeAnchor,"mouseover",this.instanceHandlePreviewMouseover),this.on(this.activeAnchor,"mouseout",this.instanceHandlePreviewMouseout)}});a.extensions.anchorPreview=b}(),function(){function b(b){return!a.util.getClosestTag(b,"a")}var c,d,e,f,g;c=[" "," ","\n","\r"," "," "," "," "," ","\u2028","\u2029"],d="com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw",e="(((?:(https?://|ftps?://|nntp://)|www\\d{0,3}[.]|[a-z0-9.\\-]+[.]("+d+")\\/)\\S+(?:[^\\s`!\\[\\]{};:'\".,?«»“”‘’])))|(([a-z0-9\\-]+\\.)?[a-z0-9\\-]+\\.("+d+"))",f=new RegExp("^("+d+")$","i"),g=new RegExp(e,"gi");var h=a.Extension.extend({init:function(){a.Extension.prototype.init.apply(this,arguments),this.disableEventHandling=!1,this.subscribe("editableKeypress",this.onKeypress.bind(this)),this.subscribe("editableBlur",this.onBlur.bind(this)),this.document.execCommand("AutoUrlDetect",!1,!1)},isLastInstance:function(){for(var a=0,b=0;b0&&null!==g;)e=c.currentNode,f=e.nodeValue,f.length>b?(g=e.splitText(f.length-b),b=0):(g=c.previousNode(),b-=f.length);return g},performLinkingWithinElement:function(b){for(var c=this.findLinkableText(b),d=!1,e=0;e1;)e.appendChild(d.childNodes[1])}});a.extensions.autoLink=h}(),function(){function b(b){var d=a.util.getContainerEditorElement(b),e=Array.prototype.slice.call(d.parentElement.querySelectorAll("."+c));e.forEach(function(a){a.classList.remove(c)})}var c="medium-editor-dragover",d=a.Extension.extend({name:"fileDragging",allowedTypes:["image"],init:function(){a.Extension.prototype.init.apply(this,arguments),this.subscribe("editableDrag",this.handleDrag.bind(this)),this.subscribe("editableDrop",this.handleDrop.bind(this))},handleDrag:function(a){a.preventDefault(),a.dataTransfer.dropEffect="copy";var d=a.target.classList?a.target:a.target.parentElement;b(d),"dragover"===a.type&&d.classList.add(c)},handleDrop:function(a){a.preventDefault(),a.stopPropagation(),this.base.selectElement(a.target);var c=this.base.exportSelection();c.start=c.end,this.base.importSelection(c),a.dataTransfer.files&&Array.prototype.slice.call(a.dataTransfer.files).forEach(function(a){this.isAllowedFile(a)&&a.type.match("image")&&this.insertImageFile(a)},this),b(a.target)},isAllowedFile:function(a){return this.allowedTypes.some(function(b){return!!a.type.match(b)})},insertImageFile:function(b){if("function"==typeof FileReader){var c=new FileReader;c.readAsDataURL(b),c.addEventListener("load",function(b){var c=this.document.createElement("img");c.src=b.target.result,a.util.insertHTMLCommand(this.document,c.outerHTML)}.bind(this))}}});a.extensions.fileDragging=d}(),function(){var b=a.Extension.extend({name:"keyboard-commands",commands:[{command:"bold",key:"B",meta:!0,shift:!1,alt:!1},{command:"italic",key:"I",meta:!0,shift:!1,alt:!1},{command:"underline",key:"U",meta:!0,shift:!1,alt:!1}],init:function(){a.Extension.prototype.init.apply(this,arguments),this.subscribe("editableKeydown",this.handleKeydown.bind(this)),this.keys={},this.commands.forEach(function(a){var b=a.key.charCodeAt(0);this.keys[b]||(this.keys[b]=[]),this.keys[b].push(a)},this)},handleKeydown:function(b){var c=a.util.getKeyCode(b);if(this.keys[c]){var d=a.util.isMetaCtrlKey(b),e=!!b.shiftKey,f=!!b.altKey;this.keys[c].forEach(function(a){a.meta!==d||a.shift!==e||a.alt!==f&&void 0!==a.alt||(b.preventDefault(),b.stopPropagation(),"function"==typeof a.command?a.command.apply(this):!1!==a.command&&this.execAction(a.command))},this)}}});a.extensions.keyboardCommands=b}(),function(){var b=a.extensions.form.extend({name:"fontname",action:"fontName",aria:"change font name",contentDefault:"±",contentFA:'',fonts:["","Arial","Verdana","Times New Roman"],init:function(){a.extensions.form.prototype.init.apply(this,arguments)},handleClick:function(a){if(a.preventDefault(),a.stopPropagation(),!this.isDisplayed()){var b=this.document.queryCommandValue("fontName")+"";this.showForm(b)}return!1},getForm:function(){return this.form||(this.form=this.createForm()),this.form},isDisplayed:function(){return"block"===this.getForm().style.display},hideForm:function(){this.getForm().style.display="none",this.getSelect().value=""},showForm:function(a){var b=this.getSelect();this.base.saveSelection(),this.hideToolbarDefaultActions(),this.getForm().style.display="block",this.setToolbarPosition(),b.value=a||"",b.focus()},destroy:function(){return this.form?(this.form.parentNode&&this.form.parentNode.removeChild(this.form),void delete this.form):!1},doFormSave:function(){this.base.restoreSelection(),this.base.checkSelection()},doFormCancel:function(){this.base.restoreSelection(),this.clearFontName(),this.base.checkSelection()},createForm:function(){var a,b=this.document,c=b.createElement("div"),d=b.createElement("select"),e=b.createElement("a"),f=b.createElement("a");c.className="medium-editor-toolbar-form",c.id="medium-editor-toolbar-form-fontname-"+this.getEditorId(),this.on(c,"click",this.handleFormClick.bind(this));for(var g=0;g
    ':"✓",c.appendChild(f),this.on(f,"click",this.handleSaveClick.bind(this),!0),e.setAttribute("href","#"),e.className="medium-editor-toobar-close",e.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"×",c.appendChild(e),this.on(e,"click",this.handleCloseClick.bind(this)),c},getSelect:function(){return this.getForm().querySelector("select.medium-editor-toolbar-select")},clearFontName:function(){a.selection.getSelectedElements(this.document).forEach(function(a){"font"===a.nodeName.toLowerCase()&&a.hasAttribute("face")&&a.removeAttribute("face")})},handleFontChange:function(){var a=this.getSelect().value;""===a?this.clearFontName():this.execAction("fontName",{value:a})},handleFormClick:function(a){a.stopPropagation()},handleSaveClick:function(a){a.preventDefault(),this.doFormSave()},handleCloseClick:function(a){a.preventDefault(),this.doFormCancel()}});a.extensions.fontName=b}(),function(){var b=a.extensions.form.extend({name:"fontsize",action:"fontSize",aria:"increase/decrease font size",contentDefault:"±",contentFA:'',init:function(){a.extensions.form.prototype.init.apply(this,arguments)},handleClick:function(a){if(a.preventDefault(),a.stopPropagation(),!this.isDisplayed()){var b=this.document.queryCommandValue("fontSize")+"";this.showForm(b)}return!1},getForm:function(){return this.form||(this.form=this.createForm()),this.form},isDisplayed:function(){return"block"===this.getForm().style.display},hideForm:function(){this.getForm().style.display="none",this.getInput().value=""},showForm:function(a){var b=this.getInput();this.base.saveSelection(),this.hideToolbarDefaultActions(),this.getForm().style.display="block",this.setToolbarPosition(),b.value=a||"",b.focus()},destroy:function(){return this.form?(this.form.parentNode&&this.form.parentNode.removeChild(this.form),void delete this.form):!1},doFormSave:function(){this.base.restoreSelection(),this.base.checkSelection()},doFormCancel:function(){this.base.restoreSelection(),this.clearFontSize(),this.base.checkSelection()},createForm:function(){var a=this.document,b=a.createElement("div"),c=a.createElement("input"),d=a.createElement("a"),e=a.createElement("a");return b.className="medium-editor-toolbar-form",b.id="medium-editor-toolbar-form-fontsize-"+this.getEditorId(),this.on(b,"click",this.handleFormClick.bind(this)),c.setAttribute("type","range"),c.setAttribute("min","1"), -c.setAttribute("max","7"),c.className="medium-editor-toolbar-input",b.appendChild(c),this.on(c,"change",this.handleSliderChange.bind(this)),e.setAttribute("href","#"),e.className="medium-editor-toobar-save",e.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"✓",b.appendChild(e),this.on(e,"click",this.handleSaveClick.bind(this),!0),d.setAttribute("href","#"),d.className="medium-editor-toobar-close",d.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"×",b.appendChild(d),this.on(d,"click",this.handleCloseClick.bind(this)),b},getInput:function(){return this.getForm().querySelector("input.medium-editor-toolbar-input")},clearFontSize:function(){a.selection.getSelectedElements(this.document).forEach(function(a){"font"===a.nodeName.toLowerCase()&&a.hasAttribute("size")&&a.removeAttribute("size")})},handleSliderChange:function(){var a=this.getInput().value;"4"===a?this.clearFontSize():this.execAction("fontSize",{value:a})},handleFormClick:function(a){a.stopPropagation()},handleSaveClick:function(a){a.preventDefault(),this.doFormSave()},handleCloseClick:function(a){a.preventDefault(),this.doFormCancel()}});a.extensions.fontSize=b}(),function(){function b(){return[[new RegExp(/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g),""],[new RegExp(/|/g),""],[new RegExp(/
    $/i),""],[new RegExp(/<[^>]*docs-internal-guid[^>]*>/gi),""],[new RegExp(/<\/b>(]*>)?$/gi),""],[new RegExp(/\s+<\/span>/g)," "],[new RegExp(/
    /g),"
    "],[new RegExp(/]*(font-style:italic;font-weight:(bold|700)|font-weight:(bold|700);font-style:italic)[^>]*>/gi),''],[new RegExp(/]*font-style:italic[^>]*>/gi),''],[new RegExp(/]*font-weight:(bold|700)[^>]*>/gi),''],[new RegExp(/<(\/?)(i|b|a)>/gi),"<$1$2>"],[new RegExp(/<a(?:(?!href).)+href=(?:"|”|“|"|“|”)(((?!"|”|“|"|“|”).)*)(?:"|”|“|"|“|”)(?:(?!>).)*>/gi),''],[new RegExp(/<\/p>\n+/gi),"

    "],[new RegExp(/\n+

    /gi),""],[new RegExp(/(((?!/gi),"$1"]]}function c(a,b,c){var d=a.clipboardData||b.clipboardData||c.dataTransfer,e={};if(!d)return e;if(d.getData){var f=d.getData("Text");f&&f.length>0&&(e["text/plain"]=f)}if(d.types)for(var g=0;g1)for(f=0;f"+a.util.htmlEntities(e[f])+"

    ");else g=a.util.htmlEntities(e[0]);a.util.insertHTMLCommand(this.document,g)}},handlePasteBinPaste:function(a){if(a.defaultPrevented)return void this.removePasteBin();var b=c(a,this.window,this.document),d=b["text/html"],e=b["text/plain"],g=f;return!this.cleanPastedHTML||d?(a.preventDefault(),this.removePasteBin(),this.doPaste(d,e,g),void this.trigger("editablePaste",{currentTarget:g,target:g},g)):void setTimeout(function(){this.cleanPastedHTML&&(d=this.getPasteBinHtml()),this.removePasteBin(),this.doPaste(d,e,g),this.trigger("editablePaste",{currentTarget:g,target:g},g)}.bind(this),0)},handleKeydown:function(b,c){a.util.isKey(b,a.util.keyCode.V)&&a.util.isMetaCtrlKey(b)&&(b.stopImmediatePropagation(),this.removePasteBin(),this.createPasteBin(c))},createPasteBin:function(b){var c,h=a.selection.getSelectionRange(this.document),i=this.window.pageYOffset;f=b,h&&(c=h.getClientRects(),i+=c.length?c[0].top:void 0!==h.startContainer.getBoundingClientRect?h.startContainer.getBoundingClientRect().top:h.getBoundingClientRect().top),e=h;var j=this.document.createElement("div");j.id=this.pasteBinId="medium-editor-pastebin-"+ +Date.now(),j.setAttribute("style","border: 1px red solid; position: absolute; top: "+i+"px; width: 10px; height: 10px; overflow: hidden; opacity: 0"),j.setAttribute("contentEditable",!0),j.innerHTML=d,this.document.body.appendChild(j),this.on(j,"focus",g),this.on(j,"focusin",g),this.on(j,"focusout",g),j.focus(),a.selection.selectNode(j,this.document),this.boundHandlePaste||(this.boundHandlePaste=this.handlePasteBinPaste.bind(this)),this.on(j,"paste",this.boundHandlePaste)},removePasteBin:function(){null!==e&&(a.selection.selectRange(this.document,e),e=null),null!==f&&(f=null);var b=this.getPasteBin();b&&b&&(this.off(b,"focus",g),this.off(b,"focusin",g),this.off(b,"focusout",g),this.off(b,"paste",this.boundHandlePaste),b.parentElement.removeChild(b))},getPasteBin:function(){return this.document.getElementById(this.pasteBinId)},getPasteBinHtml:function(){var a=this.getPasteBin();if(!a)return!1;if(a.firstChild&&"mcepastebin"===a.firstChild.id)return!1;var b=a.innerHTML;return b&&b!==d?b:!1},cleanPaste:function(a){var c,d,e,f,g=/"+a.split("

    ").join("

    ")+"

    ",d=e.querySelectorAll("a,p,div,br"),c=0;c"+d.innerHTML+"
    ":e.innerHTML=d.innerHTML,d.parentNode.replaceChild(e,d);for(f=b.querySelectorAll("span"),c=0;c0&&(d[0].classList.add(this.firstButtonClass),d[d.length-1].classList.add(this.lastButtonClass)),h},destroy:function(){this.toolbar&&(this.toolbar.parentNode&&this.toolbar.parentNode.removeChild(this.toolbar),delete this.toolbar)},getInteractionElements:function(){return this.getToolbarElement()},getToolbarElement:function(){return this.toolbar||(this.toolbar=this.createToolbar()),this.toolbar},getToolbarActionsElement:function(){return this.getToolbarElement().querySelector(".medium-editor-toolbar-actions")},initThrottledMethods:function(){this.throttledPositionToolbar=a.util.throttle(function(){this.base.isActive&&this.positionToolbarIfShown()}.bind(this))},attachEventHandlers:function(){this.subscribe("blur",this.handleBlur.bind(this)),this.subscribe("focus",this.handleFocus.bind(this)),this.subscribe("editableClick",this.handleEditableClick.bind(this)),this.subscribe("editableKeyup",this.handleEditableKeyup.bind(this)),this.on(this.document.documentElement,"mouseup",this.handleDocumentMouseup.bind(this)),this["static"]&&this.sticky&&this.on(this.window,"scroll",this.handleWindowScroll.bind(this),!0),this.on(this.window,"resize",this.handleWindowResize.bind(this))},handleWindowScroll:function(){this.positionToolbarIfShown()},handleWindowResize:function(){this.throttledPositionToolbar()},handleDocumentMouseup:function(b){return b&&b.target&&a.util.isDescendant(this.getToolbarElement(),b.target)?!1:void this.checkState()},handleEditableClick:function(){setTimeout(function(){this.checkState()}.bind(this),0)},handleEditableKeyup:function(){this.checkState()},handleBlur:function(){clearTimeout(this.hideTimeout),clearTimeout(this.delayShowTimeout),this.hideTimeout=setTimeout(function(){this.hideToolbar()}.bind(this),1)},handleFocus:function(){this.checkState()},isDisplayed:function(){return this.getToolbarElement().classList.contains("medium-editor-toolbar-active")},showToolbar:function(){clearTimeout(this.hideTimeout),this.isDisplayed()||(this.getToolbarElement().classList.add("medium-editor-toolbar-active"),this.trigger("showToolbar",{},this.base.getFocusedElement()))},hideToolbar:function(){this.isDisplayed()&&(this.getToolbarElement().classList.remove("medium-editor-toolbar-active"),this.trigger("hideToolbar",{},this.base.getFocusedElement()))},isToolbarDefaultActionsDisplayed:function(){return"block"===this.getToolbarActionsElement().style.display},hideToolbarDefaultActions:function(){this.isToolbarDefaultActionsDisplayed()&&(this.getToolbarActionsElement().style.display="none")},showToolbarDefaultActions:function(){this.hideExtensionForms(),this.isToolbarDefaultActionsDisplayed()||(this.getToolbarActionsElement().style.display="block"),this.delayShowTimeout=this.base.delay(function(){this.showToolbar()}.bind(this))},hideExtensionForms:function(){this.forEachExtension(function(a){a.hasForm&&a.isDisplayed()&&a.hideForm()})},multipleBlockElementsSelected:function(){var b=/<[^\/>][^>]*><\/[^>]+>/gim,c=new RegExp("<("+a.util.blockContainerElementNames.join("|")+")[^>]*>","g"),d=a.selection.getSelectionHtml(this.document).replace(b,""),e=d.match(c);return!!e&&e.length>1},modifySelection:function(){var b=this.window.getSelection(),c=b.getRangeAt(0);if(this.standardizeSelectionStart&&c.startContainer.nodeValue&&c.startOffset===c.startContainer.nodeValue.length){var d=a.util.findAdjacentTextNodeWithContent(a.selection.getSelectionElement(this.window),c.startContainer,this.document);if(d){for(var e=0;0===d.nodeValue.substr(e,1).trim().length;)e+=1;c=a.selection.select(this.document,d,e,c.endContainer,c.endOffset)}}},checkState:function(){if(!this.base.preventSelectionUpdates){if(!this.base.getFocusedElement()||a.selection.selectionInContentEditableFalse(this.window))return this.hideToolbar();var b=a.selection.getSelectionElement(this.window);return!b||-1===this.getEditorElements().indexOf(b)||b.getAttribute("data-disable-toolbar")?this.hideToolbar():this.updateOnEmptySelection&&this["static"]?this.showAndUpdateToolbar():!a.selection.selectionContainsContent(this.document)||this.allowMultiParagraphSelection===!1&&this.multipleBlockElementsSelected()?this.hideToolbar():void this.showAndUpdateToolbar()}},showAndUpdateToolbar:function(){this.modifySelection(),this.setToolbarButtonStates(),this.trigger("positionToolbar",{},this.base.getFocusedElement()),this.showToolbarDefaultActions(),this.setToolbarPosition()},setToolbarButtonStates:function(){this.forEachExtension(function(a){"function"==typeof a.isActive&&"function"==typeof a.setInactive&&a.setInactive()}),this.checkActiveButtons()},checkActiveButtons:function(){var b,c=[],d=null,e=a.selection.getSelectionRange(this.document),f=function(a){"function"==typeof a.checkState?a.checkState(b):"function"==typeof a.isActive&&"function"==typeof a.isAlreadyApplied&&"function"==typeof a.setActive&&!a.isActive()&&a.isAlreadyApplied(b)&&a.setActive()};if(e&&(this.forEachExtension(function(a){return"function"==typeof a.queryCommandState&&(d=a.queryCommandState(),null!==d)?void(d&&"function"==typeof a.setActive&&a.setActive()):void c.push(a)}),b=a.selection.getSelectedParentElement(e),this.getEditorElements().some(function(c){return a.util.isDescendant(c,b,!0)})))for(;b&&(c.forEach(f),!a.util.isMediumEditorElement(b));)b=b.parentNode},positionToolbarIfShown:function(){this.isDisplayed()&&this.setToolbarPosition()},setToolbarPosition:function(){var a=this.base.getFocusedElement(),b=this.window.getSelection();return a?void(!this["static"]&&b.isCollapsed||(this.showToolbar(),this.relativeContainer||(this["static"]?this.positionStaticToolbar(a):this.positionToolbar(b)),this.trigger("positionedToolbar",{},this.base.getFocusedElement()))):this},positionStaticToolbar:function(a){this.getToolbarElement().style.left="0";var b,c=this.document.documentElement&&this.document.documentElement.scrollTop||this.document.body.scrollTop,d=this.window.innerWidth,e=this.getToolbarElement(),f=a.getBoundingClientRect(),g=f.top+c,h=f.left+f.width/2,i=e.offsetHeight,j=e.offsetWidth,k=j/2;switch(this.sticky?c>g+a.offsetHeight-i-this.stickyTopOffset?(e.style.top=g+a.offsetHeight-i+"px",e.classList.remove("medium-editor-sticky-toolbar")):c>g-i-this.stickyTopOffset?(e.classList.add("medium-editor-sticky-toolbar"),e.style.top=this.stickyTopOffset+"px"):(e.classList.remove("medium-editor-sticky-toolbar"),e.style.top=g-i+"px"):e.style.top=g-i+"px",this.align){case"left":b=f.left;break;case"right":b=f.right-j;break;case"center":b=h-k}0>b?b=0:b+j>d&&(b=d-Math.ceil(j)-1),e.style.left=b+"px"},positionToolbar:function(a){this.getToolbarElement().style.left="0",this.getToolbarElement().style.right="initial";var b=a.getRangeAt(0),c=b.getBoundingClientRect();(!c||0===c.height&&0===c.width&&b.startContainer===b.endContainer)&&(c=1===b.startContainer.nodeType&&b.startContainer.querySelector("img")?b.startContainer.querySelector("img").getBoundingClientRect():b.startContainer.getBoundingClientRect());var d,e,f=this.window.innerWidth,g=this.getToolbarElement(),h=g.offsetHeight,i=g.offsetWidth,j=i/2,k=50,l=this.diffLeft-j,m=this.getEditorOption("elementsContainer"),n=["absolute","fixed"].indexOf(window.getComputedStyle(m).getPropertyValue("position"))>-1,o={},p={};n?(e=m.getBoundingClientRect(),["top","left"].forEach(function(a){p[a]=c[a]-e[a]}),p.width=c.width,p.height=c.height,c=p,f=e.width,o.top=m.scrollTop):o.top=this.window.pageYOffset,d=c.left+c.width/2,o.top+=c.top-h,c.topd?(o.left=l+j,o.right="initial"):j>f-d?(o.left="auto",o.right=0):(o.left=l+d,o.right="initial"),["top","left","right"].forEach(function(a){g.style[a]=o[a]+(isNaN(o[a])?"":"px")})}});a.extensions.toolbar=b}(),function(){var b=a.Extension.extend({init:function(){a.Extension.prototype.init.apply(this,arguments),this.subscribe("editableDrag",this.handleDrag.bind(this)),this.subscribe("editableDrop",this.handleDrop.bind(this))},handleDrag:function(a){var b="medium-editor-dragover";a.preventDefault(),a.dataTransfer.dropEffect="copy","dragover"===a.type?a.target.classList.add(b):"dragleave"===a.type&&a.target.classList.remove(b)},handleDrop:function(b){var c,d="medium-editor-dragover";b.preventDefault(),b.stopPropagation(),b.dataTransfer.files&&(c=Array.prototype.slice.call(b.dataTransfer.files,0),c.some(function(b){if(b.type.match("image")){var c,d;c=new FileReader,c.readAsDataURL(b),d="medium-img-"+ +new Date,a.util.insertHTMLCommand(this.document,''),c.onload=function(){var a=this.document.getElementById(d);a&&(a.removeAttribute("id"),a.removeAttribute("class"),a.src=c.result)}.bind(this)}}.bind(this))),b.target.classList.remove(d)}});a.extensions.imageDragging=b}(),function(){function b(b){var c=a.selection.getSelectionStart(this.options.ownerDocument),d=c.textContent,e=a.selection.getCaretOffsets(c);(void 0===d[e.left-1]||""===d[e.left-1].trim()||void 0!==d[e.left]&&""===d[e.left].trim())&&b.preventDefault()}function c(b,c){if(this.options.disableReturn||c.getAttribute("data-disable-return"))b.preventDefault();else if(this.options.disableDoubleReturn||c.getAttribute("data-disable-double-return")){var d=a.selection.getSelectionStart(this.options.ownerDocument);(d&&""===d.textContent.trim()&&"li"!==d.nodeName.toLowerCase()||d.previousElementSibling&&"br"!==d.previousElementSibling.nodeName.toLowerCase()&&""===d.previousElementSibling.textContent.trim())&&b.preventDefault()}}function d(b){var c=a.selection.getSelectionStart(this.options.ownerDocument),d=c&&c.nodeName.toLowerCase();"pre"===d&&(b.preventDefault(),a.util.insertHTMLCommand(this.options.ownerDocument," ")),a.util.isListItem(c)&&(b.preventDefault(),b.shiftKey?this.options.ownerDocument.execCommand("outdent",!1,null):this.options.ownerDocument.execCommand("indent",!1,null))}function e(b){var c,d=a.selection.getSelectionStart(this.options.ownerDocument),e=d.nodeName.toLowerCase(),f=/^(\s+|)?$/i,g=/h\d/i;a.util.isKey(b,[a.util.keyCode.BACKSPACE,a.util.keyCode.ENTER])&&d.previousElementSibling&&g.test(e)&&0===a.selection.getCaretOffsets(d).left?a.util.isKey(b,a.util.keyCode.BACKSPACE)&&f.test(d.previousElementSibling.innerHTML)?(d.previousElementSibling.parentNode.removeChild(d.previousElementSibling),b.preventDefault()):!this.options.disableDoubleReturn&&a.util.isKey(b,a.util.keyCode.ENTER)&&(c=this.options.ownerDocument.createElement("p"),c.innerHTML="
    ",d.previousElementSibling.parentNode.insertBefore(c,d),b.preventDefault()):a.util.isKey(b,a.util.keyCode.DELETE)&&d.nextElementSibling&&d.previousElementSibling&&!g.test(e)&&f.test(d.innerHTML)&&g.test(d.nextElementSibling.nodeName.toLowerCase())?(a.selection.moveCursor(this.options.ownerDocument,d.nextElementSibling),d.previousElementSibling.parentNode.removeChild(d),b.preventDefault()):a.util.isKey(b,a.util.keyCode.BACKSPACE)&&"li"===e&&f.test(d.innerHTML)&&!d.previousElementSibling&&!d.parentElement.previousElementSibling&&d.nextElementSibling&&"li"===d.nextElementSibling.nodeName.toLowerCase()?(c=this.options.ownerDocument.createElement("p"),c.innerHTML="
    ",d.parentElement.parentElement.insertBefore(c,d.parentElement),a.selection.moveCursor(this.options.ownerDocument,c),d.parentElement.removeChild(d),b.preventDefault()):a.util.isKey(b,a.util.keyCode.BACKSPACE)&&a.util.getClosestTag(d,"blockquote")!==!1&&0===a.selection.getCaretOffsets(d).left?(b.preventDefault(),a.util.execFormatBlock(this.options.ownerDocument,"p")):a.util.isKey(b,a.util.keyCode.ENTER)&&a.util.getClosestTag(d,"blockquote")!==!1&&0===a.selection.getCaretOffsets(d).right?(c=this.options.ownerDocument.createElement("p"),c.innerHTML="
    ",d.parentElement.insertBefore(c,d.nextSibling),a.selection.moveCursor(this.options.ownerDocument,c),b.preventDefault()):a.util.isKey(b,a.util.keyCode.BACKSPACE)&&a.util.isMediumEditorElement(d.parentElement)&&!d.previousElementSibling&&d.nextElementSibling&&f.test(d.innerHTML)&&(b.preventDefault(),a.selection.moveCursor(this.options.ownerDocument,d.nextSibling),d.parentElement.removeChild(d))}function f(b){var c,d=a.selection.getSelectionStart(this.options.ownerDocument);d&&(a.util.isMediumEditorElement(d)&&0===d.children.length&&!a.util.isBlockContainer(d)&&this.options.ownerDocument.execCommand("formatBlock",!1,"p"),!a.util.isKey(b,a.util.keyCode.ENTER)||a.util.isListItem(d)||a.util.isBlockContainer(d)||(c=d.nodeName.toLowerCase(),"a"===c?this.options.ownerDocument.execCommand("unlink",!1,null):b.shiftKey||b.ctrlKey||this.options.ownerDocument.execCommand("formatBlock",!1,"p")))}function g(a,b){var c=b.parentNode.querySelector('textarea[medium-editor-textarea-id="'+b.getAttribute("medium-editor-textarea-id")+'"]');c&&(c.value=b.innerHTML.trim())}function h(a){a._mediumEditors||(a._mediumEditors=[null]),this.id||(this.id=a._mediumEditors.length),a._mediumEditors[this.id]=this}function i(a){a._mediumEditors&&a._mediumEditors[this.id]&&(a._mediumEditors[this.id]=null)}function j(b,c,d){var e=[];if(b||(b=[]),"string"==typeof b&&(b=c.querySelectorAll(b)),a.util.isElement(b)&&(b=[b]),d)for(var f=0;ff;f++)b.hasAttribute(e[f].nodeName)||b.setAttribute(e[f].nodeName,e[f].value);return a.form&&this.on(a.form,"reset",function(a){a.defaultPrevented||this.resetContent(this.options.ownerDocument.getElementById(d))}.bind(this)),a.classList.add("medium-editor-hidden"),a.parentNode.insertBefore(b,a),b}function v(b,d){if(!b.getAttribute("data-medium-editor-element")){"textarea"===b.nodeName.toLowerCase()&&(b=u.call(this,b),this.instanceHandleEditableInput||(this.instanceHandleEditableInput=g.bind(this),this.subscribe("editableInput",this.instanceHandleEditableInput))),this.options.disableEditing||b.getAttribute("data-disable-editing")||(b.setAttribute("contentEditable",!0),b.setAttribute("spellcheck",this.options.spellcheck)),this.instanceHandleEditableKeydownEnter||(b.getAttribute("data-disable-return")||b.getAttribute("data-disable-double-return"))&&(this.instanceHandleEditableKeydownEnter=c.bind(this),this.subscribe("editableKeydownEnter",this.instanceHandleEditableKeydownEnter)),this.options.disableReturn||b.getAttribute("data-disable-return")||this.on(b,"keyup",f.bind(this));var e=a.util.guid();b.setAttribute("data-medium-editor-element",!0),b.classList.add("medium-editor-element"),b.setAttribute("role","textbox"),b.setAttribute("aria-multiline",!0),b.setAttribute("data-medium-editor-editor-index",d),b.setAttribute("medium-editor-index",e),B[e]=b.innerHTML,this.events.attachAllEventsToElement(b)}return b}function w(){this.subscribe("editableKeydownTab",d.bind(this)),this.subscribe("editableKeydownDelete",e.bind(this)),this.subscribe("editableKeydownEnter",e.bind(this)),this.options.disableExtraSpaces&&this.subscribe("editableKeydownSpace",b.bind(this)),this.instanceHandleEditableKeydownEnter||(this.options.disableReturn||this.options.disableDoubleReturn)&&(this.instanceHandleEditableKeydownEnter=c.bind(this),this.subscribe("editableKeydownEnter",this.instanceHandleEditableKeydownEnter))}function x(){if(this.extensions=[],Object.keys(this.options.extensions).forEach(function(a){"toolbar"!==a&&this.options.extensions[a]&&this.extensions.push(m(this.options.extensions[a],a,this))},this),t.call(this)){var b=this.options.fileDragging;b||(b={},r.call(this)||(b.allowedTypes=[])),this.addBuiltInExtension("fileDragging",b)}var c={paste:!0,"anchor-preview":o.call(this),autoLink:q.call(this),keyboardCommands:s.call(this),placeholder:p.call(this)};Object.keys(c).forEach(function(a){c[a]&&this.addBuiltInExtension(a)},this);var d=this.options.extensions.toolbar;if(!d&&n.call(this)){var e=a.util.extend({},this.options.toolbar,{allowMultiParagraphSelection:this.options.allowMultiParagraphSelection});d=new a.extensions.toolbar(e)}d&&this.extensions.push(m(d,"toolbar",this))}function y(b,c){var d=[["allowMultiParagraphSelection","toolbar.allowMultiParagraphSelection"]];return c&&d.forEach(function(b){c.hasOwnProperty(b[0])&&void 0!==c[b[0]]&&a.util.deprecated(b[0],b[1],"v6.0.0")}),a.util.defaults({},c,b)}function z(b,c){var d,e,f=/^append-(.+)$/gi,g=/justify([A-Za-z]*)$/g;if(d=f.exec(b))return a.util.execFormatBlock(this.options.ownerDocument,d[1]);if("fontSize"===b)return c.size&&a.util.deprecated(".size option for fontSize command",".value","6.0.0"),e=c.value||c.size,this.options.ownerDocument.execCommand("fontSize",!1,e);if("fontName"===b)return c.name&&a.util.deprecated(".name option for fontName command",".value","6.0.0"),e=c.value||c.name,this.options.ownerDocument.execCommand("fontName",!1,e);if("createLink"===b)return this.createLink(c);if("image"===b){var h=this.options.contentWindow.getSelection().toString().trim();return this.options.ownerDocument.execCommand("insertImage",!1,h)}if("html"===b){var i=this.options.contentWindow.getSelection().toString().trim();return a.util.insertHTMLCommand(this.options.ownerDocument,i)}if(g.exec(b)){var j=this.options.ownerDocument.execCommand(b,!1,null),k=a.selection.getSelectedParentElement(a.selection.getSelectionRange(this.options.ownerDocument));return k&&A.call(this,a.util.getTopBlockContainer(k)),j}return e=c&&c.value,this.options.ownerDocument.execCommand(b,!1,e)}function A(b){if(b){var c,d=Array.prototype.slice.call(b.childNodes).filter(function(a){var b="div"===a.nodeName.toLowerCase();return b&&!c&&(c=a.style.textAlign),b});d.length&&(this.saveSelection(),d.forEach(function(b){if(b.style.textAlign===c){var d=b.lastChild;if(d){a.util.unwrap(b,this.options.ownerDocument);var e=this.options.ownerDocument.createElement("BR");d.parentNode.insertBefore(e,d.nextSibling)}}},this),b.style.textAlign=c,this.restoreSelection())}}var B={};a.prototype={init:function(a,b){return this.options=y.call(this,this.defaults,b),this.origElements=a,this.options.elementsContainer||(this.options.elementsContainer=this.options.ownerDocument.body),this.setup()},setup:function(){this.isActive||(h.call(this,this.options.contentWindow),this.events=new a.Events(this),this.elements=[],this.addElements(this.origElements),0!==this.elements.length&&(this.isActive=!0,x.call(this),w.call(this))); -},destroy:function(){this.isActive&&(this.isActive=!1,this.extensions.forEach(function(a){"function"==typeof a.destroy&&a.destroy()},this),this.events.destroy(),this.elements.forEach(function(a){this.options.spellcheck&&(a.innerHTML=a.innerHTML),a.removeAttribute("contentEditable"),a.removeAttribute("spellcheck"),a.removeAttribute("data-medium-editor-element"),a.classList.remove("medium-editor-element"),a.removeAttribute("role"),a.removeAttribute("aria-multiline"),a.removeAttribute("medium-editor-index"),a.removeAttribute("data-medium-editor-editor-index"),a.getAttribute("medium-editor-textarea-id")&&k(a)},this),this.elements=[],this.instanceHandleEditableKeydownEnter=null,this.instanceHandleEditableInput=null,i.call(this,this.options.contentWindow))},on:function(a,b,c,d){return this.events.attachDOMEvent(a,b,c,d),this},off:function(a,b,c,d){return this.events.detachDOMEvent(a,b,c,d),this},subscribe:function(a,b){return this.events.attachCustomEvent(a,b),this},unsubscribe:function(a,b){return this.events.detachCustomEvent(a,b),this},trigger:function(a,b,c){return this.events.triggerCustomEvent(a,b,c),this},delay:function(a){var b=this;return setTimeout(function(){b.isActive&&a()},this.options.delay)},serialize:function(){var a,b,c={},d=this.elements.length;for(a=0;d>a;a+=1)b=""!==this.elements[a].id?this.elements[a].id:"element-"+a,c[b]={value:this.elements[a].innerHTML.trim()};return c},getExtensionByName:function(a){var b;return this.extensions&&this.extensions.length&&this.extensions.some(function(c){return c.name===a?(b=c,!0):!1}),b},addBuiltInExtension:function(b,c){var d,e=this.getExtensionByName(b);if(e)return e;switch(b){case"anchor":d=a.util.extend({},this.options.anchor,c),e=new a.extensions.anchor(d);break;case"anchor-preview":e=new a.extensions.anchorPreview(this.options.anchorPreview);break;case"autoLink":e=new a.extensions.autoLink;break;case"fileDragging":e=new a.extensions.fileDragging(c);break;case"fontname":e=new a.extensions.fontName(this.options.fontName);break;case"fontsize":e=new a.extensions.fontSize(c);break;case"keyboardCommands":e=new a.extensions.keyboardCommands(this.options.keyboardCommands);break;case"paste":e=new a.extensions.paste(this.options.paste);break;case"placeholder":e=new a.extensions.placeholder(this.options.placeholder);break;default:a.extensions.button.isBuiltInButton(b)&&(c?(d=a.util.defaults({},c,a.extensions.button.prototype.defaults[b]),e=new a.extensions.button(d)):e=new a.extensions.button(b))}return e&&this.extensions.push(m(e,b,this)),e},stopSelectionUpdates:function(){this.preventSelectionUpdates=!0},startSelectionUpdates:function(){this.preventSelectionUpdates=!1},checkSelection:function(){var a=this.getExtensionByName("toolbar");return a&&a.checkState(),this},queryCommandState:function(a){var b,c=/^full-(.+)$/gi,d=null;b=c.exec(a),b&&(a=b[1]);try{d=this.options.ownerDocument.queryCommandState(a)}catch(e){d=null}return d},execAction:function(b,c){var d,e,f=/^full-(.+)$/gi;return d=f.exec(b),d?(this.saveSelection(),this.selectAllContents(),e=z.call(this,d[1],c),this.restoreSelection()):e=z.call(this,b,c),"insertunorderedlist"!==b&&"insertorderedlist"!==b||a.util.cleanListDOM(this.options.ownerDocument,this.getSelectedParentElement()),this.checkSelection(),e},getSelectedParentElement:function(b){return void 0===b&&(b=this.options.contentWindow.getSelection().getRangeAt(0)),a.selection.getSelectedParentElement(b)},selectAllContents:function(){var b=a.selection.getSelectionElement(this.options.contentWindow);if(b){for(;1===b.children.length;)b=b.children[0];this.selectElement(b)}},selectElement:function(b){a.selection.selectNode(b,this.options.ownerDocument);var c=a.selection.getSelectionElement(this.options.contentWindow);c&&this.events.focusElement(c)},getFocusedElement:function(){var a;return this.elements.some(function(b){return!a&&b.getAttribute("data-medium-focused")&&(a=b),!!a},this),a},exportSelection:function(){var b=a.selection.getSelectionElement(this.options.contentWindow),c=this.elements.indexOf(b),d=null;return c>=0&&(d=a.selection.exportSelection(b,this.options.ownerDocument)),null!==d&&0!==c&&(d.editableElementIndex=c),d},saveSelection:function(){this.selectionState=this.exportSelection()},importSelection:function(b,c){if(b){var d=this.elements[b.editableElementIndex||0];a.selection.importSelection(b,d,this.options.ownerDocument,c)}},restoreSelection:function(){this.importSelection(this.selectionState)},createLink:function(b){var c,d=a.selection.getSelectionElement(this.options.contentWindow),e={};if(-1!==this.elements.indexOf(d)){try{if(this.events.disableCustomEvent("editableInput"),b.url&&a.util.deprecated(".url option for createLink",".value","6.0.0"),c=b.url||b.value,c&&c.trim().length>0){var f=this.options.contentWindow.getSelection();if(f){var g,h,i,j,k=f.getRangeAt(0),l=k.commonAncestorContainer;if(3===k.endContainer.nodeType&&3!==k.startContainer.nodeType&&0===k.startOffset&&k.startContainer.firstChild===k.endContainer&&(l=k.endContainer),h=a.util.getClosestBlockContainer(k.startContainer),i=a.util.getClosestBlockContainer(k.endContainer),3!==l.nodeType&&0!==l.textContent.length&&h===i){var m=h||d,n=this.options.ownerDocument.createDocumentFragment();this.execAction("unlink"),g=this.exportSelection(),n.appendChild(m.cloneNode(!0)),d===m?a.selection.select(this.options.ownerDocument,m.firstChild,0,m.lastChild,3===m.lastChild.nodeType?m.lastChild.nodeValue.length:m.lastChild.childNodes.length):a.selection.select(this.options.ownerDocument,m,0,m,m.childNodes.length);var o=this.exportSelection();j=a.util.findOrCreateMatchingTextNodes(this.options.ownerDocument,n,{start:g.start-o.start,end:g.end-o.start,editableElementIndex:g.editableElementIndex}),0===j.length&&(n=this.options.ownerDocument.createDocumentFragment(),n.appendChild(l.cloneNode(!0)),j=[n.firstChild.firstChild,n.firstChild.lastChild]),a.util.createLink(this.options.ownerDocument,j,c.trim());var p=(n.firstChild.innerHTML.match(/^\s+/)||[""])[0].length;a.util.insertHTMLCommand(this.options.ownerDocument,n.firstChild.innerHTML.replace(/^\s+/,"")),g.start-=p,g.end-=p,this.importSelection(g)}else this.options.ownerDocument.execCommand("createLink",!1,c);this.options.targetBlank||"_blank"===b.target?a.util.setTargetBlank(a.selection.getSelectionStart(this.options.ownerDocument),c):a.util.removeTargetBlank(a.selection.getSelectionStart(this.options.ownerDocument),c),b.buttonClass&&a.util.addClassToAnchors(a.selection.getSelectionStart(this.options.ownerDocument),b.buttonClass)}}if(this.options.targetBlank||"_blank"===b.target||b.buttonClass){e=this.options.ownerDocument.createEvent("HTMLEvents"),e.initEvent("input",!0,!0,this.options.contentWindow);for(var q=0,r=this.elements.length;r>q;q+=1)this.elements[q].dispatchEvent(e)}}finally{this.events.enableCustomEvent("editableInput")}this.events.triggerCustomEvent("editableInput",e,d)}},cleanPaste:function(a){this.getExtensionByName("paste").cleanPaste(a)},pasteHTML:function(a,b){this.getExtensionByName("paste").pasteHTML(a,b)},setContent:function(a,b){if(b=b||0,this.elements[b]){var c=this.elements[b];c.innerHTML=a,this.checkContentChanged(c)}},getContent:function(a){return a=a||0,this.elements[a]?this.elements[a].innerHTML.trim():null},checkContentChanged:function(b){b=b||a.selection.getSelectionElement(this.options.contentWindow),this.events.updateInput(b,{target:b,currentTarget:b})},resetContent:function(a){if(a){var b=this.elements.indexOf(a);return void(-1!==b&&this.setContent(B[a.getAttribute("medium-editor-index")],b))}this.elements.forEach(function(a,b){this.setContent(B[a.getAttribute("medium-editor-index")],b)},this)},addElements:function(a){var b=j(a,this.options.ownerDocument,!0);return 0===b.length?!1:void b.forEach(function(a){a=v.call(this,a,this.id),this.elements.push(a),this.trigger("addElement",{target:a,currentTarget:a},a)},this)},removeElements:function(a){var b=j(a,this.options.ownerDocument),c=b.map(function(a){return a.getAttribute("medium-editor-textarea-id")&&a.parentNode?a.parentNode.querySelector('div[medium-editor-textarea-id="'+a.getAttribute("medium-editor-textarea-id")+'"]'):a});this.elements=this.elements.filter(function(a){return-1!==c.indexOf(a)?(this.events.cleanupElement(a),a.getAttribute("medium-editor-textarea-id")&&k(a),this.trigger("removeElement",{target:a,currentTarget:a},a),!1):!0},this)}},a.getEditorFromElement=function(a){var b=a.getAttribute("data-medium-editor-editor-index"),c=a&&a.ownerDocument&&(a.ownerDocument.defaultView||a.ownerDocument.parentWindow);return c&&c._mediumEditors&&c._mediumEditors[b]?c._mediumEditors[b]:null}}(),function(){a.prototype.defaults={activeButtonClass:"medium-editor-button-active",buttonLabels:!1,delay:0,disableReturn:!1,disableDoubleReturn:!1,disableExtraSpaces:!1,disableEditing:!1,autoLink:!1,elementsContainer:!1,contentWindow:window,ownerDocument:document,targetBlank:!1,extensions:{},spellcheck:!0}}(),a.parseVersionString=function(a){var b=a.split("-"),c=b[0].split("."),d=b.length>1?b[1]:"";return{major:parseInt(c[0],10),minor:parseInt(c[1],10),revision:parseInt(c[2],10),preRelease:d,toString:function(){return[c[0],c[1],c[2]].join(".")+(d?"-"+d:"")}}},a.version=a.parseVersionString.call(this,{version:"5.23.3"}.version),a}()); \ No newline at end of file +"classList"in document.createElement("_")||function(e){"use strict";if("Element"in e){var t="classList",n="prototype",i=e.Element[n],o=Object,s=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[n].indexOf||function(e){for(var t=0,n=this.length;t)?$/i,s=/h\d/i;b.util.isKey(e,[b.util.keyCode.BACKSPACE,b.util.keyCode.ENTER])&&n.previousElementSibling&&s.test(i)&&0===b.selection.getCaretOffsets(n).left?b.util.isKey(e,b.util.keyCode.BACKSPACE)&&o.test(n.previousElementSibling.innerHTML)?(n.previousElementSibling.parentNode.removeChild(n.previousElementSibling),e.preventDefault()):!this.options.disableDoubleReturn&&b.util.isKey(e,b.util.keyCode.ENTER)&&((t=this.options.ownerDocument.createElement("p")).innerHTML="
    ",n.previousElementSibling.parentNode.insertBefore(t,n),e.preventDefault()):b.util.isKey(e,b.util.keyCode.DELETE)&&n.nextElementSibling&&n.previousElementSibling&&!s.test(i)&&o.test(n.innerHTML)&&s.test(n.nextElementSibling.nodeName.toLowerCase())?(b.selection.moveCursor(this.options.ownerDocument,n.nextElementSibling),n.previousElementSibling.parentNode.removeChild(n),e.preventDefault()):b.util.isKey(e,b.util.keyCode.BACKSPACE)&&"li"===i&&o.test(n.innerHTML)&&!n.previousElementSibling&&!n.parentElement.previousElementSibling&&n.nextElementSibling&&"li"===n.nextElementSibling.nodeName.toLowerCase()?((t=this.options.ownerDocument.createElement("p")).innerHTML="
    ",n.parentElement.parentElement.insertBefore(t,n.parentElement),b.selection.moveCursor(this.options.ownerDocument,t),n.parentElement.removeChild(n),e.preventDefault()):b.util.isKey(e,b.util.keyCode.BACKSPACE)&&!1!==b.util.getClosestTag(n,"blockquote")&&0===b.selection.getCaretOffsets(n).left?(e.preventDefault(),b.util.execFormatBlock(this.options.ownerDocument,"p")):b.util.isKey(e,b.util.keyCode.ENTER)&&!1!==b.util.getClosestTag(n,"blockquote")&&0===b.selection.getCaretOffsets(n).right?((t=this.options.ownerDocument.createElement("p")).innerHTML="
    ",n.parentElement.insertBefore(t,n.nextSibling),b.selection.moveCursor(this.options.ownerDocument,t),e.preventDefault()):b.util.isKey(e,b.util.keyCode.BACKSPACE)&&b.util.isMediumEditorElement(n.parentElement)&&!n.previousElementSibling&&n.nextElementSibling&&o.test(n.innerHTML)&&(e.preventDefault(),b.selection.moveCursor(this.options.ownerDocument,n.nextSibling),n.parentElement.removeChild(n))}function N(e,t,n){var i=[];if("string"==typeof(e=e||[])&&(e=t.querySelectorAll(e)),b.util.isElement(e)&&(e=[e]),n)for(var o=0;on.end+1)throw new Error("PerformLinking overshot the target!");r&&o.push(l||a),s+=a.nodeValue.length,null!==l&&(s+=l.nodeValue.length,i.nextNode()),l=null}else"img"===a.tagName.toLowerCase()&&(!r&&n.start<=s&&(r=!0),r&&o.push(a));return o},splitStartNodeIfNeeded:function(e,t,n){return t!==n?e.splitText(t-n):null},splitEndNodeIfNeeded:function(e,t,n,i){var o,s;o=i+e.nodeValue.length+(t?t.nodeValue.length:0)-1,s=n-i-(t?e.nodeValue.length:0),n<=o&&i!==o&&0!=s&&(t||e).splitText(s)},splitByBlockElements:function(e){if(3!==e.nodeType&&1!==e.nodeType)return[];var t=[],n=b.util.blockContainerElementNames.join(",");if(3===e.nodeType||0===e.querySelectorAll(n).length)return[e];for(var i=0;i/g,">").replace(/"/g,""")},insertHTMLCommand:function(e,t){var n,i,o,s,r,a,l,c=!1,d=["insertHTML",!1,t];if(!b.util.isEdge&&e.queryCommandSupported("insertHTML"))try{return e.execCommand.apply(e,d)}catch(e){}if((n=e.getSelection()).rangeCount){if(l=(i=n.getRangeAt(0)).commonAncestorContainer,f.isMediumEditorElement(l)&&!l.firstChild)i.selectNode(l.appendChild(e.createTextNode("")));else if(3===l.nodeType&&0===i.startOffset&&i.endOffset===l.nodeValue.length||3!==l.nodeType&&l.innerHTML===i.toString()){for(;!f.isMediumEditorElement(l)&&l.parentNode&&1===l.parentNode.childNodes.length&&!f.isMediumEditorElement(l.parentNode);)l=l.parentNode;i.selectNode(l)}for(i.deleteContents(),(o=e.createElement("div")).innerHTML=t,s=e.createDocumentFragment();o.firstChild;)r=o.firstChild,a=s.appendChild(r);i.insertNode(s),a&&((i=i.cloneRange()).setStartAfter(a),i.collapse(!0),b.selection.selectRange(e,i)),c=!0}return e.execCommand.callListeners&&e.execCommand.callListeners(d,c),c},execFormatBlock:function(e,t){var n=f.getTopBlockContainer(b.selection.getSelectionStart(e));if("blockquote"===t){if(n&&Array.prototype.slice.call(n.childNodes).some(function(e){return f.isBlockContainer(e)}))return e.execCommand("outdent",!1,null);if(f.isIE)return e.execCommand("indent",!1,t)}if(n&&t===n.nodeName.toLowerCase()&&(t="p"),f.isIE&&(t="<"+t+">"),n&&"blockquote"===n.nodeName.toLowerCase()){if(f.isIE&&"

    "===t)return e.execCommand("outdent",!1,t);if((f.isFF||f.isEdge)&&"p"===t)return Array.prototype.slice.call(n.childNodes).some(function(e){return!f.isBlockContainer(e)})&&e.execCommand("formatBlock",!1,t),e.execCommand("outdent",!1,t)}return e.execCommand("formatBlock",!1,t)},setTargetBlank:function(e,t){var n,i=t||!1;if("a"===e.nodeName.toLowerCase())e.target="_blank",e.rel="noopener noreferrer";else for(e=e.getElementsByTagName("a"),n=0;n=l&&e.start<=s&&(m||e.start=l&&e.end<=s&&(e.trailingImageCount?d=!0:(o.setEnd(r,e.end-l),h=!0)),l=s;h||(r=a.pop())}!c&&f&&(o.setStart(f,f.length),o.setEnd(f,f.length)),void 0!==e.emptyBlocksIndex&&(o=this.importSelectionMoveCursorPastBlocks(n,t,e.emptyBlocksIndex,o)),i&&(o=this.importSelectionMoveCursorPastAnchor(e,o)),this.selectRange(n,o)}},importSelectionMoveCursorPastAnchor:function(e,t){if(e.start===e.end&&3===t.startContainer.nodeType&&t.startOffset===t.startContainer.nodeValue.length&&b.util.traverseUp(t.startContainer,function(e){return"a"===e.nodeName.toLowerCase()})){for(var n=t.startContainer,i=t.startContainer.parentNode;null!==i&&"a"!==i.nodeName.toLowerCase();)i=i.childNodes[i.childNodes.length-1]!==n?null:(n=i).parentNode;if(null!==i&&"a"===i.nodeName.toLowerCase()){for(var o=null,s=0;null===o&&s=l&&t.start<=s&&(c=!0),c&&t.end>=l&&t.end<=s&&(d=!0),l=s;u||(r=a.pop())}return h},selectionContainsContent:function(e){var t=e.getSelection();if(!t||t.isCollapsed||!t.rangeCount)return!1;if(""!==t.toString().trim())return!0;var n=this.getSelectedParentElement(t.getRangeAt(0));return!(!n||!("img"===n.nodeName.toLowerCase()||1===n.nodeType&&n.querySelector("img")))},selectionInContentEditableFalse:function(e){var n,t=this.findMatchingSelectionParent(function(e){var t=e&&e.getAttribute("contenteditable");return"true"===t&&(n=!0),"#text"!==e.nodeName&&"false"===t},e);return!n&&t},getSelectionHtml:function(e){var t,n,i,o="",s=e.getSelection();if(s.rangeCount){for(i=e.createElement("div"),t=0,n=s.rangeCount;tB",contentFA:''},italic:{name:"italic",action:"italic",aria:"italic",tagNames:["i","em"],style:{prop:"font-style",value:"italic"},useQueryState:!0,contentDefault:"I",contentFA:''},underline:{name:"underline",action:"underline",aria:"underline",tagNames:["u"],style:{prop:"text-decoration",value:"underline"},useQueryState:!0,contentDefault:"U",contentFA:''},strikethrough:{name:"strikethrough",action:"strikethrough",aria:"strike through",tagNames:["strike"],style:{prop:"text-decoration",value:"line-through"},useQueryState:!0,contentDefault:"A",contentFA:''},superscript:{name:"superscript",action:"superscript",aria:"superscript",tagNames:["sup"],contentDefault:"x1",contentFA:''},subscript:{name:"subscript",action:"subscript",aria:"subscript",tagNames:["sub"],contentDefault:"x1",contentFA:''},image:{name:"image",action:"image",aria:"image",tagNames:["img"],contentDefault:"image",contentFA:''},html:{name:"html",action:"html",aria:"evaluate html",tagNames:["iframe","object"],contentDefault:"html",contentFA:''},orderedlist:{name:"orderedlist",action:"insertorderedlist",aria:"ordered list",tagNames:["ol"],useQueryState:!0,contentDefault:"1.",contentFA:''},unorderedlist:{name:"unorderedlist",action:"insertunorderedlist",aria:"unordered list",tagNames:["ul"],useQueryState:!0,contentDefault:"",contentFA:''},indent:{name:"indent",action:"indent",aria:"indent",tagNames:[],contentDefault:"",contentFA:''},outdent:{name:"outdent",action:"outdent",aria:"outdent",tagNames:[],contentDefault:"",contentFA:''},justifyCenter:{name:"justifyCenter",action:"justifyCenter",aria:"center justify",tagNames:[],style:{prop:"text-align",value:"center"},contentDefault:"C",contentFA:''},justifyFull:{name:"justifyFull",action:"justifyFull",aria:"full justify",tagNames:[],style:{prop:"text-align",value:"justify"},contentDefault:"J",contentFA:''},justifyLeft:{name:"justifyLeft",action:"justifyLeft",aria:"left justify",tagNames:[],style:{prop:"text-align",value:"left"},contentDefault:"L",contentFA:''},justifyRight:{name:"justifyRight",action:"justifyRight",aria:"right justify",tagNames:[],style:{prop:"text-align",value:"right"},contentDefault:"R",contentFA:''},removeFormat:{name:"removeFormat",aria:"remove formatting",action:"removeFormat",contentDefault:"X",contentFA:''},quote:{name:"quote",action:"append-blockquote",aria:"blockquote",tagNames:["blockquote"],contentDefault:"",contentFA:''},pre:{name:"pre",action:"append-pre",aria:"preformatted text",tagNames:["pre"],contentDefault:"0101",contentFA:''},h1:{name:"h1",action:"append-h1",aria:"header type one",tagNames:["h1"],contentDefault:"H1",contentFA:'1'},h2:{name:"h2",action:"append-h2",aria:"header type two",tagNames:["h2"],contentDefault:"H2",contentFA:'2'},h3:{name:"h3",action:"append-h3",aria:"header type three",tagNames:["h3"],contentDefault:"H3",contentFA:'3'},h4:{name:"h4",action:"append-h4",aria:"header type four",tagNames:["h4"],contentDefault:"H4",contentFA:'4'},h5:{name:"h5",action:"append-h5",aria:"header type five",tagNames:["h5"],contentDefault:"H5",contentFA:'5'},h6:{name:"h6",action:"append-h6",aria:"header type six",tagNames:["h6"],contentDefault:"H6",contentFA:'6'}},i=b.extensions.button.extend({init:function(){b.extensions.button.prototype.init.apply(this,arguments)},formSaveLabel:"✓",formCloseLabel:"×",activeClass:"medium-editor-toolbar-form-active",hasForm:!0,getForm:function(){},isDisplayed:function(){return!!this.hasForm&&this.getForm().classList.contains(this.activeClass)},showForm:function(){this.hasForm&&this.getForm().classList.add(this.activeClass)},hideForm:function(){this.hasForm&&this.getForm().classList.remove(this.activeClass)},showToolbarDefaultActions:function(){var e=this.base.getExtensionByName("toolbar");e&&e.showToolbarDefaultActions()},hideToolbarDefaultActions:function(){var e=this.base.getExtensionByName("toolbar");e&&e.hideToolbarDefaultActions()},setToolbarPosition:function(){var e=this.base.getExtensionByName("toolbar");e&&e.setToolbarPosition()}}),b.extensions.form=i,o=b.extensions.form.extend({customClassOption:null,customClassOptionText:"Button",linkValidation:!1,placeholderText:"Paste or type a link",targetCheckbox:!1,targetCheckboxText:"Open in new window",name:"anchor",action:"createLink",aria:"link",tagNames:["a"],contentDefault:"#",contentFA:'',init:function(){b.extensions.form.prototype.init.apply(this,arguments),this.subscribe("editableKeydown",this.handleKeydown.bind(this))},handleClick:function(e){e.preventDefault(),e.stopPropagation();var t=b.selection.getSelectionRange(this.document);return"a"===t.startContainer.nodeName.toLowerCase()||"a"===t.endContainer.nodeName.toLowerCase()||b.util.getClosestTag(b.selection.getSelectedParentElement(t),"a")?this.execAction("unlink"):(this.isDisplayed()||this.showForm(),!1)},handleKeydown:function(e){b.util.isKey(e,b.util.keyCode.K)&&b.util.isMetaCtrlKey(e)&&!e.shiftKey&&this.handleClick(e)},getForm:function(){return this.form||(this.form=this.createForm()),this.form},getTemplate:function(){var e=[''];return e.push('',"fontawesome"===this.getEditorOption("buttonLabels")?'':this.formSaveLabel,""),e.push('',"fontawesome"===this.getEditorOption("buttonLabels")?'':this.formCloseLabel,""),this.targetCheckbox&&e.push('

    ','','","
    "),this.customClassOption&&e.push('
    ','','","
    "),e.join("")},isDisplayed:function(){return b.extensions.form.prototype.isDisplayed.apply(this)},hideForm:function(){b.extensions.form.prototype.hideForm.apply(this),this.getInput().value=""},showForm:function(e){var t=this.getInput(),n=this.getAnchorTargetCheckbox(),i=this.getAnchorButtonCheckbox();if("string"==typeof(e=e||{value:""})&&(e={value:e}),this.base.saveSelection(),this.hideToolbarDefaultActions(),b.extensions.form.prototype.showForm.apply(this),this.setToolbarPosition(),t.value=e.value,t.focus(),n&&(n.checked="_blank"===e.target),i){var o=e.buttonClass?e.buttonClass.split(" "):[];i.checked=-1!==o.indexOf(this.customClassOption)}},destroy:function(){if(!this.form)return!1;this.form.parentNode&&this.form.parentNode.removeChild(this.form),delete this.form},getFormOpts:function(){var e=this.getAnchorTargetCheckbox(),t=this.getAnchorButtonCheckbox(),n={value:this.getInput().value.trim()};return this.linkValidation&&(n.value=this.checkLinkFormat(n.value)),n.target="_self",e&&e.checked&&(n.target="_blank"),t&&t.checked&&(n.buttonClass=this.customClassOption),n},doFormSave:function(){var e=this.getFormOpts();this.completeFormSave(e)},completeFormSave:function(e){this.base.restoreSelection(),this.execAction(this.action,e),this.base.checkSelection()},ensureEncodedUri:function(e){return e===decodeURI(e)?encodeURI(e):e},ensureEncodedUriComponent:function(e){return e===decodeURIComponent(e)?encodeURIComponent(e):e},ensureEncodedParam:function(e){var t=e.split("="),n=t[0],i=t[1];return n+(void 0===i?"":"="+this.ensureEncodedUriComponent(i))},ensureEncodedQuery:function(e){return e.split("&").map(this.ensureEncodedParam.bind(this)).join("&")},checkLinkFormat:function(e){var t=/^([a-z]+:)?\/\/|^(mailto|tel|maps):|^#/i.test(e),n="",i=e.match(/^(.*?)(?:\?(.*?))?(?:#(.*))?$/),o=i[1],s=i[2],r=i[3];if(/^\+?\s?\(?(?:\d\s?-?\)?){3,20}$/.test(e))return"tel:"+e;if(!t){var a=o.split("/")[0];!a.match(/.+([.:]).+/)&&"localhost"!==a||(n="http://")}return n+this.ensureEncodedUri(o)+(void 0===s?"":"?"+this.ensureEncodedQuery(s))+(void 0===r?"":"#"+r)},doFormCancel:function(){this.base.restoreSelection(),this.base.checkSelection()},attachFormEvents:function(e){var t=e.querySelector(".medium-editor-toolbar-close"),n=e.querySelector(".medium-editor-toolbar-save"),i=e.querySelector(".medium-editor-toolbar-input");this.on(e,"click",this.handleFormClick.bind(this)),this.on(i,"keyup",this.handleTextboxKeyup.bind(this)),this.on(t,"click",this.handleCloseClick.bind(this)),this.on(n,"click",this.handleSaveClick.bind(this),!0)},createForm:function(){var e=this.document.createElement("div");return e.className="medium-editor-toolbar-form",e.id="medium-editor-toolbar-form-anchor-"+this.getEditorId(),e.innerHTML=this.getTemplate(),this.attachFormEvents(e),e},getInput:function(){return this.getForm().querySelector("input.medium-editor-toolbar-input")},getAnchorTargetCheckbox:function(){return this.getForm().querySelector(".medium-editor-toolbar-anchor-target")},getAnchorButtonCheckbox:function(){return this.getForm().querySelector(".medium-editor-toolbar-anchor-button")},handleTextboxKeyup:function(e){if(e.keyCode===b.util.keyCode.ENTER)return e.preventDefault(),void this.doFormSave();e.keyCode===b.util.keyCode.ESCAPE&&(e.preventDefault(),this.doFormCancel())},handleFormClick:function(e){e.stopPropagation()},handleSaveClick:function(e){e.preventDefault(),this.doFormSave()},handleCloseClick:function(e){e.preventDefault(),this.doFormCancel()}}),b.extensions.anchor=o,s=b.Extension.extend({name:"anchor-preview",hideDelay:500,previewValueSelector:"a",showWhenToolbarIsVisible:!1,showOnEmptyLinks:!0,init:function(){this.anchorPreview=this.createPreview(),this.getEditorOption("elementsContainer").appendChild(this.anchorPreview),this.attachToEditables()},getInteractionElements:function(){return this.getPreviewElement()},getPreviewElement:function(){return this.anchorPreview},createPreview:function(){var e=this.document.createElement("div");return e.id="medium-editor-anchor-preview-"+this.getEditorId(),e.className="medium-editor-anchor-preview",e.innerHTML=this.getTemplate(),this.on(e,"click",this.handleClick.bind(this)),e},getTemplate:function(){return'
    '},destroy:function(){this.anchorPreview&&(this.anchorPreview.parentNode&&this.anchorPreview.parentNode.removeChild(this.anchorPreview),delete this.anchorPreview)},hidePreview:function(){this.anchorPreview&&this.anchorPreview.classList.remove("medium-editor-anchor-preview-active"),this.activeAnchor=null},showPreview:function(e){return!(!this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")&&!e.getAttribute("data-disable-preview"))||(this.previewValueSelector&&(this.anchorPreview.querySelector(this.previewValueSelector).textContent=e.attributes.href.value,this.anchorPreview.querySelector(this.previewValueSelector).href=e.attributes.href.value),this.anchorPreview.classList.add("medium-toolbar-arrow-over"),this.anchorPreview.classList.remove("medium-toolbar-arrow-under"),this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")||this.anchorPreview.classList.add("medium-editor-anchor-preview-active"),this.activeAnchor=e,this.positionPreview(),this.attachPreviewHandlers(),this)},positionPreview:function(e){e=e||this.activeAnchor;var t,n,i,o,s,r=this.window.innerWidth,a=this.anchorPreview.offsetHeight,l=e.getBoundingClientRect(),c=this.diffLeft,d=this.diffTop,u=this.getEditorOption("elementsContainer"),h=-1<["absolute","fixed"].indexOf(window.getComputedStyle(u).getPropertyValue("position")),m={};t=this.anchorPreview.offsetWidth/2;var f=this.base.getExtensionByName("toolbar");f&&(c=f.diffLeft,d=f.diffTop),n=c-t,s=h?(o=u.getBoundingClientRect(),["top","left"].forEach(function(e){m[e]=l[e]-o[e]}),m.width=l.width,m.height=l.height,l=m,r=o.width,u.scrollTop):this.window.pageYOffset,i=l.left+l.width/2,s+=a+l.top+l.height-d-this.anchorPreview.offsetHeight,this.anchorPreview.style.top=Math.round(s)+"px",this.anchorPreview.style.right="initial",ithis.hideDelay&&this.detachPreviewHandlers()},detachPreviewHandlers:function(){clearInterval(this.intervalTimer),this.instanceHandlePreviewMouseover&&(this.off(this.anchorPreview,"mouseover",this.instanceHandlePreviewMouseover),this.off(this.anchorPreview,"mouseout",this.instanceHandlePreviewMouseout),this.activeAnchor&&(this.off(this.activeAnchor,"mouseover",this.instanceHandlePreviewMouseover),this.off(this.activeAnchor,"mouseout",this.instanceHandlePreviewMouseout))),this.hidePreview(),this.hovering=this.instanceHandlePreviewMouseover=this.instanceHandlePreviewMouseout=null},attachPreviewHandlers:function(){this.lastOver=(new Date).getTime(),this.hovering=!0,this.instanceHandlePreviewMouseover=this.handlePreviewMouseover.bind(this),this.instanceHandlePreviewMouseout=this.handlePreviewMouseout.bind(this),this.intervalTimer=setInterval(this.updatePreview.bind(this),200),this.on(this.anchorPreview,"mouseover",this.instanceHandlePreviewMouseover),this.on(this.anchorPreview,"mouseout",this.instanceHandlePreviewMouseout),this.on(this.activeAnchor,"mouseover",this.instanceHandlePreviewMouseover),this.on(this.activeAnchor,"mouseout",this.instanceHandlePreviewMouseout)}}),b.extensions.anchorPreview=s,function(){var s,e,r,a;s=[" ","\t","\n","\r"," "," "," "," "," ","\u2028","\u2029"],e="com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw",r=new RegExp("^("+e+")$","i"),a=new RegExp("(((?:(https?://|ftps?://|nntp://)|www\\d{0,3}[.]|[a-z0-9.\\-]+[.](com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\\/)\\S+(?:[^\\s`!\\[\\]{};:'\".,?«»“”‘’])))|(([a-z0-9\\-]+\\.)?[a-z0-9\\-]+\\.(com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw))","gi");var t=b.Extension.extend({init:function(){b.Extension.prototype.init.apply(this,arguments),this.disableEventHandling=!1,this.subscribe("editableKeypress",this.onKeypress.bind(this)),this.subscribe("editableBlur",this.onBlur.bind(this)),this.document.execCommand("AutoUrlDetect",!1,!1)},isLastInstance:function(){for(var e=0,t=0;tt?(o=n.splitText(i.length-t),t=0):(o=s.previousNode(),t-=i.length);return o},performLinkingWithinElement:function(e){for(var t=this.findLinkableText(e),n=0;n
    ',fonts:["","Arial","Verdana","Times New Roman"],init:function(){b.extensions.form.prototype.init.apply(this,arguments)},handleClick:function(e){if(e.preventDefault(),e.stopPropagation(),!this.isDisplayed()){var t=this.document.queryCommandValue("fontName")+"";this.showForm(t)}return!1},getForm:function(){return this.form||(this.form=this.createForm()),this.form},isDisplayed:function(){return"block"===this.getForm().style.display},hideForm:function(){this.getForm().style.display="none",this.getSelect().value=""},showForm:function(e){var t=this.getSelect();this.base.saveSelection(),this.hideToolbarDefaultActions(),this.getForm().style.display="block",this.setToolbarPosition(),t.value=e||"",t.focus()},destroy:function(){if(!this.form)return!1;this.form.parentNode&&this.form.parentNode.removeChild(this.form),delete this.form},doFormSave:function(){this.base.restoreSelection(),this.base.checkSelection()},doFormCancel:function(){this.base.restoreSelection(),this.clearFontName(),this.base.checkSelection()},createForm:function(){var e,t=this.document,n=t.createElement("div"),i=t.createElement("select"),o=t.createElement("a"),s=t.createElement("a");n.className="medium-editor-toolbar-form",n.id="medium-editor-toolbar-form-fontname-"+this.getEditorId(),this.on(n,"click",this.handleFormClick.bind(this));for(var r=0;r
    ':"✓",n.appendChild(s),this.on(s,"click",this.handleSaveClick.bind(this),!0),o.setAttribute("href","#"),o.className="medium-editor-toolbar-close",o.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"×",n.appendChild(o),this.on(o,"click",this.handleCloseClick.bind(this)),n},getSelect:function(){return this.getForm().querySelector("select.medium-editor-toolbar-select")},clearFontName:function(){b.selection.getSelectedElements(this.document).forEach(function(e){"font"===e.nodeName.toLowerCase()&&e.hasAttribute("face")&&e.removeAttribute("face")})},handleFontChange:function(){var e=this.getSelect().value;""===e?this.clearFontName():this.execAction("fontName",{value:e})},handleFormClick:function(e){e.stopPropagation()},handleSaveClick:function(e){e.preventDefault(),this.doFormSave()},handleCloseClick:function(e){e.preventDefault(),this.doFormCancel()}}),b.extensions.fontName=c,u=b.extensions.form.extend({name:"fontsize",action:"fontSize",aria:"increase/decrease font size",contentDefault:"±",contentFA:'',init:function(){b.extensions.form.prototype.init.apply(this,arguments)},handleClick:function(e){if(e.preventDefault(),e.stopPropagation(),!this.isDisplayed()){var t=this.document.queryCommandValue("fontSize")+"";this.showForm(t)}return!1},getForm:function(){return this.form||(this.form=this.createForm()),this.form},isDisplayed:function(){return"block"===this.getForm().style.display},hideForm:function(){this.getForm().style.display="none",this.getInput().value=""},showForm:function(e){var t=this.getInput();this.base.saveSelection(),this.hideToolbarDefaultActions(),this.getForm().style.display="block",this.setToolbarPosition(),t.value=e||"",t.focus()},destroy:function(){if(!this.form)return!1;this.form.parentNode&&this.form.parentNode.removeChild(this.form),delete this.form},doFormSave:function(){this.base.restoreSelection(),this.base.checkSelection()},doFormCancel:function(){this.base.restoreSelection(),this.clearFontSize(),this.base.checkSelection()},createForm:function(){var e=this.document,t=e.createElement("div"),n=e.createElement("input"),i=e.createElement("a"),o=e.createElement("a");return t.className="medium-editor-toolbar-form",t.id="medium-editor-toolbar-form-fontsize-"+this.getEditorId(),this.on(t,"click",this.handleFormClick.bind(this)),n.setAttribute("type","range"),n.setAttribute("min","1"),n.setAttribute("max","7"),n.className="medium-editor-toolbar-input",t.appendChild(n),this.on(n,"change",this.handleSliderChange.bind(this)),o.setAttribute("href","#"),o.className="medium-editor-toolbar-save",o.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"✓",t.appendChild(o),this.on(o,"click",this.handleSaveClick.bind(this),!0),i.setAttribute("href","#"),i.className="medium-editor-toolbar-close",i.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"×",t.appendChild(i),this.on(i,"click",this.handleCloseClick.bind(this)),t},getInput:function(){return this.getForm().querySelector("input.medium-editor-toolbar-input")},clearFontSize:function(){b.selection.getSelectedElements(this.document).forEach(function(e){"font"===e.nodeName.toLowerCase()&&e.hasAttribute("size")&&e.removeAttribute("size")})},handleSliderChange:function(){var e=this.getInput().value;"4"===e?this.clearFontSize():this.execAction("fontSize",{value:e})},handleFormClick:function(e){e.stopPropagation()},handleSaveClick:function(e){e.preventDefault(),this.doFormSave()},handleCloseClick:function(e){e.preventDefault(),this.doFormCancel()}}),b.extensions.fontSize=u,h="%ME_PASTEBIN%",f=m=null,p=b.Extension.extend({forcePlainText:!0,cleanPastedHTML:!1,preCleanReplacements:[],cleanReplacements:[],cleanAttrs:["class","style","dir"],cleanTags:["meta"],unwrapTags:[],init:function(){b.Extension.prototype.init.apply(this,arguments),(this.forcePlainText||this.cleanPastedHTML)&&(this.subscribe("editableKeydown",this.handleKeydown.bind(this)),this.getEditorElements().forEach(function(e){this.on(e,"paste",this.handlePaste.bind(this))},this),this.subscribe("addElement",this.handleAddElement.bind(this)))},handleAddElement:function(e,t){this.on(t,"paste",this.handlePaste.bind(this))},destroy:function(){(this.forcePlainText||this.cleanPastedHTML)&&this.removePasteBin()},handlePaste:function(e,t){if(!e.defaultPrevented){var n=k(e,this.window,this.document),i=n["text/html"],o=n["text/plain"];this.window.clipboardData&&void 0===e.clipboardData&&!i&&(i=o),(i||o)&&(e.preventDefault(),this.doPaste(i,o,t))}},doPaste:function(e,t,n){var i,o,s="";if(this.cleanPastedHTML&&e)return this.cleanPaste(e);if(t){if(this.getEditorOption("disableReturn")||n&&n.getAttribute("data-disable-return"))s=b.util.htmlEntities(t);else if(1<(i=t.split(/[\r\n]+/g)).length)for(o=0;o"+b.util.htmlEntities(i[o])+"

    ");else s=b.util.htmlEntities(i[0]);b.util.insertHTMLCommand(this.document,s)}},handlePasteBinPaste:function(e){if(e.defaultPrevented)this.removePasteBin();else{var t=k(e,this.window,this.document),n=t["text/html"],i=t["text/plain"],o=f;if(!this.cleanPastedHTML||n)return e.preventDefault(),this.removePasteBin(),this.doPaste(n,i,o),void this.trigger("editablePaste",{currentTarget:o,target:o},o);setTimeout(function(){this.cleanPastedHTML&&(n=this.getPasteBinHtml()),this.removePasteBin(),this.doPaste(n,i,o),this.trigger("editablePaste",{currentTarget:o,target:o},o)}.bind(this),0)}},handleKeydown:function(e,t){b.util.isKey(e,b.util.keyCode.V)&&b.util.isMetaCtrlKey(e)&&(e.stopImmediatePropagation(),this.removePasteBin(),this.createPasteBin(t))},createPasteBin:function(e){var t,n=b.selection.getSelectionRange(this.document),i=this.window.pageYOffset;f=e,n&&((t=n.getClientRects()).length?i+=t[0].top:void 0!==n.startContainer.getBoundingClientRect?i+=n.startContainer.getBoundingClientRect().top:i+=n.getBoundingClientRect().top),m=n;var o=this.document.createElement("div");o.id=this.pasteBinId="medium-editor-pastebin-"+ +Date.now(),o.setAttribute("style","border: 1px red solid; position: absolute; top: "+i+"px; width: 10px; height: 10px; overflow: hidden; opacity: 0"),o.setAttribute("contentEditable",!0),o.innerHTML=h,this.document.body.appendChild(o),this.on(o,"focus",T),this.on(o,"focusin",T),this.on(o,"focusout",T),o.focus(),b.selection.selectNode(o,this.document),this.boundHandlePaste||(this.boundHandlePaste=this.handlePasteBinPaste.bind(this)),this.on(o,"paste",this.boundHandlePaste)},removePasteBin:function(){null!==m&&(b.selection.selectRange(this.document,m),m=null),null!==f&&(f=null);var e=this.getPasteBin();e&&e&&(this.off(e,"focus",T),this.off(e,"focusin",T),this.off(e,"focusout",T),this.off(e,"paste",this.boundHandlePaste),e.parentElement.removeChild(e))},getPasteBin:function(){return this.document.getElementById(this.pasteBinId)},getPasteBinHtml:function(){var e=this.getPasteBin();if(!e)return!1;if(e.firstChild&&"mcepastebin"===e.firstChild.id)return!1;var t=e.innerHTML;return!(!t||t===h)&&t},cleanPaste:function(e){var t,n,i,o,s=/]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g),""],[new RegExp(/|/g),""],[new RegExp(/
    $/i),""],[new RegExp(/<[^>]*docs-internal-guid[^>]*>/gi),""],[new RegExp(/<\/b>(]*>)?$/gi),""],[new RegExp(/\s+<\/span>/g)," "],[new RegExp(/
    /g),"
    "],[new RegExp(/]*(font-style:italic;font-weight:(bold|700)|font-weight:(bold|700);font-style:italic)[^>]*>/gi),''],[new RegExp(/]*font-style:italic[^>]*>/gi),''],[new RegExp(/]*font-weight:(bold|700)[^>]*>/gi),''],[new RegExp(/<(\/?)([iba])>/gi),"<$1$2>"],[new RegExp(/<a(?:(?!href).)+href=(?:"|”|“|"|“|”)(((?!"|”|“|"|“|”).)*)(?:"|”|“|"|“|”)(?:(?!>).)*>/gi),''],[new RegExp(/<\/p>\n+/gi),"

    "],[new RegExp(/\n+

    /gi),""],[new RegExp(/(((?!/gi),"$1"]],this.cleanReplacements||[]);for(t=0;t"+e.split("

    ").join("

    ")+"

    ",n=i.querySelectorAll("a,p,div,br"),t=0;t"+i.innerHTML+"
    ":o.innerHTML=i.innerHTML,i.parentNode.replaceChild(o,i);for(s=e.querySelectorAll("span"),n=0;n]*>","g"),t=b.selection.getSelectionHtml(this.document).replace(/<[^\/>][^>]*><\/[^>]+>/gim,"").match(e);return!!t&&1r+e.offsetHeight-l-this.stickyTopOffset?(o.style.top=r+e.offsetHeight-l+"px",o.classList.remove("medium-editor-sticky-toolbar")):n>r-l-this.stickyTopOffset?(o.classList.add("medium-editor-sticky-toolbar"),o.style.top=this.stickyTopOffset+"px"):(o.classList.remove("medium-editor-sticky-toolbar"),o.style.top=r-l+"px"):o.style.top=r-l+"px",this.align){case"left":t=s.left;break;case"right":t=s.right-c;break;case"center":t=a-d}t<0?t=0:i'),t.onload=function(){var e=this.document.getElementById(n);e&&(e.removeAttribute("id"),e.removeAttribute("class"),e.src=t.result)}.bind(this))}.bind(this)),e.target.classList.remove("medium-editor-dragover")}}),b.extensions.imageDragging=E,C={},b.prototype={init:function(e,t){return this.options=function(e,t){return t&&[["allowMultiParagraphSelection","toolbar.allowMultiParagraphSelection"]].forEach(function(e){t.hasOwnProperty(e[0])&&void 0!==t[e[0]]&&b.util.deprecated(e[0],e[1],"v6.0.0")}),b.util.defaults({},t,e)}.call(this,this.defaults,t),this.origElements=e,this.options.elementsContainer||(this.options.elementsContainer=this.options.ownerDocument.body),this.setup()},setup:function(){this.isActive||(function(e){e._mediumEditors||(e._mediumEditors=[null]),this.id||(this.id=e._mediumEditors.length),e._mediumEditors[this.id]=this}.call(this,this.options.contentWindow),this.events=new b.Events(this),this.elements=[],this.addElements(this.origElements),0!==this.elements.length&&(this.isActive=!0,M.call(this),F.call(this)))},destroy:function(){this.isActive&&(this.isActive=!1,this.extensions.forEach(function(e){"function"==typeof e.destroy&&e.destroy()},this),this.events.destroy(),this.elements.forEach(function(e){this.options.spellcheck&&(e.innerHTML=e.innerHTML),e.removeAttribute("contentEditable"),e.removeAttribute("spellcheck"),e.removeAttribute("data-medium-editor-element"),e.classList.remove("medium-editor-element"),e.removeAttribute("role"),e.removeAttribute("aria-multiline"),e.removeAttribute("medium-editor-index"),e.removeAttribute("data-medium-editor-editor-index"),e.getAttribute("medium-editor-textarea-id")&&L(e)},this),this.elements=[],this.instanceHandleEditableKeydownEnter=null,this.instanceHandleEditableInput=null,function(e){e._mediumEditors&&e._mediumEditors[this.id]&&(e._mediumEditors[this.id]=null)}.call(this,this.options.contentWindow))},on:function(e,t,n,i){return this.events.attachDOMEvent(e,t,n,i),this},off:function(e,t,n,i){return this.events.detachDOMEvent(e,t,n,i),this},subscribe:function(e,t){return this.events.attachCustomEvent(e,t),this},unsubscribe:function(e,t){return this.events.detachCustomEvent(e,t),this},trigger:function(e,t,n){return this.events.triggerCustomEvent(e,t,n),this},delay:function(e){var t=this;return setTimeout(function(){t.isActive&&e()},this.options.delay)},serialize:function(){var e,t={},n=this.elements.length;for(e=0;e' + + '' + 'Link: http' + '://' + - '' + - '' + + '' + + '' + 'www' + '.google.com' + - '' + - '' + + '' + + '' + '/wow ' + 'impressive' + - ''; + ''; selectElementContentsAndFire(this.el.firstChild); @@ -358,28 +358,28 @@ describe('Autolink', function () { links[0].firstChild.removeAttribute('data-href'); // to make the next innerHTML check work consistently var expectedOutput = '' + - '' + + '' + 'Link: ' + - '' + - '' + + '' + + '' + '' + - '' + - 'http' + - '://' + - '' + - '' + - 'www' + - '.google.com' + - '' + - '' + - '/wow' + - '' + + '' + + 'http' + + '://' + + '' + + '' + + 'www' + + '.google.com' + + '' + + '' + + '/wow' + + '' + '' + - '' + - '' + + '' + + '' + ' ' + 'impressive' + - ''; + ''; expect(this.el.innerHTML).toBe(expectedOutput); }); @@ -433,7 +433,7 @@ describe('Autolink', function () { }); it('should create a link with data-auto-link=true when the text no longer matches the original link' + - ' and it has been unlinked', function () { + ' and it has been unlinked', function () { this.el.innerHTML = 'Click this ' + 'www.example.co.uk link'; diff --git a/spec/buttons.spec.js b/spec/buttons.spec.js index 628b4198f..746e9bc2a 100644 --- a/spec/buttons.spec.js +++ b/spec/buttons.spec.js @@ -869,10 +869,10 @@ describe('Buttons TestCase', function () { it('buttons should deactivate other justify buttons', function () { this.el.innerHTML = '

    lorem ipsum

    ' + - '

    lorem ipsum

    ' + - '

    lorem ipsum

    ' + - '

    lorem ipsum

    ' + - '

    lorem ipsum

    '; + '

    lorem ipsum

    ' + + '

    lorem ipsum

    ' + + '

    lorem ipsum

    ' + + '

    lorem ipsum

    '; var editor = this.newMediumEditor('.editor', { toolbar: { buttons: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'] @@ -1069,7 +1069,7 @@ describe('Buttons TestCase', function () { }); }); -function stripAttrIfEmpty(element, attribute) { +function stripAttrIfEmpty (element, attribute) { // we want to strip empty attributes (especially styles, // because the tests create style tags, inject style content, // and then remove that style content. diff --git a/spec/core-api.spec.js b/spec/core-api.spec.js index 249db48c6..1ddc14b89 100644 --- a/spec/core-api.spec.js +++ b/spec/core-api.spec.js @@ -155,7 +155,7 @@ describe('Core-API', function () { fireEvent(button, 'click'); // Edge breaks this into 3 separate tags for some reason... - var regex = new RegExp('^lorem (||)ipsum(||) dolor$'); + var regex = new RegExp('^lorem (||)ipsum(||) dolor$'); expect(editor.elements[0].innerHTML).toMatch(regex); }); }); diff --git a/spec/dyn-elements.spec.js b/spec/dyn-elements.spec.js index 64fb1bcf9..dc07d1e3f 100644 --- a/spec/dyn-elements.spec.js +++ b/spec/dyn-elements.spec.js @@ -17,14 +17,14 @@ describe('MediumEditor.DynamicElements TestCase', function () { describe('addElements', function () { it('should initialize dom element properly when adding dynamically', function () { var editor = this.newMediumEditor('.editor'), - focusedEditable, - blurredEditable, - focusListener = function (event, editable) { - focusedEditable = editable; - }, - blurListener = function (event, editable) { - blurredEditable = editable; - }; + focusedEditable, + blurredEditable, + focusListener = function (event, editable) { + focusedEditable = editable; + }, + blurListener = function (event, editable) { + blurredEditable = editable; + }; editor.subscribe('focus', focusListener); editor.subscribe('blur', blurListener); @@ -63,7 +63,8 @@ describe('MediumEditor.DynamicElements TestCase', function () { var editor = this.newMediumEditor('.editor', { anchorPreview: false }); expect(this.el.listenerInfo.length).not.toBe(0); var listenerCount = this.el.listenerInfo.length; - editor.subscribe('editableBlur', function blurHandler () { }); + editor.subscribe('editableBlur', function blurHandler () { + }); expect(this.el.listenerInfo.length).toBe(listenerCount + 1); // When adding a new element, all handlers should also be added to that element @@ -72,7 +73,8 @@ describe('MediumEditor.DynamicElements TestCase', function () { expect(this.addOne.listenerInfo.length).toBe(this.el.listenerInfo.length); // When attaching a new handler, the handler should be added to dynamically added elements too - editor.subscribe('editableMouseover', function mouseoverHandler () {}); + editor.subscribe('editableMouseover', function mouseoverHandler () { + }); expect(this.el.listenerInfo.length).toBe(listenerCount + 2); expect(this.addOne.listenerInfo.length).toBe(listenerCount + 2); @@ -127,22 +129,22 @@ describe('MediumEditor.DynamicElements TestCase', function () { expect(spy).toHaveBeenCalledWith({ target: this.addTwo, currentTarget: this.addTwo }, this.addTwo); }); - function runAddTest(inputSupported) { + function runAddTest (inputSupported) { it('should re-attach element properly when removed from dom, cleaned up and injected to dom again', function () { var originalInputSupport = MediumEditor.Events.prototype.InputEventOnContenteditableSupported; MediumEditor.Events.prototype.InputEventOnContenteditableSupported = inputSupported; var editor = this.newMediumEditor('.editor'), - focusedEditable, - firedTarget, - firedCounter, - handler = function (event, editable) { - firedTarget = editable; - firedCounter++; - }, - focusListener = function (event, editable) { - focusedEditable = editable; - }; + focusedEditable, + firedTarget, + firedCounter, + handler = function (event, editable) { + firedTarget = editable; + firedCounter++; + }, + focusListener = function (event, editable) { + focusedEditable = editable; + }; firedCounter = 0; @@ -262,7 +264,7 @@ describe('MediumEditor.DynamicElements TestCase', function () { }); }); -function detach(node, async, fn) { +function detach (node, async, fn) { var parent = node.parentNode, next = node.nextSibling; // No parent node? Abort! @@ -285,8 +287,9 @@ function detach(node, async, fn) { fn.call(node); reattach(); } + // Re-attach node to DOM. - function reattach() { + function reattach () { parent.insertBefore(node, next); } } diff --git a/spec/events.spec.js b/spec/events.spec.js index 1aac19aee..a89b06601 100644 --- a/spec/events.spec.js +++ b/spec/events.spec.js @@ -273,7 +273,8 @@ describe('MediumEditor.Events TestCase', function () { var origExecCommand = document.execCommand, editor = this.newMediumEditor('.editor'); - editor.subscribe('editableInput', function () { }); + editor.subscribe('editableInput', function () { + }); expect(document.execCommand).not.toBe(origExecCommand); editor.selectElement(editor.elements[0].firstChild); @@ -331,7 +332,7 @@ describe('MediumEditor.Events TestCase', function () { describe('Custom EditableInput Listener', function () { - function runEditableInputTests(inputSupported) { + function runEditableInputTests (inputSupported) { var namePrefix = inputSupported ? 'when Input is supported' : 'when Input is NOT supported'; it(namePrefix + ' should trigger with the corresponding editor element passed as an argument', function () { diff --git a/spec/extension.spec.js b/spec/extension.spec.js index 0ef322567..d38f8a413 100644 --- a/spec/extension.spec.js +++ b/spec/extension.spec.js @@ -52,8 +52,10 @@ describe('Extensions TestCase', function () { }); it('should set the name of property of extensions', function () { - var ExtensionOne = function () {}, - ExtensionTwo = function () {}, + var ExtensionOne = function () { + }, + ExtensionTwo = function () { + }, extOne = new ExtensionOne(), extTwo = new ExtensionTwo(), editor = this.newMediumEditor('.editor', { @@ -111,15 +113,16 @@ describe('Extensions TestCase', function () { it('should call destroy on extensions when being destroyed', function () { var TempExtension = MediumEditor.Extension.extend({ - destroy: function () {} + destroy: function () { + } }), extInstance = new TempExtension(); spyOn(extInstance, 'destroy'); var editor = this.newMediumEditor('.editor', { - extensions: { - 'temp-extension': extInstance - } - }); + extensions: { + 'temp-extension': extInstance + } + }); editor.destroy(); expect(extInstance.destroy).toHaveBeenCalled(); }); @@ -225,7 +228,8 @@ describe('Extensions TestCase', function () { describe('All extensions', function () { it('should get helper methods to call into base instance methods', function () { - var noop = function () {}, + var noop = function () { + }, helpers = { 'on': [document, 'click', noop, false], 'off': [document, 'click', noop, false], @@ -328,7 +332,8 @@ describe('Extensions TestCase', function () { button.innerText = 'XXX'; return button; }, - checkState: function () {} + checkState: function () { + } }, ExtensionWithString = { getButton: function () { @@ -336,7 +341,8 @@ describe('Extensions TestCase', function () { } }, ExtensionWithNoButton = function () { - this.init = function () {}; + this.init = function () { + }; }; it('should include extensions button into toolbar', function () { @@ -354,13 +360,13 @@ describe('Extensions TestCase', function () { it('should call checkState on extensions when toolbar selection updates', function () { var editor = this.newMediumEditor('.editor', { - toolbar: { - buttons: ['dummy'] - }, - extensions: { - 'dummy': ExtensionWithElement - } - }); + toolbar: { + buttons: ['dummy'] + }, + extensions: { + 'dummy': ExtensionWithElement + } + }); selectElementContentsAndFire(editor.elements[0].firstChild, { eventToFire: 'focus' }); spyOn(ExtensionWithElement, 'checkState').and.callThrough(); editor.checkSelection(); diff --git a/spec/fontname.spec.js b/spec/fontname.spec.js index 718d1010b..9dbd69833 100644 --- a/spec/fontname.spec.js +++ b/spec/fontname.spec.js @@ -4,7 +4,7 @@ describe('Font Name Button TestCase', function () { 'use strict'; - function testFontNameContents(el, name) { + function testFontNameContents (el, name) { expect(el.childNodes.length).toBe(1); var child = el.childNodes[0]; expect(child.nodeName.toLowerCase()).toBe('font'); @@ -69,7 +69,7 @@ describe('Font Name Button TestCase', function () { expect(document.execCommand).toHaveBeenCalledWith('fontName', false, 'Arial'); - fireEvent(fontNameExtension.getForm().querySelector('a.medium-editor-toobar-save'), 'click'); + fireEvent(fontNameExtension.getForm().querySelector('a.medium-editor-toolbar-save'), 'click'); testFontNameContents(this.el, 'Arial'); }); @@ -109,7 +109,7 @@ describe('Font Name Button TestCase', function () { selectElementContents(editor.elements[0]); fireEvent(select, 'change'); - fireEvent(fontNameExtension.getForm().querySelector('a.medium-editor-toobar-save'), 'click'); + fireEvent(fontNameExtension.getForm().querySelector('a.medium-editor-toolbar-save'), 'click'); testFontNameContents(this.el, null); // TODO: remove the element entirely instead of just the `size` attribute expect(fontNameExtension.clearFontName).toHaveBeenCalled(); }); @@ -127,7 +127,7 @@ describe('Font Name Button TestCase', function () { selectElementContentsAndFire(editor.elements[0]); button = toolbar.getToolbarElement().querySelector('[data-action="fontName"]'); - cancel = fontNameExtension.getForm().querySelector('a.medium-editor-toobar-close'); + cancel = fontNameExtension.getForm().querySelector('a.medium-editor-toolbar-close'); fireEvent(button, 'click'); expect(fontNameExtension.isDisplayed()).toBe(true); diff --git a/spec/fontsize.spec.js b/spec/fontsize.spec.js index 6d948d1a0..f933af344 100644 --- a/spec/fontsize.spec.js +++ b/spec/fontsize.spec.js @@ -4,7 +4,7 @@ describe('Font Size Button TestCase', function () { 'use strict'; - function testFontSizeContents(el, size) { + function testFontSizeContents (el, size) { expect(el.childNodes.length).toBe(1); var child = el.childNodes[0]; expect(child.nodeName.toLowerCase()).toBe('font'); @@ -69,7 +69,7 @@ describe('Font Size Button TestCase', function () { expect(document.execCommand).toHaveBeenCalledWith('fontSize', false, '7'); - fireEvent(fontSizeExtension.getForm().querySelector('a.medium-editor-toobar-save'), 'click'); + fireEvent(fontSizeExtension.getForm().querySelector('a.medium-editor-toolbar-save'), 'click'); testFontSizeContents(this.el, '7'); }); @@ -109,7 +109,7 @@ describe('Font Size Button TestCase', function () { selectElementContents(editor.elements[0]); fireEvent(input, 'change'); - fireEvent(fontSizeExtension.getForm().querySelector('a.medium-editor-toobar-save'), 'click'); + fireEvent(fontSizeExtension.getForm().querySelector('a.medium-editor-toolbar-save'), 'click'); testFontSizeContents(this.el, null); // TODO: remove the element entirely instead of just the `size` attribute expect(fontSizeExtension.clearFontSize).toHaveBeenCalled(); }); @@ -127,7 +127,7 @@ describe('Font Size Button TestCase', function () { selectElementContentsAndFire(editor.elements[0]); button = toolbar.getToolbarElement().querySelector('[data-action="fontSize"]'); - cancel = fontSizeExtension.getForm().querySelector('a.medium-editor-toobar-close'); + cancel = fontSizeExtension.getForm().querySelector('a.medium-editor-toolbar-close'); fireEvent(button, 'click'); expect(fontSizeExtension.isDisplayed()).toBe(true); diff --git a/spec/full-content.spec.js b/spec/full-content.spec.js index 92d49e0b2..5a2c7c21a 100644 --- a/spec/full-content.spec.js +++ b/spec/full-content.spec.js @@ -44,7 +44,8 @@ describe('Full Content Action TestCase', function () { // Ensure the selection is still maintained editor.execAction('strikethrough'); - expect(this.el.innerHTML).toBe('

    lorem ipsum dolor

    '); + var regex = new RegExp('^

    lorem ipsum dolor

    $'); + expect(this.el.innerHTML).toMatch(regex); }); it('should justify all contents including multiple block elements', function () { diff --git a/spec/init.spec.js b/spec/init.spec.js index a16e6d181..9d99747f5 100644 --- a/spec/init.spec.js +++ b/spec/init.spec.js @@ -97,21 +97,21 @@ describe('Initialization TestCase', function () { describe('With a valid element', function () { it('should have a default set of options', function () { var defaultOptions = { - delay: 0, - disableReturn: false, - disableDoubleReturn: false, - disableExtraSpaces: false, - disableEditing: false, - autoLink: false, - elementsContainer: document.body, - contentWindow: window, - ownerDocument: document, - buttonLabels: false, - targetBlank: false, - extensions: {}, - activeButtonClass: 'medium-editor-button-active', - spellcheck: true - }, + delay: 0, + disableReturn: false, + disableDoubleReturn: false, + disableExtraSpaces: false, + disableEditing: false, + autoLink: false, + elementsContainer: document.body, + contentWindow: window, + ownerDocument: document, + buttonLabels: false, + targetBlank: false, + extensions: {}, + activeButtonClass: 'medium-editor-button-active', + spellcheck: true + }, editor = this.newMediumEditor('.editor'); expect(Object.keys(editor.options).length).toBe(Object.keys(defaultOptions).length); expect(_.isEqual(editor.options, defaultOptions)).toBe(true); @@ -119,20 +119,20 @@ describe('Initialization TestCase', function () { it('should accept custom options values', function () { var options = { - delay: 300, - toolbar: { - diffLeft: 10, - diffTop: 5 - }, - anchor: { - placeholderText: 'test', - targetCheckboxText: 'new window?' + delay: 300, + toolbar: { + diffLeft: 10, + diffTop: 5 + }, + anchor: { + placeholderText: 'test', + targetCheckboxText: 'new window?' + }, + paste: { + forcePlainText: false, + cleanPastedHTML: true + } }, - paste: { - forcePlainText: false, - cleanPastedHTML: true - } - }, editor = this.newMediumEditor('.editor', options); Object.keys(options).forEach(function (customOption) { expect(editor.options[customOption]).toBe(options[customOption]); diff --git a/spec/keyboard-commands.spec.js b/spec/keyboard-commands.spec.js index 9488f7f1a..f108c7143 100644 --- a/spec/keyboard-commands.spec.js +++ b/spec/keyboard-commands.spec.js @@ -255,17 +255,17 @@ describe('KeyboardCommands TestCase', function () { spyOn(MediumEditor.prototype, 'execAction'); var result, editor = this.newMediumEditor('.editor', { - keyboardCommands: { - commands: [ - { - command: false, - key: 'J', - meta: true, - shift: false - } - ] - } - }); + keyboardCommands: { + commands: [ + { + command: false, + key: 'J', + meta: true, + shift: false + } + ] + } + }); selectElementContentsAndFire(editor.elements[0]); fireEvent(editor.elements[0], 'keydown', { diff --git a/spec/paste.spec.js b/spec/paste.spec.js index 1ab7f4de9..6fb8a88ea 100644 --- a/spec/paste.spec.js +++ b/spec/paste.spec.js @@ -261,11 +261,11 @@ describe('Pasting content', function () { describe('using keyboard', function () { it('should insert a custom paste-bin on keydown of CTRL + V', function () { var editor = this.newMediumEditor('.editor', { - paste: { - forcePlainText: false, - cleanPastedHTML: true - } - }); + paste: { + forcePlainText: false, + cleanPastedHTML: true + } + }); selectElementContentsAndFire(editor.elements[0].firstChild); @@ -347,7 +347,8 @@ describe('Pasting content', function () { var evt = { type: 'paste', defaultPrevented: false, - preventDefault: function () {}, + preventDefault: function () { + }, clipboardData: { types: ['text/plain', 'text/html'], getData: function () { @@ -360,7 +361,10 @@ describe('Pasting content', function () { pasteExtension.handlePasteBinPaste(evt); jasmine.clock().tick(1); - expect(spy).toHaveBeenCalledWith({ currentTarget: editor.elements[0], target: editor.elements[0] }, editor.elements[0]); + expect(spy).toHaveBeenCalledWith({ + currentTarget: editor.elements[0], + target: editor.elements[0] + }, editor.elements[0]); }); it('should do nothing if default was prevented on paste event of the paste-bin', function () { @@ -387,17 +391,18 @@ describe('Pasting content', function () { expect(contentEditables.length).toBe(2); var evt = { - type: 'paste', - defaultPrevented: true, - preventDefault: function () {}, - clipboardData: { - types: ['text/plain', 'text/html'], - getData: function () { - // do we need to return different results for the different types? text/plain, text/html - return 'pasted content'; - } + type: 'paste', + defaultPrevented: true, + preventDefault: function () { + }, + clipboardData: { + types: ['text/plain', 'text/html'], + getData: function () { + // do we need to return different results for the different types? text/plain, text/html + return 'pasted content'; } - }; + } + }; spyOn(evt, 'preventDefault'); @@ -435,16 +440,17 @@ describe('Pasting content', function () { expect(contentEditables.length).toBe(2); var evt = { - type: 'paste', - preventDefault: function () {}, - clipboardData: { - types: ['text/plain', 'text/html'], - getData: function () { - // do we need to return different results for the different types? text/plain, text/html - return 'pasted content'; - } + type: 'paste', + preventDefault: function () { + }, + clipboardData: { + types: ['text/plain', 'text/html'], + getData: function () { + // do we need to return different results for the different types? text/plain, text/html + return 'pasted content'; } - }; + } + }; spyOn(evt, 'preventDefault'); @@ -483,7 +489,8 @@ describe('Pasting content', function () { var evt = { type: 'paste', - preventDefault: function () {}, + preventDefault: function () { + }, clipboardData: { types: ['text/plain'], getData: function () { @@ -536,7 +543,8 @@ describe('Pasting content', function () { var evt = { type: 'paste', - preventDefault: function () {}, + preventDefault: function () { + }, clipboardData: { types: ['text/plain'], getData: function () { @@ -595,11 +603,11 @@ describe('Pasting content', function () { it('should filter inline rich-text when "insertHTML" command is not supported', function () { var editor = this.newMediumEditor('.editor', { - paste: { - forcePlainText: false, - cleanPastedHTML: true - } - }); + paste: { + forcePlainText: false, + cleanPastedHTML: true + } + }); spyOn(document, 'queryCommandSupported').and.returnValue(false); diff --git a/spec/placeholder.spec.js b/spec/placeholder.spec.js index 62e99a2b7..535b17f15 100644 --- a/spec/placeholder.spec.js +++ b/spec/placeholder.spec.js @@ -75,7 +75,7 @@ describe('MediumEditor.extensions.placeholder TestCase', function () { }); it('should remove the placeholder on input, and NOT on click', function () { - var editor = this.newMediumEditor('.editor', { placeholder: { hideOnClick: false }}); + var editor = this.newMediumEditor('.editor', { placeholder: { hideOnClick: false } }); expect(editor.elements[0].className).toContain('medium-editor-placeholder'); fireEvent(editor.elements[0], 'click'); expect(editor.elements[0].className).toContain('medium-editor-placeholder'); @@ -137,21 +137,21 @@ describe('MediumEditor.extensions.placeholder TestCase', function () { }); /*jslint regexp: true*/ - function validatePlaceholderContent(element, expectedValue) { + function validatePlaceholderContent (element, expectedValue) { var placeholder = window.getComputedStyle(element, ':after').getPropertyValue('content'), regex = /^attr\(([^\)]+)\)$/g, match = regex.exec(placeholder); if (match) { // In firefox, getComputedStyle().getPropertyValue('content') can return attr() instead of what attr() evaluates to expect(match[1]).toBe('data-placeholder'); - } - // When these tests run in firefox in saucelabs, for some reason the content property of the - // placeholder is 'none'. Not sure why this happens, or why this is specific to saucelabs - // but for now, just skipping the assertion in this case - else if (placeholder !== 'none') { + } else if (placeholder !== 'none') { + // When these tests run in firefox in saucelabs, for some reason the content property of the + // placeholder is 'none'. Not sure why this happens, or why this is specific to saucelabs + // but for now, just skipping the assertion in this case expect(placeholder).toMatch(new RegExp('^[\'"]' + expectedValue + '[\'"]$')); } } + /*jslint regexp: false*/ it('should add the default placeholder text when data-placeholder is not present', function () { @@ -212,10 +212,10 @@ describe('MediumEditor.extensions.placeholder TestCase', function () { it('should use custom placeholder text when passed as the placeholder.text option', function () { var placeholderText = 'Custom placeholder', editor = this.newMediumEditor('.editor', { - placeholder: { - text: placeholderText - } - }); + placeholder: { + text: placeholderText + } + }); validatePlaceholderContent(editor.elements[0], placeholderText); }); diff --git a/spec/selection.spec.js b/spec/selection.spec.js index 119dc9c78..4e371604b 100644 --- a/spec/selection.spec.js +++ b/spec/selection.spec.js @@ -43,17 +43,17 @@ describe('MediumEditor.selection TestCase', function () { }); it('should not export a position indicating the cursor is after an empty paragraph (in a complicated markup case)', - function () { - this.el.innerHTML = '

    www.google.com


    ' + - '

    Whatever

    '; - // Before the 'e' in whatever - placeCursorInsideElement(this.el.querySelector('span.target').firstChild, 0); - var exportedSelection = MediumEditor.selection.exportSelection(this.el, document); - expect(exportedSelection.emptyBlocksIndex).toEqual(undefined); - }); + function () { + this.el.innerHTML = '

    www.google.com


    ' + + '

    Whatever

    '; + // Before the 'e' in whatever + placeCursorInsideElement(this.el.querySelector('span.target').firstChild, 0); + var exportedSelection = MediumEditor.selection.exportSelection(this.el, document); + expect(exportedSelection.emptyBlocksIndex).toEqual(undefined); + }); it('should not export a position indicating the cursor is after an empty paragraph ' + - '(in a complicated markup with selection on the element)', function () { + '(in a complicated markup with selection on the element)', function () { this.el.innerHTML = '

    www.google.com


    ' + '

    Whatever

    '; // Before the 'e' in whatever @@ -324,10 +324,10 @@ describe('MediumEditor.selection TestCase', function () { // https://github.com/yabwe/medium-editor/issues/732 it('should support a selection correctly when space + newlines are separating block elements', function () { this.el.innerHTML = '
      \n' + - '
    • a link
    • \n' + - '
    • a list item
    • \n' + - '
    • target
    • \n' + - '
    '; + '
  • a link
  • \n' + + '
  • a list item
  • \n' + + '
  • target
  • \n' + + ''; var lastLi = this.el.querySelectorAll('ul > li')[2]; // Select the
  • with 'target' @@ -346,7 +346,12 @@ describe('MediumEditor.selection TestCase', function () { it('should support a selection that specifies an image is the selection', function () { this.el.innerHTML = '

    lorem ipsum dolor

    '; - MediumEditor.selection.importSelection({ start: 12, end: 12, startsWithImage: true, trailingImageCount: 1 }, this.el, document); + MediumEditor.selection.importSelection({ + start: 12, + end: 12, + startsWithImage: true, + trailingImageCount: 1 + }, this.el, document); var range = window.getSelection().getRangeAt(0); expect(range.toString()).toBe(''); expect(MediumEditor.util.isDescendant(range.endContainer, this.el.querySelector('img'), true)).toBe(true, 'the image is not within the selection'); diff --git a/spec/toolbar.spec.js b/spec/toolbar.spec.js index 07436fa06..02c78bda3 100644 --- a/spec/toolbar.spec.js +++ b/spec/toolbar.spec.js @@ -735,11 +735,11 @@ describe('MediumEditor.extensions.toolbar TestCase', function () { window.document.body.appendChild(relativeContainer); var editor = this.newMediumEditor('.editor', { - toolbar: { - relativeContainer: document.getElementById('someRelativeDiv') - } - }), - toolbarHTML = editor.getExtensionByName('toolbar').getToolbarElement().outerHTML; + toolbar: { + relativeContainer: document.getElementById('someRelativeDiv') + } + }), + toolbarHTML = editor.getExtensionByName('toolbar').getToolbarElement().outerHTML; expect(document.getElementById('someRelativeDiv').innerHTML).toBe(toolbarHTML); }); diff --git a/spec/util.spec.js b/spec/util.spec.js index de688b2bc..ea920648d 100644 --- a/spec/util.spec.js +++ b/spec/util.spec.js @@ -49,7 +49,8 @@ describe('MediumEditor.util', function () { describe('Deprecated', function () { it('should warn when a method is deprecated', function () { var testObj = { - newMethod: function () {} + newMethod: function () { + } }; spyOn(testObj, 'newMethod').and.callThrough(); spyOn(MediumEditor.util, 'warn').and.callThrough(); @@ -193,8 +194,7 @@ describe('MediumEditor.util', function () { * 1 2 3 4 5 6 */ it('should split a complex tree correctly when splitting off right part of tree', function () { - var el = this.createElement('div', '', - '123456'), + var el = this.createElement('div', '', '123456'), splitOn = el.querySelector('u').firstChild, result = MediumEditor.util.splitOffDOMTree(el, splitOn); @@ -219,8 +219,7 @@ describe('MediumEditor.util', function () { * 1 2 3 4 5 6 */ it('should split a complex tree correctly when splitting off left part of tree', function () { - var el = this.createElement('div', '', - '123456'), + var el = this.createElement('div', '', '123456'), splitOn = el.querySelector('u').firstChild, result = MediumEditor.util.splitOffDOMTree(el, splitOn, true); @@ -251,7 +250,8 @@ describe('MediumEditor.util', function () { ':443/' + 'path/to' + 'somewhere#' + - 'index notLink'), + 'index notLink' + ), firstText = el.firstChild.firstChild.splitText('Link = '.length), lastText = el.lastChild.firstChild, para = this.createElement('p', ''); @@ -260,14 +260,14 @@ describe('MediumEditor.util', function () { expect(el.innerHTML).toBe( 'Link = ' + '

    ' + - 'http' + - '://' + - 'www.exam' + - 'ple.com' + - ':443/' + - 'path/to' + - 'somewhere#' + - 'index' + + 'http' + + '://' + + 'www.exam' + + 'ple.com' + + ':443/' + + 'path/to' + + 'somewhere#' + + 'index' + '

    ' + ' notLink' ); @@ -503,10 +503,10 @@ describe('MediumEditor.util', function () { var el = this.createElement('div'); el.innerHTML = '' + '
      ' + - '
    1. Head
    2. ' + - '
    3. List Item
    4. ' + - '
    ' + - '

    paragraph

    ' + + '
  • Head
  • ' + + '
  • List Item
  • ' + + '' + + '

    paragraph

    ' + '
    '; var parts = MediumEditor.util.splitByBlockElements(el); @@ -527,9 +527,9 @@ describe('MediumEditor.util', function () { var el = this.createElement('div'); el.innerHTML = '' + '
    ' + - 'Text bold bold + italics underlined' + - '
    1. List Item
    ' + - 'Text Node' + + 'Text bold bold + italics underlined' + + '
    1. List Item
    ' + + 'Text Node' + '
    '; var parts = MediumEditor.util.splitByBlockElements(el); expect(parts.length).toBe(3); @@ -554,8 +554,8 @@ describe('MediumEditor.util', function () { it('should ignore nested comments', function () { var el = this.createElement('div'); el.innerHTML = '' + - '

    Text

    ' + - ''; + '

    Text

    ' + + ''; var parts = MediumEditor.util.splitByBlockElements(el); expect(parts.length).toBe(1); }); @@ -625,7 +625,10 @@ describe('MediumEditor.util', function () { it('should return text nodes within an element', function () { var el = this.createElement('div'); el.innerHTML = '

    Plain bold link italic underline span1 span2

    '; - var textNodes = MediumEditor.util.findOrCreateMatchingTextNodes(document, el, { start: 0, end: el.textContent.length }); + var textNodes = MediumEditor.util.findOrCreateMatchingTextNodes(document, el, { + start: 0, + end: el.textContent.length + }); expect(textNodes.length).toBe(11); expect(textNodes[0].nodeValue).toBe('Plain '); expect(textNodes[9].nodeValue).toBe('span1 '); diff --git a/src/js/core.js b/src/js/core.js index 0c59a786c..e530e640f 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -3,7 +3,7 @@ // Event handlers that shouldn't be exposed externally - function handleDisableExtraSpaces(event) { + function handleDisableExtraSpaces (event) { var node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), textContent = node.textContent, caretPositions = MediumEditor.selection.getCaretOffsets(node); @@ -13,7 +13,7 @@ } } - function handleDisabledEnterKeydown(event, element) { + function handleDisabledEnterKeydown (event, element) { if (this.options.disableReturn || element.getAttribute('data-disable-return')) { event.preventDefault(); } else if (this.options.disableDoubleReturn || element.getAttribute('data-disable-double-return')) { @@ -22,13 +22,13 @@ // if current text selection is empty OR previous sibling text is empty OR it is not a list if ((node && node.textContent.trim() === '' && node.nodeName.toLowerCase() !== 'li') || (node.previousElementSibling && node.previousElementSibling.nodeName.toLowerCase() !== 'br' && - node.previousElementSibling.textContent.trim() === '')) { + node.previousElementSibling.textContent.trim() === '')) { event.preventDefault(); } } } - function handleTabKeydown(event) { + function handleTabKeydown (event) { // Override tab only for pre nodes var node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), tag = node && node.nodeName.toLowerCase(); @@ -51,27 +51,27 @@ } } - function handleBlockDeleteKeydowns(event) { + function handleBlockDeleteKeydowns (event) { var p, node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), tagName = node.nodeName.toLowerCase(), isEmpty = /^(\s+|)?$/i, isHeader = /h\d/i; if (MediumEditor.util.isKey(event, [MediumEditor.util.keyCode.BACKSPACE, MediumEditor.util.keyCode.ENTER]) && - // has a preceeding sibling - node.previousElementSibling && - // in a header - isHeader.test(tagName) && - // at the very end of the block - MediumEditor.selection.getCaretOffsets(node).left === 0) { + // has a preceding sibling + node.previousElementSibling && + // in a header + isHeader.test(tagName) && + // at the very end of the block + MediumEditor.selection.getCaretOffsets(node).left === 0) { if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && isEmpty.test(node.previousElementSibling.innerHTML)) { - // backspacing the begining of a header into an empty previous element will + // backspacing the beginning of a header into an empty previous element will // change the tagName of the current node to prevent one // instead delete previous node and cancel the event. node.previousElementSibling.parentNode.removeChild(node.previousElementSibling); event.preventDefault(); } else if (!this.options.disableDoubleReturn && MediumEditor.util.isKey(event, MediumEditor.util.keyCode.ENTER)) { - // hitting return in the begining of a header will create empty header elements before the current one + // hitting return in the beginning of a header will create empty header elements before the current one // instead, make "


    " element, which are what happens if you hit return in an empty paragraph p = this.options.ownerDocument.createElement('p'); p.innerHTML = '
    '; @@ -79,19 +79,19 @@ event.preventDefault(); } } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.DELETE) && - // between two sibling elements - node.nextElementSibling && - node.previousElementSibling && - // not in a header - !isHeader.test(tagName) && - // in an empty tag - isEmpty.test(node.innerHTML) && - // when the next tag *is* a header - isHeader.test(node.nextElementSibling.nodeName.toLowerCase())) { + // between two sibling elements + node.nextElementSibling && + node.previousElementSibling && + // not in a header + !isHeader.test(tagName) && + // in an empty tag + isEmpty.test(node.innerHTML) && + // when the next tag *is* a header + isHeader.test(node.nextElementSibling.nodeName.toLowerCase())) { // hitting delete in an empty element preceding a header, ex: //

    [CURSOR]

    Header

    // Will cause the h1 to become a paragraph. - // Instead, delete the paragraph node and move the cursor to the begining of the h1 + // Instead, delete the paragraph node and move the cursor to the beginning of the h1 // remove node and move cursor to start of header MediumEditor.selection.moveCursor(this.options.ownerDocument, node.nextElementSibling); @@ -100,16 +100,16 @@ event.preventDefault(); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && - tagName === 'li' && - // hitting backspace inside an empty li - isEmpty.test(node.innerHTML) && - // is first element (no preceeding siblings) - !node.previousElementSibling && - // parent also does not have a sibling - !node.parentElement.previousElementSibling && - // is not the only li in a list - node.nextElementSibling && - node.nextElementSibling.nodeName.toLowerCase() === 'li') { + tagName === 'li' && + // hitting backspace inside an empty li + isEmpty.test(node.innerHTML) && + // is first element (no preceding siblings) + !node.previousElementSibling && + // parent also does not have a sibling + !node.parentElement.previousElementSibling && + // is not the only li in a list + node.nextElementSibling && + node.nextElementSibling.nodeName.toLowerCase() === 'li') { // backspacing in an empty first list element in the first list (with more elements) ex: //
    • [CURSOR]
    • List Item 2
    // will remove the first
  • but add some extra element before (varies based on browser) @@ -131,16 +131,16 @@ event.preventDefault(); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && - (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && - MediumEditor.selection.getCaretOffsets(node).left === 0) { + (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && + MediumEditor.selection.getCaretOffsets(node).left === 0) { - // when cursor is at the begining of the element and the element is
    + // when cursor is at the beginning of the element and the element is
    // then pressing backspace key should change the
    to a

    tag event.preventDefault(); MediumEditor.util.execFormatBlock(this.options.ownerDocument, 'p'); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.ENTER) && - (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && - MediumEditor.selection.getCaretOffsets(node).right === 0) { + (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) && + MediumEditor.selection.getCaretOffsets(node).right === 0) { // when cursor is at the end of

    , // then pressing enter key should create

    tag, not

    @@ -153,10 +153,10 @@ event.preventDefault(); } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) && - MediumEditor.util.isMediumEditorElement(node.parentElement) && - !node.previousElementSibling && - node.nextElementSibling && - isEmpty.test(node.innerHTML)) { + MediumEditor.util.isMediumEditorElement(node.parentElement) && + !node.previousElementSibling && + node.nextElementSibling && + isEmpty.test(node.innerHTML)) { // when cursor is in the first element, it's empty and user presses backspace, // do delete action instead to get rid of the first element and move caret to 2nd @@ -166,7 +166,7 @@ } } - function handleKeyup(event) { + function handleKeyup (event) { var node = MediumEditor.selection.getSelectionStart(this.options.ownerDocument), tagName; @@ -211,7 +211,7 @@ } } - function handleEditableInput(event, editable) { + function handleEditableInput (event, editable) { var textarea = editable.parentNode.querySelector('textarea[medium-editor-textarea-id="' + editable.getAttribute('medium-editor-textarea-id') + '"]'); if (textarea) { textarea.value = editable.innerHTML.trim(); @@ -220,7 +220,7 @@ // Internal helper methods which shouldn't be exposed externally - function addToEditors(win) { + function addToEditors (win) { if (!win._mediumEditors) { // To avoid breaking users who are assuming that the unique id on // medium-editor elements will start at 1, inserting a 'null' in the @@ -236,7 +236,7 @@ win._mediumEditors[this.id] = this; } - function removeFromEditors(win) { + function removeFromEditors (win) { if (!win._mediumEditors || !win._mediumEditors[this.id]) { return; } @@ -251,7 +251,7 @@ win._mediumEditors[this.id] = null; } - function createElementsArray(selector, doc, filterEditorElements) { + function createElementsArray (selector, doc, filterEditorElements) { var elements = []; if (!selector) { @@ -285,7 +285,7 @@ return elements; } - function cleanupTextareaElement(element) { + function cleanupTextareaElement (element) { var textarea = element.parentNode.querySelector('textarea[medium-editor-textarea-id="' + element.getAttribute('medium-editor-textarea-id') + '"]'); if (textarea) { // Un-hide the textarea @@ -297,7 +297,7 @@ } } - function setExtensionDefaults(extension, defaults) { + function setExtensionDefaults (extension, defaults) { Object.keys(defaults).forEach(function (prop) { if (extension[prop] === undefined) { extension[prop] = defaults[prop]; @@ -306,7 +306,7 @@ return extension; } - function initExtension(extension, name, instance) { + function initExtension (extension, name, instance) { var extensionDefaults = { 'window': instance.options.contentWindow, 'document': instance.options.ownerDocument, @@ -328,19 +328,19 @@ return extension; } - function isToolbarEnabled() { + function isToolbarEnabled () { // If any of the elements don't have the toolbar disabled // We need a toolbar if (this.elements.every(function (element) { - return !!element.getAttribute('data-disable-toolbar'); - })) { + return !!element.getAttribute('data-disable-toolbar'); + })) { return false; } return this.options.toolbar !== false; } - function isAnchorPreviewEnabled() { + function isAnchorPreviewEnabled () { // If toolbar is disabled, don't add if (!isToolbarEnabled.call(this)) { return false; @@ -349,34 +349,34 @@ return this.options.anchorPreview !== false; } - function isPlaceholderEnabled() { + function isPlaceholderEnabled () { return this.options.placeholder !== false; } - function isAutoLinkEnabled() { + function isAutoLinkEnabled () { return this.options.autoLink !== false; } - function isImageDraggingEnabled() { + function isImageDraggingEnabled () { return this.options.imageDragging !== false; } - function isKeyboardCommandsEnabled() { + function isKeyboardCommandsEnabled () { return this.options.keyboardCommands !== false; } - function shouldUseFileDraggingExtension() { + function shouldUseFileDraggingExtension () { // Since the file-dragging extension replaces the image-dragging extension, - // we need to check if the user passed an overrided image-dragging extension. + // we need to check if the user passed an overridden image-dragging extension. // If they have, to avoid breaking users, we won't use file-dragging extension. return !this.options.extensions['imageDragging']; } - function createContentEditable(textarea) { + function createContentEditable (textarea) { var div = this.options.ownerDocument.createElement('div'), now = Date.now(), uniqueId = 'medium-editor-' + now, - atts = textarea.attributes; + attributes = textarea.attributes; // Some browsers can move pretty fast, since we're using a timestamp // to make a unique-id, ensure that the id is actually unique on the page @@ -391,11 +391,11 @@ textarea.setAttribute('medium-editor-textarea-id', uniqueId); - // re-create all attributes from the textearea to the new created div - for (var i = 0, n = atts.length; i < n; i++) { + // re-create all attributes from the textarea to the new created div + for (var i = 0, n = attributes.length; i < n; i++) { // do not re-create existing attributes - if (!div.hasAttribute(atts[i].nodeName)) { - div.setAttribute(atts[i].nodeName, atts[i].value); + if (!div.hasAttribute(attributes[i].nodeName)) { + div.setAttribute(attributes[i].nodeName, attributes[i].value); } } @@ -418,7 +418,9 @@ return div; } - function initElement(element, editorId) { + var initialContent = {}; + + function initElement (element, editorId) { if (!element.getAttribute('data-medium-editor-element')) { if (element.nodeName.toLowerCase() === 'textarea') { element = createContentEditable.call(this, element); @@ -468,7 +470,7 @@ return element; } - function attachHandlers() { + function attachHandlers () { // attach to tabs this.subscribe('editableKeydownTab', handleTabKeydown.bind(this)); @@ -491,7 +493,7 @@ } } - function initExtensions() { + function initExtensions () { this.extensions = []; @@ -503,7 +505,7 @@ } }, this); - // 4 Cases for imageDragging + fileDragging extensons: + // 4 Cases for imageDragging + fileDragging extensions: // // 1. ImageDragging ON + No Custom Image Dragging Extension: // * Use fileDragging extension (default options) @@ -546,7 +548,7 @@ // just create the default toolbar var toolbarExtension = this.options.extensions['toolbar']; if (!toolbarExtension && isToolbarEnabled.call(this)) { - // Backwards compatability + // Backwards compatibility var toolbarOptions = MediumEditor.util.extend({}, this.options.toolbar, { allowMultiParagraphSelection: this.options.allowMultiParagraphSelection // deprecated }); @@ -560,7 +562,7 @@ } } - function mergeOptions(defaults, options) { + function mergeOptions (defaults, options) { var deprecatedProperties = [ ['allowMultiParagraphSelection', 'toolbar.allowMultiParagraphSelection'] ]; @@ -576,7 +578,7 @@ return MediumEditor.util.defaults({}, options, defaults); } - function execActionInternal(action, opts) { + function execActionInternal (action, opts) { /*jslint regexp: true*/ var appendAction = /^append-(.+)$/gi, justifyAction = /justify([A-Za-z]*)$/g, /* Detecting if is justifyCenter|Right|Left */ @@ -643,7 +645,7 @@ * Chrome may have removed
    elements and instead wrapped lines in
    elements * with a text-align property. If so, we want to fix this */ - function cleanupJustifyDivFragments(blockContainer) { + function cleanupJustifyDivFragments (blockContainer) { if (!blockContainer) { return; } @@ -684,10 +686,8 @@ } } - var initialContent = {}; - MediumEditor.prototype = { - // NOT DOCUMENTED - exposed for backwards compatability + // NOT DOCUMENTED - exposed for backwards compatibility init: function (elements, options) { this.options = mergeOptions.call(this, this.defaults, options); this.origElements = elements; @@ -1100,7 +1100,7 @@ // since we are going to create a link from an extracted text, // be sure that if we are updating a link, we won't let an empty link behind (see #754) - // (Workaroung for Chrome) + // (Workaround for Chrome) this.execAction('unlink'); exportedSelection = this.exportSelection(); @@ -1111,7 +1111,7 @@ // as our reference inside this.elements gets detached from the page when insertHTML runs. // If we just use [parentElement, 0] and [parentElement, parentElement.childNodes.length] // as the range boundaries, this happens whenever parentElement === currentEditor. - // The tradeoff to this workaround is that a orphaned tag can sometimes be left behind at + // The trade-off to this workaround is that a orphaned tag can sometimes be left behind at // the end of the editor's content. // In Gecko: // as an empty if parentElement.lastChild is a tag. @@ -1123,7 +1123,7 @@ 0, parentElement.lastChild, parentElement.lastChild.nodeType === 3 ? - parentElement.lastChild.nodeValue.length : parentElement.lastChild.childNodes.length + parentElement.lastChild.nodeValue.length : parentElement.lastChild.childNodes.length ); } else { MediumEditor.selection.select( diff --git a/src/js/events.js b/src/js/events.js index a5f7f1c7c..8c1083495 100644 --- a/src/js/events.js +++ b/src/js/events.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - function isElementDescendantOfExtension(extensions, element) { + function isElementDescendantOfExtension (extensions, element) { if (!extensions) { return false; } @@ -226,17 +226,17 @@ // Helper method to call all listeners to execCommand var callListeners = function (args, result) { - if (doc.execCommand.listeners) { - doc.execCommand.listeners.forEach(function (listener) { - listener({ - command: args[0], - value: args[2], - args: args, - result: result + if (doc.execCommand.listeners) { + doc.execCommand.listeners.forEach(function (listener) { + listener({ + command: args[0], + value: args[2], + args: args, + result: result + }); }); - }); - } - }, + } + }, // Create a wrapper method for execCommand which will: // 1) Call document.execCommand with the correct arguments @@ -466,7 +466,7 @@ if (!this.contentCache) { return; } - // An event triggered which signifies that the user may have changed someting + // An event triggered which signifies that the user may have changed something // Look in our cache of input for the contenteditables to see if something changed var index = target.getAttribute('medium-editor-index'), html = target.innerHTML; diff --git a/src/js/extension.js b/src/js/extension.js index 0872a3f10..262538435 100644 --- a/src/js/extension.js +++ b/src/js/extension.js @@ -73,11 +73,12 @@ * current instance of MediumEditor when this is called. * All helper methods will exist as well */ - init: function () {}, + init: function () { + }, /* base: [MediumEditor instance] * - * If not overriden, this will be set to the current instance + * If not overridden, this will be set to the current instance * of MediumEditor, before the init method is called */ base: undefined, @@ -167,7 +168,7 @@ /* setInactive: [function ()] * * If implemented, this function is called when MediumEditor knows - * that this extension is currently disabled. Curently, this + * that this extension is currently disabled. Currently, this * is called at the beginning of each state change for * the editor & toolbar. After calling this, MediumEditor * will attempt to update the extension, either via checkState() @@ -198,7 +199,7 @@ /* window: [Window] * - * If not overriden, this will be set to the window object + * If not overridden, this will be set to the window object * to be used by MediumEditor and its extensions. This is * passed via the 'contentWindow' option to MediumEditor * and is the global 'window' object by default @@ -207,7 +208,7 @@ /* document: [Document] * - * If not overriden, this will be set to the document object + * If not overridden, this will be set to the document object * to be used by MediumEditor and its extensions. This is * passed via the 'ownerDocument' optin to MediumEditor * and is the global 'document' object by default diff --git a/src/js/extensions/README.md b/src/js/extensions/README.md index 82ef2ef9a..0709520af 100644 --- a/src/js/extensions/README.md +++ b/src/js/extensions/README.md @@ -294,7 +294,7 @@ Currently, this method is called when updating the editor & toolbar, and if `que *** ### `setInactive()` -If implemented, this method is called when MediumEditor knows that this extension has not been applied to the current selection. Curently, this is called at the beginning of each state change for the editor & toolbar. +If implemented, this method is called when MediumEditor knows that this extension has not been applied to the current selection. Currently, this is called at the beginning of each state change for the editor & toolbar. After calling this, MediumEditor will attempt to update the extension, either via `checkState()` or the combination of `queryCommandState()`, `isAlreadyApplied(node)`, `isActive()`, and `setActive()` @@ -544,7 +544,7 @@ The `getButton()` method on each button will be called and appended to the toolb *** ## Button Helpers -The following are properties and methods of the built-in button extension implementation (`MediumEditor.extensions.button`) that can be reused and/or overriden to make custom button extensions easier to create. +The following are properties and methods of the built-in button extension implementation (`MediumEditor.extensions.button`) that can be reused and/or overridden to make custom button extensions easier to create. ### `action` _(string)_ diff --git a/src/js/extensions/WALKTHROUGH-BUTTON.md b/src/js/extensions/WALKTHROUGH-BUTTON.md index 94df33d26..ea2418a5c 100644 --- a/src/js/extensions/WALKTHROUGH-BUTTON.md +++ b/src/js/extensions/WALKTHROUGH-BUTTON.md @@ -118,7 +118,7 @@ var editor = new MediumEditor('.editable', { **PREVIEW:**

    -To change the apperances, we have: +To change the appearances, we have: 1. Changed the `innerHTML` of our button to be `` in the `init()` method 1. Added 'Highlight' as a title attribute to enable the tooltip @@ -181,7 +181,7 @@ After highlighting the text and clicking the button, the text now appears highli **NOTE:** -A great convienience of using the `toggleSelection()` method of the **CSS Class Applier** is that it will also unwrap the selection. So, since we're always calling `toggleSelection()` when the button is clicked, if you highlight the same text and click the button again, the text will go back to normal and the `` element will be removed. +A great convenience of using the `toggleSelection()` method of the **CSS Class Applier** is that it will also unwrap the selection. So, since we're always calling `toggleSelection()` when the button is clicked, if you highlight the same text and click the button again, the text will go back to normal and the `` element will be removed. **NOTE:** @@ -249,7 +249,7 @@ var HighlighterButton = MediumEditor.Extension.extend({ As shown above, now our button responds to what the user has selected. To make this final piece work, we've implemented 4 extension methods: 1. **isAlreadyApplied(node)** - * This will be called on each element which contains the user's selection, starting with the lowest element and climbing its ancestors. If any of these elements are a `` element, we return `true` since that means the selection is higlighted. + * This will be called on each element which contains the user's selection, starting with the lowest element and climbing its ancestors. If any of these elements are a `` element, we return `true` since that means the selection is highlighted. 1. **isActive()** * This should return whether the button is already active. We check this by seeing if the `'medium-editor-button-active'` class already exists on the toolbar button. 1. **setActive()** diff --git a/src/js/extensions/anchor-preview.js b/src/js/extensions/anchor-preview.js index 8963f68ba..06e99b7be 100644 --- a/src/js/extensions/anchor-preview.js +++ b/src/js/extensions/anchor-preview.js @@ -79,7 +79,7 @@ showPreview: function (anchorEl) { if (this.anchorPreview.classList.contains('medium-editor-anchor-preview-active') || - anchorEl.getAttribute('data-disable-preview')) { + anchorEl.getAttribute('data-disable-preview')) { return true; } diff --git a/src/js/extensions/anchor.js b/src/js/extensions/anchor.js index 86fd7f3d0..b550dda73 100644 --- a/src/js/extensions/anchor.js +++ b/src/js/extensions/anchor.js @@ -107,7 +107,7 @@ if (this.targetCheckbox) { // fixme: ideally, this targetCheckboxText would be a formLabel too, - // figure out how to deprecate? also consider `fa-` icon default implcations. + // figure out how to deprecate? also consider `fa-` icon default implications. template.push( '
    ', '', @@ -151,7 +151,7 @@ buttonCheckbox = this.getAnchorButtonCheckbox(); opts = opts || { value: '' }; - // TODO: This is for backwards compatability + // TODO: This is for backwards compatibility // We don't need to support the 'string' argument in 6.0.0 if (typeof opts === 'string') { opts = { @@ -256,11 +256,11 @@ // Matches protocol relative "//" // Matches common external protocols "mailto:" "tel:" "maps:" // Matches relative hash link, begins with "#" - var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):|^\#/i, + var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):|^#/i, hasScheme = urlSchemeRegex.test(value), scheme = '', // telRegex is a regex for checking if the string is a telephone number - telRegex = /^\+?\s?\(?(?:\d\s?\-?\)?){3,20}$/, + telRegex = /^\+?\s?\(?(?:\d\s?-?\)?){3,20}$/, urlParts = value.match(/^(.*?)(?:\?(.*?))?(?:#(.*))?$/), path = urlParts[1], query = urlParts[2], @@ -273,7 +273,7 @@ if (!hasScheme) { var host = path.split('/')[0]; // if the host part of the path looks like a hostname - if (host.match(/.+(\.|:).+/) || host === 'localhost') { + if (host.match(/.+([.:]).+/) || host === 'localhost') { scheme = 'http://'; } } diff --git a/src/js/extensions/auto-link.js b/src/js/extensions/auto-link.js index 1f2e8f316..0db65b24a 100644 --- a/src/js/extensions/auto-link.js +++ b/src/js/extensions/auto-link.js @@ -8,7 +8,7 @@ LINK_REGEXP; WHITESPACE_CHARS = [' ', '\t', '\n', '\r', '\u00A0', '\u2000', '\u2001', '\u2002', '\u2003', - '\u2028', '\u2029']; + '\u2028', '\u2029']; KNOWN_TLDS_FRAGMENT = 'com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|' + 'xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|' + 'bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|' + @@ -29,7 +29,7 @@ LINK_REGEXP = new RegExp(LINK_REGEXP_TEXT, 'gi'); - function nodeIsNotInsideAnchorTag(node) { + function nodeIsNotInsideAnchorTag (node) { return !MediumEditor.util.getClosestTag(node, 'a'); } @@ -188,7 +188,7 @@ for (var matchIndex = 0; matchIndex < matches.length; matchIndex++) { var matchingTextNodes = MediumEditor.util.findOrCreateMatchingTextNodes(this.document, element, - matches[matchIndex]); + matches[matchIndex]); if (this.shouldNotLink(matchingTextNodes)) { continue; } diff --git a/src/js/extensions/file-dragging.js b/src/js/extensions/file-dragging.js index 9efc5a751..ddbb068c6 100644 --- a/src/js/extensions/file-dragging.js +++ b/src/js/extensions/file-dragging.js @@ -3,7 +3,7 @@ var CLASS_DRAG_OVER = 'medium-editor-dragover'; - function clearClassNames(element) { + function clearClassNames (element) { var editable = MediumEditor.util.getContainerEditorElement(element), existing = Array.prototype.slice.call(editable.parentElement.querySelectorAll('.' + CLASS_DRAG_OVER)); diff --git a/src/js/extensions/fontname.js b/src/js/extensions/fontname.js index df54d73a2..e8bd9701c 100644 --- a/src/js/extensions/fontname.js +++ b/src/js/extensions/fontname.js @@ -103,7 +103,7 @@ this.on(form, 'click', this.handleFormClick.bind(this)); // Add font names - for (var i = 0; i' : - '✓'; + '' : + '✓'; form.appendChild(save); // Handle save button clicks (capture) @@ -129,10 +129,10 @@ // Add close button close.setAttribute('href', '#'); - close.className = 'medium-editor-toobar-close'; + close.className = 'medium-editor-toolbar-close'; close.innerHTML = this.getEditorOption('buttonLabels') === 'fontawesome' ? - '' : - '×'; + '' : + '×'; form.appendChild(close); // Handle close button clicks diff --git a/src/js/extensions/fontsize.js b/src/js/extensions/fontsize.js index 3d3247e35..6641dc6f7 100644 --- a/src/js/extensions/fontsize.js +++ b/src/js/extensions/fontsize.js @@ -109,12 +109,12 @@ // Handle typing in the textbox this.on(input, 'change', this.handleSliderChange.bind(this)); - // Add save buton + // Add save button save.setAttribute('href', '#'); - save.className = 'medium-editor-toobar-save'; + save.className = 'medium-editor-toolbar-save'; save.innerHTML = this.getEditorOption('buttonLabels') === 'fontawesome' ? - '' : - '✓'; + '' : + '✓'; form.appendChild(save); // Handle save button clicks (capture) @@ -122,10 +122,10 @@ // Add close button close.setAttribute('href', '#'); - close.className = 'medium-editor-toobar-close'; + close.className = 'medium-editor-toolbar-close'; close.innerHTML = this.getEditorOption('buttonLabels') === 'fontawesome' ? - '' : - '×'; + '' : + '×'; form.appendChild(close); // Handle close button clicks diff --git a/src/js/extensions/keyboard-commands.js b/src/js/extensions/keyboard-commands.js index dd214c714..ee8fffa56 100644 --- a/src/js/extensions/keyboard-commands.js +++ b/src/js/extensions/keyboard-commands.js @@ -67,16 +67,15 @@ if (data.meta === isMeta && data.shift === isShift && (data.alt === isAlt || - undefined === data.alt)) { // TODO deprecated: remove check for undefined === data.alt when jumping to 6.0.0 + undefined === data.alt)) { // TODO deprecated: remove check for undefined === data.alt when jumping to 6.0.0 event.preventDefault(); event.stopPropagation(); // command can be a function to execute if (typeof data.command === 'function') { data.command.apply(this); - } - // command can be false so the shortcut is just disabled - else if (false !== data.command) { + } else if (false !== data.command) { + // command can be false so the shortcut is just disabled this.execAction(data.command); } } diff --git a/src/js/extensions/paste.js b/src/js/extensions/paste.js index 0081a7907..c350f1fef 100644 --- a/src/js/extensions/paste.js +++ b/src/js/extensions/paste.js @@ -11,13 +11,12 @@ }; /*jslint regexp: true*/ - /* - jslint does not allow character negation, because the negation - will not match any unicode characters. In the regexes in this - block, negation is used specifically to match the end of an html - tag, and in fact unicode characters *should* be allowed. - */ - function createReplacements() { + + // jslint does not allow character negation, because the negation + // will not match any unicode characters. In the regexes in this + // block, negation is used specifically to match the end of an html + // tag, and in fact unicode characters *should* be allowed. + function createReplacements () { return [ // Remove anything but the contents within the BODY element [new RegExp(/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g), ''], @@ -32,7 +31,7 @@ [new RegExp(/<[^>]*docs-internal-guid[^>]*>/gi), ''], [new RegExp(/<\/b>(]*>)?$/gi), ''], - // un-html spaces and newlines inserted by OS X + // un-html spaces and newlines inserted by OS X [new RegExp(/\s+<\/span>/g), ' '], [new RegExp(/
    /g), '
    '], @@ -45,10 +44,10 @@ //[replace google docs bolds with a span to be replaced once the html is inserted [new RegExp(/]*font-weight:(bold|700)[^>]*>/gi), ''], - // replace manually entered b/i/a tags with real ones - [new RegExp(/<(\/?)(i|b|a)>/gi), '<$1$2>'], + // replace manually entered b/i/a tags with real ones + [new RegExp(/<(\/?)([iba])>/gi), '<$1$2>'], - // replace manually a tags with real ones, converting smart-quotes from google docs + // replace manually a tags with real ones, converting smart-quotes from google docs [new RegExp(/<a(?:(?!href).)+href=(?:"|”|“|"|“|”)(((?!"|”|“|"|“|”).)*)(?:"|”|“|"|“|”)(?:(?!>).)*>/gi), ''], // Newlines between paragraphs in html have no syntactic value, @@ -60,9 +59,10 @@ [new RegExp(/<\/?o:[a-z]*>/gi), ''], // Microsoft Word adds some special elements around list items - [new RegExp(/(((?!/gi), '$1'] + [new RegExp(/(((?!/gi), '$1'] ]; } + /*jslint regexp: false*/ /** @@ -74,7 +74,7 @@ * @param {doc} reference to document * @return {Object} Object with mime types and data for those mime types. */ - function getClipboardContent(event, win, doc) { + function getClipboardContent (event, win, doc) { var dataTransfer = event.clipboardData || win.clipboardData || doc.dataTransfer, data = {}; diff --git a/src/js/extensions/toolbar.js b/src/js/extensions/toolbar.js index ab94bab43..a7e16756e 100644 --- a/src/js/extensions/toolbar.js +++ b/src/js/extensions/toolbar.js @@ -154,7 +154,7 @@ } // If the button already exists as an extension, it'll be returned - // othwerise it'll create the default built-in button + // otherwise it'll create the default built-in button extension = this.base.addBuiltInExtension(buttonName, buttonOpts); if (extension && typeof extension.getButton === 'function') { @@ -251,8 +251,8 @@ handleDocumentMouseup: function (event) { // Do not trigger checkState when mouseup fires over the toolbar if (event && - event.target && - MediumEditor.util.isDescendant(this.getToolbarElement(), event.target)) { + event.target && + MediumEditor.util.isDescendant(this.getToolbarElement(), event.target)) { return false; } this.checkState(); @@ -344,7 +344,7 @@ // Responding to changes in user selection - // Checks for existance of multiple block elements in the current selection + // Checks for existence of multiple block elements in the current selection multipleBlockElementsSelected: function () { var regexEmptyHTMLTags = /<[^\/>][^>]*><\/[^>]+>/gim, // http://stackoverflow.com/questions/3129738/remove-empty-tags-using-regex regexBlockElements = new RegExp('<(' + MediumEditor.util.blockContainerElementNames.join('|') + ')[^>]*>', 'g'), @@ -375,8 +375,8 @@ * adjacent text node that actually has content in it, and move the selectionRange start there. */ if (this.standardizeSelectionStart && - selectionRange.startContainer.nodeValue && - (selectionRange.startOffset === selectionRange.startContainer.nodeValue.length)) { + selectionRange.startContainer.nodeValue && + (selectionRange.startOffset === selectionRange.startContainer.nodeValue.length)) { var adjacentNode = MediumEditor.util.findAdjacentTextNodeWithContent(MediumEditor.selection.getSelectionElement(this.window), selectionRange.startContainer, this.document); if (adjacentNode) { var offset = 0; @@ -397,7 +397,7 @@ // If no editable has focus OR selection is inside contenteditable = false // hide toolbar if (!this.base.getFocusedElement() || - MediumEditor.selection.selectionInContentEditableFalse(this.window)) { + MediumEditor.selection.selectionInContentEditableFalse(this.window)) { return this.hideToolbar(); } @@ -406,8 +406,8 @@ // hide toolbar var selectionElement = MediumEditor.selection.getSelectionElement(this.window); if (!selectionElement || - this.getEditorElements().indexOf(selectionElement) === -1 || - selectionElement.getAttribute('data-disable-toolbar')) { + this.getEditorElements().indexOf(selectionElement) === -1 || + selectionElement.getAttribute('data-disable-toolbar')) { return this.hideToolbar(); } @@ -457,8 +457,8 @@ if (typeof extension.checkState === 'function') { extension.checkState(parentNode); } else if (typeof extension.isActive === 'function' && - typeof extension.isAlreadyApplied === 'function' && - typeof extension.setActive === 'function') { + typeof extension.isAlreadyApplied === 'function' && + typeof extension.setActive === 'function') { if (!extension.isActive() && extension.isAlreadyApplied(parentNode)) { extension.setActive(); } @@ -491,8 +491,8 @@ // Make sure the selection parent isn't outside of the contenteditable if (!this.getEditorElements().some(function (element) { - return MediumEditor.util.isDescendant(element, parentNode, true); - })) { + return MediumEditor.util.isDescendant(element, parentNode, true); + })) { return; } @@ -562,11 +562,11 @@ if (scrollTop > (containerTop + container.offsetHeight - toolbarHeight - this.stickyTopOffset)) { toolbarElement.style.top = (containerTop + container.offsetHeight - toolbarHeight) + 'px'; toolbarElement.classList.remove('medium-editor-sticky-toolbar'); - // Stick the toolbar to the top of the window + // Stick the toolbar to the top of the window } else if (scrollTop > (containerTop - toolbarHeight - this.stickyTopOffset)) { toolbarElement.classList.add('medium-editor-sticky-toolbar'); toolbarElement.style.top = this.stickyTopOffset + 'px'; - // Normal static toolbar position + // Normal static toolbar position } else { toolbarElement.classList.remove('medium-editor-sticky-toolbar'); toolbarElement.style.top = containerTop - toolbarHeight + 'px'; diff --git a/src/js/globals.js b/src/js/globals.js index a69822e13..28bf47df2 100644 --- a/src/js/globals.js +++ b/src/js/globals.js @@ -1,5 +1,5 @@ /*jshint unused: false */ -function MediumEditor(elements, options) { +function MediumEditor (elements, options) { 'use strict'; return this.init(elements, options); } diff --git a/src/js/polyfills.js b/src/js/polyfills.js index 43b830433..c743e6646 100644 --- a/src/js/polyfills.js +++ b/src/js/polyfills.js @@ -191,7 +191,7 @@ if (!("classList" in document.createElement("_"))) { */ /*global self, unescape */ -/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, +/*jslint bitwise: true, regexp: true, confusion: true, vars: true, white: true, plusplus: true */ /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ diff --git a/src/js/selection.js b/src/js/selection.js index 34deaac15..eb936bb56 100644 --- a/src/js/selection.js +++ b/src/js/selection.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - function filterOnlyParentElements(node) { + function filterOnlyParentElements (node) { if (MediumEditor.util.isBlockContainer(node)) { return NodeFilter.FILTER_ACCEPT; } else { @@ -145,12 +145,11 @@ if (allowRangeToStartAtEndOfNode || selectionState.start < nextCharIndex) { range.setStart(node, selectionState.start - charIndex); foundStart = true; - } - // We're at the end of a text node where the selection could start but we shouldn't - // make the selection start here because allowRangeToStartAtEndOfNode is false. - // However, we should keep a reference to this node in case there aren't any more - // text nodes after this, so that we have somewhere to import the selection to - else { + } else { + // We're at the end of a text node where the selection could start but we shouldn't + // make the selection start here because allowRangeToStartAtEndOfNode is false. + // However, we should keep a reference to this node in case there aren't any more + // text nodes after this, so that we have somewhere to import the selection to lastTextNode = node; } } @@ -222,9 +221,9 @@ return node.nodeName.toLowerCase() === 'a'; }; if (selectionState.start === selectionState.end && - range.startContainer.nodeType === 3 && - range.startOffset === range.startContainer.nodeValue.length && - MediumEditor.util.traverseUp(range.startContainer, nodeInsideAnchorTagFunction)) { + range.startContainer.nodeType === 3 && + range.startOffset === range.startContainer.nodeValue.length && + MediumEditor.util.traverseUp(range.startContainer, nodeInsideAnchorTagFunction)) { var prevNode = range.startContainer, currentNode = range.startContainer.parentNode; while (currentNode !== null && currentNode.nodeName.toLowerCase() !== 'a') { @@ -302,7 +301,7 @@ }, // Returns -1 unless the cursor is at the beginning of a paragraph/block - // If the paragraph/block is preceeded by empty paragraphs/block (with no text) + // If the paragraph/block is preceded by empty paragraphs/block (with no text) // it will return the number of empty paragraphs before the cursor. // Otherwise, it will return 0, which indicates the cursor is at the beginning // of a paragraph/block, and not at the end of the paragraph/block before it @@ -327,9 +326,8 @@ // If there is no previous sibling, this is the first text element in the editor if (!previousSibling) { return -1; - } - // If the previous sibling has text, then there are no empty blocks before this - else if (previousSibling.nodeValue) { + } else if (previousSibling.nodeValue) { + // If the previous sibling has text, then there are no empty blocks before this return -1; } } @@ -379,7 +377,7 @@ if (next === img) { break; } - // If we haven't hit the iamge, but found text that contains content + // If we haven't hit the image, but found text that contains content // then the range doesn't start with an image if (next.nodeValue) { return false; @@ -464,7 +462,7 @@ selectionContainsContent: function (doc) { var sel = doc.getSelection(); - // collapsed selection or selection withour range doesn't contain content + // collapsed selection or selection without range doesn't contain content if (!sel || sel.isCollapsed || !sel.rangeCount) { return false; } @@ -505,7 +503,7 @@ // http://stackoverflow.com/questions/4176923/html-of-selected-text // by Tim Down - getSelectionHtml: function getSelectionHtml(doc) { + getSelectionHtml: function getSelectionHtml (doc) { var i, html = '', sel = doc.getSelection(), @@ -526,9 +524,9 @@ * * @param {DOMElement} An element containing the cursor to find offsets relative to. * @param {Range} A Range representing cursor position. Will window.getSelection if none is passed. - * @return {Object} 'left' and 'right' attributes contain offsets from begining and end of Element + * @return {Object} 'left' and 'right' attributes contain offsets from beginning and end of Element */ - getCaretOffsets: function getCaretOffsets(element, range) { + getCaretOffsets: function getCaretOffsets (element, range) { var preCaretRange, postCaretRange; if (!range) { diff --git a/src/js/util.js b/src/js/util.js index 13aba27e6..d1c9732cb 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -3,7 +3,7 @@ (function (window) { 'use strict'; - function copyInto(overwrite, dest) { + function copyInto (overwrite, dest) { var prop, sources = Array.prototype.slice.call(arguments, 2); dest = dest || {}; @@ -32,13 +32,14 @@ testText = document.createTextNode(' '); testParent.appendChild(testText); nodeContainsWorksWithTextNodes = testParent.contains(testText); - } catch (exc) {} + } catch (exc) { + } var Util = { // http://stackoverflow.com/questions/17907445/how-to-detect-ie11#comment30165888_17907562 // by rg89 - isIE: ((navigator.appName === 'Microsoft Internet Explorer') || ((navigator.appName === 'Netscape') && (new RegExp('Trident/.*rv:([0-9]{1,}[.0-9]{0,})').exec(navigator.userAgent) !== null))), + isIE: ((navigator.appName === 'Microsoft Internet Explorer') || ((navigator.appName === 'Netscape') && (new RegExp('Trident/.*rv:([0-9]+[.0-9]*)').exec(navigator.userAgent) !== null))), isEdge: (/Edge\/\d+/).exec(navigator.userAgent) !== null, @@ -67,11 +68,7 @@ * See #591 */ isMetaCtrlKey: function (event) { - if ((Util.isMac && event.metaKey) || (!Util.isMac && event.ctrlKey)) { - return true; - } - - return false; + return !!((Util.isMac && event.metaKey) || (!Util.isMac && event.ctrlKey)); }, /** @@ -88,11 +85,7 @@ return keyCode === keys; } - if (-1 === keys.indexOf(keyCode)) { - return false; - } - - return true; + return -1 !== keys.indexOf(keyCode); }, getKeyCode: function (event) { @@ -118,12 +111,12 @@ emptyElementNames: ['br', 'col', 'colgroup', 'hr', 'img', 'input', 'source', 'wbr'], - extend: function extend(/* dest, source1, source2, ...*/) { + extend: function extend (/* dest, source1, source2, ...*/) { var args = [true].concat(Array.prototype.slice.call(arguments)); return copyInto.apply(this, args); }, - defaults: function defaults(/*dest, source1, source2, ...*/) { + defaults: function defaults (/*dest, source1, source2, ...*/) { var args = [false].concat(Array.prototype.slice.call(arguments)); return copyInto.apply(this, args); }, @@ -227,12 +220,12 @@ var textIndexOfEndOfFarthestNode, endSplitPoint; textIndexOfEndOfFarthestNode = currentTextIndex + currentNode.nodeValue.length + - (newNode ? newNode.nodeValue.length : 0) - 1; + (newNode ? newNode.nodeValue.length : 0) - 1; endSplitPoint = matchEndIndex - currentTextIndex - - (newNode ? currentNode.nodeValue.length : 0); + (newNode ? currentNode.nodeValue.length : 0); if (textIndexOfEndOfFarthestNode >= matchEndIndex && - currentTextIndex !== textIndexOfEndOfFarthestNode && - endSplitPoint !== 0) { + currentTextIndex !== textIndexOfEndOfFarthestNode && + endSplitPoint !== 0) { (newNode || currentNode).splitText(endSplitPoint); } }, @@ -242,7 +235,7 @@ * 1) All text content of the elements are in separate blocks. No piece of text content should span * across multiple blocks. This means no element return by this function should have * any blocks as children. - * 2) The union of the textcontent of all of the elements returned here covers all + * 2) The union of the text content of all of the elements returned here covers all * of the text within the element. * * @@ -300,7 +293,7 @@ // - A descendant of a sibling element // - A sibling text node of an ancestor // - A descendant of a sibling element of an ancestor - findAdjacentTextNodeWithContent: function findAdjacentTextNodeWithContent(rootNode, targetNode, ownerDocument) { + findAdjacentTextNodeWithContent: function findAdjacentTextNodeWithContent (rootNode, targetNode, ownerDocument) { var pastTarget = false, nextNode, nodeIterator = ownerDocument.createNodeIterator(rootNode, NodeFilter.SHOW_TEXT, null, false); @@ -338,7 +331,7 @@ return previousSibling; }, - isDescendant: function isDescendant(parent, child, checkEquality) { + isDescendant: function isDescendant (parent, child, checkEquality) { if (!parent || !child) { return false; } @@ -363,7 +356,7 @@ }, // https://github.com/jashkenas/underscore - isElement: function isElement(obj) { + isElement: function isElement (obj) { return !!(obj && obj.nodeType === 1); }, @@ -455,7 +448,8 @@ if (!MediumEditor.util.isEdge && doc.queryCommandSupported('insertHTML')) { try { return doc.execCommand.apply(doc, ecArgs); - } catch (ignore) {} + } catch (ignore) { + } } selection = doc.getSelection(); @@ -469,13 +463,13 @@ if (Util.isMediumEditorElement(toReplace) && !toReplace.firstChild) { range.selectNode(toReplace.appendChild(doc.createTextNode(''))); } else if ((toReplace.nodeType === 3 && range.startOffset === 0 && range.endOffset === toReplace.nodeValue.length) || - (toReplace.nodeType !== 3 && toReplace.innerHTML === range.toString())) { + (toReplace.nodeType !== 3 && toReplace.innerHTML === range.toString())) { // Ensure range covers maximum amount of nodes as possible // By moving up the DOM and selecting ancestors whose only child is the range while (!Util.isMediumEditorElement(toReplace) && - toReplace.parentNode && - toReplace.parentNode.childNodes.length === 1 && - !Util.isMediumEditorElement(toReplace.parentNode)) { + toReplace.parentNode && + toReplace.parentNode.childNodes.length === 1 && + !Util.isMediumEditorElement(toReplace.parentNode)) { toReplace = toReplace.parentNode; } range.selectNode(toReplace); @@ -548,7 +542,7 @@ tagName = '<' + tagName + '>'; } - // When FF, IE and Edge, we have to handle blockquote node seperately as 'formatblock' does not work. + // When FF, IE and Edge, we have to handle blockquote node separately as 'formatblock' does not work. // https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand#Commands if (blockContainer && blockContainer.nodeName.toLowerCase() === 'blockquote') { // For IE, just use outdent @@ -1148,7 +1142,7 @@ }, guid: function () { - function _s4() { + function _s4 () { return Math .floor((1 + Math.random()) * 0x10000) .toString(16) diff --git a/src/sass/components/_anchor-preview.scss b/src/sass/components/_anchor-preview.scss index 823789224..46178641e 100644 --- a/src/sass/components/_anchor-preview.scss +++ b/src/sass/components/_anchor-preview.scss @@ -7,9 +7,9 @@ position: absolute; text-align: center; top: 0; + visibility: hidden; word-break: break-all; word-wrap: break-word; - visibility: hidden; z-index: $z-toolbar; a { diff --git a/src/sass/components/_placeholder.scss b/src/sass/components/_placeholder.scss index 3e1c26737..008526230 100644 --- a/src/sass/components/_placeholder.scss +++ b/src/sass/components/_placeholder.scss @@ -4,12 +4,12 @@ &:after { content: attr(data-placeholder) !important; font-style: italic; - position: absolute; left: 0; + margin: inherit; + padding: inherit; + position: absolute; top: 0; white-space: pre; - padding: inherit; - margin: inherit; } } @@ -19,9 +19,9 @@ &:after { content: attr(data-placeholder) !important; font-style: italic; + margin: inherit; + padding: inherit; position: relative; white-space: pre; - padding: inherit; - margin: inherit; } } diff --git a/src/sass/components/_toolbar-form.scss b/src/sass/components/_toolbar-form.scss index 9aceb0ea6..332dc1cc0 100644 --- a/src/sass/components/_toolbar-form.scss +++ b/src/sass/components/_toolbar-form.scss @@ -16,11 +16,11 @@ label { border: none; box-sizing: border-box; + display: inline-block; font-size: 14px; margin: 0; padding: 6px; width: 316px; - display: inline-block; &:focus { appearance: none; diff --git a/src/sass/components/_toolbar.scss b/src/sass/components/_toolbar.scss index 4996ca8f5..a037ff0dc 100644 --- a/src/sass/components/_toolbar.scss +++ b/src/sass/components/_toolbar.scss @@ -78,7 +78,7 @@ } .medium-editor-relative-toolbar { - position: relative; + position: relative; } .medium-editor-toolbar-active.medium-editor-stalker-toolbar { diff --git a/src/sass/medium-editor.scss b/src/sass/medium-editor.scss index b33bd573c..28bb20955 100644 --- a/src/sass/medium-editor.scss +++ b/src/sass/medium-editor.scss @@ -10,8 +10,8 @@ // contenteditable rules .medium-editor-element { - word-wrap: break-word; min-height: 30px; + word-wrap: break-word; img { max-width: 100%; diff --git a/src/sass/themes/beagle.scss b/src/sass/themes/beagle.scss index a7eb56d88..d5abb3698 100644 --- a/src/sass/themes/beagle.scss +++ b/src/sass/themes/beagle.scss @@ -32,6 +32,7 @@ $medium-editor-placeholder-color: #f8f5f3; min-width: $medium-editor-button-size; padding: 5px 12px; transition: background-color .2s ease-in, color .2s ease-in; + &:hover { background-color: $medium-editor-hover-color; color: $medium-editor-button-active-text-color; @@ -73,20 +74,23 @@ $medium-editor-placeholder-color: #f8f5f3; width: 220px; &::-webkit-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } + &:-moz-placeholder { /* Firefox 18- */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } - &::-moz-placeholder { /* Firefox 19+ */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + + &::-moz-placeholder { /* Firefox 19+ */ + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } + &:-ms-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } } @@ -96,7 +100,7 @@ $medium-editor-placeholder-color: #f8f5f3; } .medium-editor-toolbar-close { - margin-right: 16px; + margin-right: 16px; } } @@ -107,14 +111,14 @@ $medium-editor-placeholder-color: #f8f5f3; } .medium-editor-anchor-preview { - a { - color: $medium-editor-link-color; - text-decoration: none; - } + a { + color: $medium-editor-link-color; + text-decoration: none; + } } .medium-editor-toolbar-actions { - li, button { - border-radius: $medium-editor-border-radius; - } + li, button { + border-radius: $medium-editor-border-radius; + } } diff --git a/src/sass/themes/bootstrap.scss b/src/sass/themes/bootstrap.scss index d1fcc1d13..2bf4cb79b 100644 --- a/src/sass/themes/bootstrap.scss +++ b/src/sass/themes/bootstrap.scss @@ -33,6 +33,7 @@ $medium-editor-placeholder-color: #fff; height: $medium-editor-button-size; min-width: $medium-editor-button-size; transition: background-color .2s ease-in, color .2s ease-in; + &:hover { background-color: $medium-editor-hover-color; color: $medium-editor-button-active-text-color; @@ -68,20 +69,23 @@ $medium-editor-placeholder-color: #fff; height: $medium-editor-button-size; &::-webkit-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } + &:-moz-placeholder { /* Firefox 18- */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } - &::-moz-placeholder { /* Firefox 19+ */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + + &::-moz-placeholder { /* Firefox 19+ */ + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } + &:-ms-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } } diff --git a/src/sass/themes/default.scss b/src/sass/themes/default.scss index 5b2d746e2..0a8855837 100644 --- a/src/sass/themes/default.scss +++ b/src/sass/themes/default.scss @@ -15,21 +15,21 @@ $medium-editor-border-radius: 5px; } .medium-editor-toolbar { - background-color: $medium-editor-bgcolor; background: linear-gradient(to bottom, $medium-editor-bgcolor, rgba($medium-editor-bgcolor, 0.75)); + background-color: $medium-editor-bgcolor; border: 1px solid #000; border-radius: $medium-editor-border-radius; box-shadow: 0 0 3px #000; li { button { - background-color: $medium-editor-bgcolor; background: linear-gradient(to bottom, $medium-editor-bgcolor, rgba($medium-editor-bgcolor, 0.89)); + background-color: $medium-editor-bgcolor; border: 0; - border-right: 1px solid #000; border-left: 1px solid #333; border-left: 1px solid rgba(#fff, .1); - box-shadow: 0 2px 2px rgba(0,0,0,0.3); + border-right: 1px solid #000; + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3); color: #fff; height: $medium-editor-button-size; min-width: $medium-editor-button-size; @@ -52,8 +52,8 @@ $medium-editor-border-radius: 5px; } .medium-editor-button-active { - background-color: #000; background: linear-gradient(to bottom, $medium-editor-bgcolor, rgba(#000, 0.89)); + background-color: #000; color: #fff; } } diff --git a/src/sass/themes/flat.scss b/src/sass/themes/flat.scss index 8e75a3c76..15f7643de 100644 --- a/src/sass/themes/flat.scss +++ b/src/sass/themes/flat.scss @@ -8,13 +8,13 @@ $medium-editor-placeholder-color: #fff; // theme rules .medium-toolbar-arrow-under:after { - top: $medium-editor-button-size; border-color: $medium-editor-bgcolor transparent transparent transparent; + top: $medium-editor-button-size; } .medium-toolbar-arrow-over:before { - top: -8px; border-color: transparent transparent $medium-editor-bgcolor transparent; + top: -8px; } .medium-editor-toolbar { @@ -24,13 +24,14 @@ $medium-editor-placeholder-color: #fff; padding: 0; button { - min-width: $medium-editor-button-size; - height: $medium-editor-button-size; + background-color: transparent; border: none; border-right: 1px solid lighten($medium-editor-bgcolor, 20); - background-color: transparent; color: $medium-editor-link-color; + height: $medium-editor-button-size; + min-width: $medium-editor-button-size; transition: background-color .2s ease-in, color .2s ease-in; + &:hover { background-color: darken($medium-editor-bgcolor, 20); color: $medium-editor-button-active-text-color; @@ -50,28 +51,28 @@ $medium-editor-placeholder-color: #fff; .medium-editor-toolbar-form { .medium-editor-toolbar-input { - height: $medium-editor-button-size; background: $medium-editor-bgcolor; color: $medium-editor-link-color; + height: $medium-editor-button-size; &::-webkit-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } &:-moz-placeholder { /* Firefox 18- */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } - &::-moz-placeholder { /* Firefox 19+ */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + &::-moz-placeholder { /* Firefox 19+ */ + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } &:-ms-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } } diff --git a/src/sass/themes/mani.scss b/src/sass/themes/mani.scss index 16924545a..a72faa447 100644 --- a/src/sass/themes/mani.scss +++ b/src/sass/themes/mani.scss @@ -17,22 +17,23 @@ $medium-editor-border-radius: 2px; } .medium-editor-toolbar { - border: 1px solid $medium-editor-border-color; + background: linear-gradient(to top, $medium-editor-bgcolor, rgba(#fff, 1)); background-color: $medium-editor-bgcolor; background-color: rgba($medium-editor-bgcolor, .95); - background: linear-gradient(to top, $medium-editor-bgcolor, rgba(#fff, 1)); + border: 1px solid $medium-editor-border-color; border-radius: $medium-editor-border-radius; box-shadow: 0 2px 6px rgba(#000, .45); li { button { - min-width: $medium-editor-button-size; - height: $medium-editor-button-size; + background-color: transparent; border: none; border-right: 1px solid $medium-editor-border-color; - background-color: transparent; color: $medium-editor-link-color; + height: $medium-editor-button-size; + min-width: $medium-editor-button-size; transition: background-color .2s ease-in, color .2s ease-in; + &:hover { background-color: $medium-editor-bgcolor-alt; background-color: rgba($medium-editor-bgcolor-alt, .45); @@ -41,34 +42,34 @@ $medium-editor-border-radius: 2px; } .medium-editor-button-first { - border-top-left-radius: $medium-editor-border-radius; border-bottom-left-radius: $medium-editor-border-radius; + border-top-left-radius: $medium-editor-border-radius; } .medium-editor-button-last { - border-top-right-radius: $medium-editor-border-radius; border-bottom-right-radius: $medium-editor-border-radius; + border-top-right-radius: $medium-editor-border-radius; } .medium-editor-button-active { + background: linear-gradient(to bottom, $medium-editor-bgcolor, rgba(#000, .1)); background-color: $medium-editor-bgcolor-alt; background-color: rgba($medium-editor-bgcolor-alt, .45); color: $medium-editor-button-active-text-color; - background: linear-gradient(to bottom, $medium-editor-bgcolor, rgba(#000, .1)); } } } .medium-editor-toolbar-form { background: $medium-editor-bgcolor; - color: #999; border-radius: $medium-editor-border-radius; + color: #999; .medium-editor-toolbar-input { - height: $medium-editor-button-size; background: $medium-editor-bgcolor; - color: $medium-editor-link-color; box-sizing: border-box; + color: $medium-editor-link-color; + height: $medium-editor-button-size; } a { @@ -78,8 +79,8 @@ $medium-editor-border-radius: 2px; .medium-editor-toolbar-anchor-preview { background: $medium-editor-bgcolor; - color: $medium-editor-link-color; border-radius: $medium-editor-border-radius; + color: $medium-editor-link-color; } .medium-editor-placeholder:after { diff --git a/src/sass/themes/roman.scss b/src/sass/themes/roman.scss index 2bd63917a..36169e3f4 100644 --- a/src/sass/themes/roman.scss +++ b/src/sass/themes/roman.scss @@ -23,16 +23,17 @@ $medium-editor-border-radius: 5px; li { button { - min-width: $medium-editor-button-size; - height: $medium-editor-button-size; + background: linear-gradient(to bottom, $medium-editor-bgcolor, rgba(#000, .2)); + background-color: transparent; border: none; border-right: 1px solid $medium-editor-border-color; - background-color: transparent; - color: $medium-editor-link-color; box-shadow: inset 0 0 3px #f8f8e6; - background: linear-gradient(to bottom, $medium-editor-bgcolor, rgba(#000, .2)); + color: $medium-editor-link-color; + height: $medium-editor-button-size; + min-width: $medium-editor-button-size; text-shadow: 1px 4px 6px #def, 0 0 0 #000, 1px 4px 6px #def; transition: background-color .2s ease-in; + &:hover { background-color: #fff; color: $medium-editor-button-hover-text-color; @@ -41,34 +42,34 @@ $medium-editor-border-radius: 5px; } .medium-editor-button-first { - border-top-left-radius: $medium-editor-border-radius; border-bottom-left-radius: $medium-editor-border-radius; + border-top-left-radius: $medium-editor-border-radius; } .medium-editor-button-last { - border-top-right-radius: $medium-editor-border-radius; border-bottom-right-radius: $medium-editor-border-radius; + border-top-right-radius: $medium-editor-border-radius; } .medium-editor-button-active { + background: linear-gradient(to top, $medium-editor-bgcolor, rgba(#000, .1)); background-color: #ccc; color: $medium-editor-button-active-text-color; color: rgba(#000, .8); - background: linear-gradient(to top, $medium-editor-bgcolor, rgba(#000, .1)); } } } .medium-editor-toolbar-form { background: $medium-editor-bgcolor; - color: #999; border-radius: $medium-editor-border-radius; + color: #999; .medium-editor-toolbar-input { - margin: 0; - height: $medium-editor-button-size; background: $medium-editor-bgcolor; color: $medium-editor-border-color; + height: $medium-editor-button-size; + margin: 0; } a { @@ -78,8 +79,8 @@ $medium-editor-border-radius: 5px; .medium-editor-toolbar-anchor-preview { background: $medium-editor-bgcolor; - color: $medium-editor-link-color; border-radius: $medium-editor-border-radius; + color: $medium-editor-link-color; } .medium-editor-placeholder:after { diff --git a/src/sass/themes/tim.scss b/src/sass/themes/tim.scss index d11af752c..14c0a2b45 100644 --- a/src/sass/themes/tim.scss +++ b/src/sass/themes/tim.scss @@ -33,6 +33,7 @@ $medium-editor-placeholder-color: #ffedd5; height: $medium-editor-button-size; min-width: $medium-editor-button-size; transition: background-color .2s ease-in, color .2s ease-in; + &:hover { background-color: $medium-editor-hover-color; color: $medium-editor-button-active-text-color; @@ -68,20 +69,23 @@ $medium-editor-placeholder-color: #ffedd5; height: $medium-editor-button-size; &::-webkit-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } + &:-moz-placeholder { /* Firefox 18- */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } - &::-moz-placeholder { /* Firefox 19+ */ - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + + &::-moz-placeholder { /* Firefox 19+ */ + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } + &:-ms-input-placeholder { - color: $medium-editor-placeholder-color; - color: rgba($medium-editor-placeholder-color, .8); + color: $medium-editor-placeholder-color; + color: rgba($medium-editor-placeholder-color, .8); } }
  • "===c)return b.execCommand("outdent",!1,c);if((h.isFF||h.isEdge)&&"p"===c)return d=Array.prototype.slice.call(e.childNodes),d.some(function(a){return!h.isBlockContainer(a)})&&b.execCommand("formatBlock",!1,c),b.execCommand("outdent",!1,c)}return b.execCommand("formatBlock",!1,c)},setTargetBlank:function(a,b){var c,d=b||!1;if("a"===a.nodeName.toLowerCase())a.target="_blank",a.rel="noopener noreferrer";else for(a=a.getElementsByTagName("a"),c=0;cd?(e=e.parentNode,c-=1):(f=f.parentNode,d-=1);for(;e!==f;)e=e.parentNode,f=f.parentNode;return e},isElementAtBeginningOfBlock:function(a){for(var b,c;!h.isBlockContainer(a)&&!h.isMediumEditorElement(a);){for(c=a;c=c.previousSibling;)if(b=3===c.nodeType?c.nodeValue:c.textContent,b.length>0)return!1;a=a.parentNode}return!0},isMediumEditorElement:function(a){return a&&a.getAttribute&&!!a.getAttribute("data-medium-editor-element")},getContainerEditorElement:function(a){return h.traverseUp(a,function(a){return h.isMediumEditorElement(a)})},isBlockContainer:function(a){return a&&3!==a.nodeType&&-1!==h.blockContainerElementNames.indexOf(a.nodeName.toLowerCase())},getClosestBlockContainer:function(a){return h.traverseUp(a,function(a){return h.isBlockContainer(a)||h.isMediumEditorElement(a)})},getTopBlockContainer:function(a){var b=h.isBlockContainer(a)?a:!1;return h.traverseUp(a,function(a){return h.isBlockContainer(a)&&(b=a),!b&&h.isMediumEditorElement(a)?(b=a,!0):!1}),b},getFirstSelectableLeafNode:function(a){for(;a&&a.firstChild;)a=a.firstChild;if(a=h.traverseUp(a,function(a){return-1===h.emptyElementNames.indexOf(a.nodeName.toLowerCase())}),"table"===a.nodeName.toLowerCase()){var b=a.querySelector("th, td");b&&(a=b)}return a},getFirstTextNode:function(a){return h.warn("getFirstTextNode is deprecated and will be removed in version 6.0.0"),h._getFirstTextNode(a)},_getFirstTextNode:function(a){if(3===a.nodeType)return a;for(var b=0;b0){var e,f=d.getRangeAt(0),g=f.cloneRange();g.selectNodeContents(a),g.setEnd(f.startContainer,f.startOffset),e=g.toString().length,c={start:e,end:e+f.toString().length},this.doesRangeStartWithImages(f,b)&&(c.startsWithImage=!0);var h=this.getTrailingImageCount(a,c,f.endContainer,f.endOffset);if(h&&(c.trailingImageCount=h),0!==e){var i=this.getIndexRelativeToAdjacentEmptyBlocks(b,a,f.startContainer,f.startOffset);-1!==i&&(c.emptyBlocksIndex=i)}}return c},importSelection:function(a,b,c,d){if(a&&b){var e=c.createRange();e.setStart(b,0),e.collapse(!0);var f,g=b,h=[],i=0,j=!1,k=!1,l=0,m=!1,n=!1,o=null;for((d||a.startsWithImage||"undefined"!=typeof a.emptyBlocksIndex)&&(n=!0);!m&&g;)if(g.nodeType>3)g=h.pop();else{if(3!==g.nodeType||k){if(a.trailingImageCount&&k&&("img"===g.nodeName.toLowerCase()&&l++,l===a.trailingImageCount)){for(var p=0;g.parentNode.childNodes[p]!==g;)p++;e.setEnd(g.parentNode,p+1),m=!0}if(!m&&1===g.nodeType)for(var q=g.childNodes.length-1;q>=0;)h.push(g.childNodes[q]),q-=1}else f=i+g.length,!j&&a.start>=i&&a.start<=f&&(n||a.start=i&&a.end<=f&&(a.trailingImageCount?k=!0:(e.setEnd(g,a.end-i),m=!0)),i=f;m||(g=h.pop())}!j&&o&&(e.setStart(o,o.length),e.setEnd(o,o.length)),"undefined"!=typeof a.emptyBlocksIndex&&(e=this.importSelectionMoveCursorPastBlocks(c,b,a.emptyBlocksIndex,e)),d&&(e=this.importSelectionMoveCursorPastAnchor(a,e)),this.selectRange(c,e)}},importSelectionMoveCursorPastAnchor:function(b,c){var d=function(a){return"a"===a.nodeName.toLowerCase()};if(b.start===b.end&&3===c.startContainer.nodeType&&c.startOffset===c.startContainer.nodeValue.length&&a.util.traverseUp(c.startContainer,d)){for(var e=c.startContainer,f=c.startContainer.parentNode;null!==f&&"a"!==f.nodeName.toLowerCase();)f.childNodes[f.childNodes.length-1]!==e?f=null:(e=f,f=f.parentNode);if(null!==f&&"a"===f.nodeName.toLowerCase()){for(var g=null,h=0;null===g&&h0)break}else g===i.currentNode&&(h=i.currentNode);return h||(h=g),f.setStart(a.util.getFirstSelectableLeafNode(h),0),f},getIndexRelativeToAdjacentEmptyBlocks:function(c,d,e,f){if(e.textContent.length>0&&f>0)return-1;var g=e;if(3!==g.nodeType&&(g=e.childNodes[f]),g){if(!a.util.isElementAtBeginningOfBlock(g))return-1;var h=a.util.findPreviousSibling(g);if(!h)return-1;if(h.nodeValue)return-1}for(var i=a.util.getClosestBlockContainer(e),j=c.createTreeWalker(d,NodeFilter.SHOW_ELEMENT,b,!1),k=0;j.nextNode();){var l=""===j.currentNode.textContent;if((l||k>0)&&(k+=1),j.currentNode===i)return k;l||(k=0)}return k},doesRangeStartWithImages:function(a,b){if(0!==a.startOffset||1!==a.startContainer.nodeType)return!1;if("img"===a.startContainer.nodeName.toLowerCase())return!0;var c=a.startContainer.querySelector("img");if(!c)return!1;for(var d=b.createTreeWalker(a.startContainer,NodeFilter.SHOW_ALL,null,!1);d.nextNode();){var e=d.currentNode;if(e===c)break;if(e.nodeValue)return!1}return!0},getTrailingImageCount:function(a,b,c,d){if(0===d||1!==c.nodeType)return 0;if("img"!==c.nodeName.toLowerCase()&&!c.querySelector("img"))return 0;for(var e=c.childNodes[d-1];e.hasChildNodes();)e=e.lastChild;for(var f,g=a,h=[],i=0,j=!1,k=!1,l=!1,m=0;!l&&g;)if(g.nodeType>3)g=h.pop();else{if(3!==g.nodeType||k){if("img"===g.nodeName.toLowerCase()&&m++,g===e)l=!0;else if(1===g.nodeType)for(var n=g.childNodes.length-1;n>=0;)h.push(g.childNodes[n]),n-=1}else m=0,f=i+g.length,!j&&b.start>=i&&b.start<=f&&(j=!0),j&&b.end>=i&&b.end<=f&&(k=!0),i=f;l||(g=h.pop())}return m},selectionContainsContent:function(a){var b=a.getSelection();if(!b||b.isCollapsed||!b.rangeCount)return!1;if(""!==b.toString().trim())return!0;var c=this.getSelectedParentElement(b.getRangeAt(0));return!(!c||!("img"===c.nodeName.toLowerCase()||1===c.nodeType&&c.querySelector("img")))},selectionInContentEditableFalse:function(a){var b,c=this.findMatchingSelectionParent(function(a){var c=a&&a.getAttribute("contenteditable");return"true"===c&&(b=!0),"#text"!==a.nodeName&&"false"===c},a);return!b&&c},getSelectionHtml:function(a){var b,c,d,e="",f=a.getSelection();if(f.rangeCount){for(d=a.createElement("div"),b=0,c=f.rangeCount;c>b;b+=1)d.appendChild(f.getRangeAt(b).cloneContents());e=d.innerHTML}return e},getCaretOffsets:function(a,b){var c,d;return b||(b=window.getSelection().getRangeAt(0)),c=b.cloneRange(),d=b.cloneRange(),c.selectNodeContents(a),c.setEnd(b.endContainer,b.endOffset),d.selectNodeContents(a),d.setStart(b.endContainer,b.endOffset),{left:c.toString().length,right:d.toString().length}},rangeSelectsSingleNode:function(a){var b=a.startContainer;return b===a.endContainer&&b.hasChildNodes()&&a.endOffset===a.startOffset+1},getSelectedParentElement:function(a){return a?this.rangeSelectsSingleNode(a)&&3!==a.startContainer.childNodes[a.startOffset].nodeType?a.startContainer.childNodes[a.startOffset]:3===a.startContainer.nodeType?a.startContainer.parentNode:a.startContainer:null},getSelectedElements:function(a){var b,c,d,e=a.getSelection();if(!e.rangeCount||e.isCollapsed||!e.getRangeAt(0).commonAncestorContainer)return[];if(b=e.getRangeAt(0),3===b.commonAncestorContainer.nodeType){for(c=[],d=b.commonAncestorContainer;d.parentNode&&1===d.parentNode.childNodes.length;)c.push(d.parentNode),d=d.parentNode;return c}return[].filter.call(b.commonAncestorContainer.getElementsByTagName("*"),function(a){return"function"==typeof e.containsNode?e.containsNode(a,!0):!0})},selectNode:function(a,b){var c=b.createRange();c.selectNodeContents(a),this.selectRange(b,c)},select:function(a,b,c,d,e){var f=a.createRange();return f.setStart(b,c),d?f.setEnd(d,e):f.collapse(!0),this.selectRange(a,f),f},clearSelection:function(a,b){b?a.getSelection().collapseToStart():a.getSelection().collapseToEnd()},moveCursor:function(a,b,c){this.select(a,b,c)},getSelectionRange:function(a){var b=a.getSelection();return 0===b.rangeCount?null:b.getRangeAt(0)},selectRange:function(a,b){var c=a.getSelection();c.removeAllRanges(),c.addRange(b)},getSelectionStart:function(a){var b=a.getSelection().anchorNode,c=b&&3===b.nodeType?b.parentNode:b;return c}};a.selection=c}(),function(){function b(b,c){return b?b.some(function(b){if("function"!=typeof b.getInteractionElements)return!1;var d=b.getInteractionElements();return d?(Array.isArray(d)||(d=[d]),d.some(function(b){return a.util.isDescendant(b,c,!0)})):!1}):!1}var c=function(a){this.base=a,this.options=this.base.options,this.events=[],this.disabledEvents={},this.customEvents={},this.listeners={}};c.prototype={InputEventOnContenteditableSupported:!a.util.isIE&&!a.util.isEdge,attachDOMEvent:function(b,c,d,e){var f=this.base.options.contentWindow,g=this.base.options.ownerDocument;b=a.util.isElement(b)||[f,g].indexOf(b)>-1?[b]:b,Array.prototype.forEach.call(b,function(a){a.addEventListener(c,d,e),this.events.push([a,c,d,e])}.bind(this))},detachDOMEvent:function(b,c,d,e){var f,g,h=this.base.options.contentWindow,i=this.base.options.ownerDocument;b&&(b=a.util.isElement(b)||[h,i].indexOf(b)>-1?[b]:b,Array.prototype.forEach.call(b,function(a){f=this.indexOfListener(a,c,d,e),-1!==f&&(g=this.events.splice(f,1)[0],g[0].removeEventListener(g[1],g[2],g[3]))}.bind(this)))},indexOfListener:function(a,b,c,d){var e,f,g;for(e=0,f=this.events.length;f>e;e+=1)if(g=this.events[e],g[0]===a&&g[1]===b&&g[2]===c&&g[3]===d)return e;return-1},detachAllDOMEvents:function(){for(var a=this.events.pop();a;)a[0].removeEventListener(a[1],a[2],a[3]),a=this.events.pop()},detachAllEventsFromElement:function(a){for(var b=this.events.filter(function(b){return b&&b[0].getAttribute&&b[0].getAttribute("medium-editor-index")===a.getAttribute("medium-editor-index")}),c=0,d=b.length;d>c;c++){var e=b[c];this.detachDOMEvent(e[0],e[1],e[2],e[3])}},attachAllEventsToElement:function(a){this.listeners.editableInput&&(this.contentCache[a.getAttribute("medium-editor-index")]=a.innerHTML),this.eventsCache&&this.eventsCache.forEach(function(b){this.attachDOMEvent(a,b.name,b.handler.bind(this))},this)},enableCustomEvent:function(a){void 0!==this.disabledEvents[a]&&delete this.disabledEvents[a]},disableCustomEvent:function(a){this.disabledEvents[a]=!0},attachCustomEvent:function(a,b){this.setupListener(a),this.customEvents[a]||(this.customEvents[a]=[]),this.customEvents[a].push(b)},detachCustomEvent:function(a,b){var c=this.indexOfCustomListener(a,b);-1!==c&&this.customEvents[a].splice(c,1)},indexOfCustomListener:function(a,b){return this.customEvents[a]&&this.customEvents[a].length?this.customEvents[a].indexOf(b):-1},detachAllCustomEvents:function(){this.customEvents={}},triggerCustomEvent:function(a,b,c){this.customEvents[a]&&!this.disabledEvents[a]&&this.customEvents[a].forEach(function(a){a(b,c)})},destroy:function(){this.detachAllDOMEvents(),this.detachAllCustomEvents(),this.detachExecCommand(),this.base.elements&&this.base.elements.forEach(function(a){a.removeAttribute("data-medium-focused")})},attachToExecCommand:function(){this.execCommandListener||(this.execCommandListener=function(a){this.handleDocumentExecCommand(a)}.bind(this),this.wrapExecCommand(),this.options.ownerDocument.execCommand.listeners.push(this.execCommandListener))},detachExecCommand:function(){var a=this.options.ownerDocument;if(this.execCommandListener&&a.execCommand.listeners){var b=a.execCommand.listeners.indexOf(this.execCommandListener);-1!==b&&a.execCommand.listeners.splice(b,1),a.execCommand.listeners.length||this.unwrapExecCommand()}},wrapExecCommand:function(){var a=this.options.ownerDocument;if(!a.execCommand.listeners){var b=function(b,c){a.execCommand.listeners&&a.execCommand.listeners.forEach(function(a){a({command:b[0],value:b[2],args:b,result:c})})},c=function(){var c=a.execCommand.orig.apply(this,arguments);if(!a.execCommand.listeners)return c;var d=Array.prototype.slice.call(arguments);return b(d,c),c};c.orig=a.execCommand,c.listeners=[],c.callListeners=b,a.execCommand=c}},unwrapExecCommand:function(){var a=this.options.ownerDocument;a.execCommand.orig&&(a.execCommand=a.execCommand.orig)},setupListener:function(a){if(!this.listeners[a]){switch(a){case"externalInteraction":this.attachDOMEvent(this.options.ownerDocument.body,"mousedown",this.handleBodyMousedown.bind(this),!0),this.attachDOMEvent(this.options.ownerDocument.body,"click",this.handleBodyClick.bind(this),!0),this.attachDOMEvent(this.options.ownerDocument.body,"focus",this.handleBodyFocus.bind(this),!0);break;case"blur":this.setupListener("externalInteraction");break;case"focus":this.setupListener("externalInteraction");break;case"editableInput":this.contentCache={},this.base.elements.forEach(function(a){this.contentCache[a.getAttribute("medium-editor-index")]=a.innerHTML},this),this.InputEventOnContenteditableSupported&&this.attachToEachElement("input",this.handleInput),this.InputEventOnContenteditableSupported||(this.setupListener("editableKeypress"),this.keypressUpdateInput=!0,this.attachDOMEvent(document,"selectionchange",this.handleDocumentSelectionChange.bind(this)),this.attachToExecCommand());break;case"editableClick":this.attachToEachElement("click",this.handleClick);break;case"editableBlur":this.attachToEachElement("blur",this.handleBlur);break;case"editableKeypress":this.attachToEachElement("keypress",this.handleKeypress);break;case"editableKeyup":this.attachToEachElement("keyup",this.handleKeyup);break;case"editableKeydown":this.attachToEachElement("keydown",this.handleKeydown);break;case"editableKeydownSpace":this.setupListener("editableKeydown");break;case"editableKeydownEnter":this.setupListener("editableKeydown");break;case"editableKeydownTab":this.setupListener("editableKeydown");break;case"editableKeydownDelete":this.setupListener("editableKeydown");break;case"editableMouseover":this.attachToEachElement("mouseover",this.handleMouseover);break;case"editableDrag":this.attachToEachElement("dragover",this.handleDragging),this.attachToEachElement("dragleave",this.handleDragging);break;case"editableDrop":this.attachToEachElement("drop",this.handleDrop);break;case"editablePaste":this.attachToEachElement("paste",this.handlePaste)}this.listeners[a]=!0}},attachToEachElement:function(a,b){this.eventsCache||(this.eventsCache=[]),this.base.elements.forEach(function(c){this.attachDOMEvent(c,a,b.bind(this))},this),this.eventsCache.push({name:a,handler:b})},cleanupElement:function(a){var b=a.getAttribute("medium-editor-index");b&&(this.detachAllEventsFromElement(a),this.contentCache&&delete this.contentCache[b])},focusElement:function(a){a.focus(),this.updateFocus(a,{target:a,type:"focus"})},updateFocus:function(c,d){var e,f=this.base.getFocusedElement();f&&"click"===d.type&&this.lastMousedownTarget&&(a.util.isDescendant(f,this.lastMousedownTarget,!0)||b(this.base.extensions,this.lastMousedownTarget))&&(e=f),e||this.base.elements.some(function(b){return!e&&a.util.isDescendant(b,c,!0)&&(e=b),!!e},this);var g=!a.util.isDescendant(f,c,!0)&&!b(this.base.extensions,c);e!==f&&(f&&g&&(f.removeAttribute("data-medium-focused"),this.triggerCustomEvent("blur",d,f)),e&&(e.setAttribute("data-medium-focused",!0),this.triggerCustomEvent("focus",d,e))),g&&this.triggerCustomEvent("externalInteraction",d)},updateInput:function(a,b){if(this.contentCache){var c=a.getAttribute("medium-editor-index"),d=a.innerHTML;d!==this.contentCache[c]&&this.triggerCustomEvent("editableInput",b,a),this.contentCache[c]=d}},handleDocumentSelectionChange:function(b){if(b.currentTarget&&b.currentTarget.activeElement){var c,d=b.currentTarget.activeElement;this.base.elements.some(function(b){return a.util.isDescendant(b,d,!0)?(c=b,!0):!1},this),c&&this.updateInput(c,{target:d,currentTarget:c})}},handleDocumentExecCommand:function(){var a=this.base.getFocusedElement();a&&this.updateInput(a,{target:a,currentTarget:a})},handleBodyClick:function(a){this.updateFocus(a.target,a)},handleBodyFocus:function(a){this.updateFocus(a.target,a); -},handleBodyMousedown:function(a){this.lastMousedownTarget=a.target},handleInput:function(a){this.updateInput(a.currentTarget,a)},handleClick:function(a){this.triggerCustomEvent("editableClick",a,a.currentTarget)},handleBlur:function(a){this.triggerCustomEvent("editableBlur",a,a.currentTarget)},handleKeypress:function(a){if(this.triggerCustomEvent("editableKeypress",a,a.currentTarget),this.keypressUpdateInput){var b={target:a.target,currentTarget:a.currentTarget};setTimeout(function(){this.updateInput(b.currentTarget,b)}.bind(this),0)}},handleKeyup:function(a){this.triggerCustomEvent("editableKeyup",a,a.currentTarget)},handleMouseover:function(a){this.triggerCustomEvent("editableMouseover",a,a.currentTarget)},handleDragging:function(a){this.triggerCustomEvent("editableDrag",a,a.currentTarget)},handleDrop:function(a){this.triggerCustomEvent("editableDrop",a,a.currentTarget)},handlePaste:function(a){this.triggerCustomEvent("editablePaste",a,a.currentTarget)},handleKeydown:function(b){return this.triggerCustomEvent("editableKeydown",b,b.currentTarget),a.util.isKey(b,a.util.keyCode.SPACE)?this.triggerCustomEvent("editableKeydownSpace",b,b.currentTarget):a.util.isKey(b,a.util.keyCode.ENTER)||b.ctrlKey&&a.util.isKey(b,a.util.keyCode.M)?this.triggerCustomEvent("editableKeydownEnter",b,b.currentTarget):a.util.isKey(b,a.util.keyCode.TAB)?this.triggerCustomEvent("editableKeydownTab",b,b.currentTarget):a.util.isKey(b,[a.util.keyCode.DELETE,a.util.keyCode.BACKSPACE])?this.triggerCustomEvent("editableKeydownDelete",b,b.currentTarget):void 0}},a.Events=c}(),function(){var b=a.Extension.extend({action:void 0,aria:void 0,tagNames:void 0,style:void 0,useQueryState:void 0,contentDefault:void 0,contentFA:void 0,classList:void 0,attrs:void 0,constructor:function(c){b.isBuiltInButton(c)?a.Extension.call(this,this.defaults[c]):a.Extension.call(this,c)},init:function(){a.Extension.prototype.init.apply(this,arguments),this.button=this.createButton(),this.on(this.button,"click",this.handleClick.bind(this))},getButton:function(){return this.button},getAction:function(){return"function"==typeof this.action?this.action(this.base.options):this.action},getAria:function(){return"function"==typeof this.aria?this.aria(this.base.options):this.aria},getTagNames:function(){return"function"==typeof this.tagNames?this.tagNames(this.base.options):this.tagNames},createButton:function(){var a=this.document.createElement("button"),b=this.contentDefault,c=this.getAria(),d=this.getEditorOption("buttonLabels");return a.classList.add("medium-editor-action"),a.classList.add("medium-editor-action-"+this.name),this.classList&&this.classList.forEach(function(b){a.classList.add(b)}),a.setAttribute("data-action",this.getAction()),c&&(a.setAttribute("title",c),a.setAttribute("aria-label",c)),this.attrs&&Object.keys(this.attrs).forEach(function(b){a.setAttribute(b,this.attrs[b])},this),"fontawesome"===d&&this.contentFA&&(b=this.contentFA),a.innerHTML=b,a},handleClick:function(a){a.preventDefault(),a.stopPropagation();var b=this.getAction();b&&this.execAction(b)},isActive:function(){return this.button.classList.contains(this.getEditorOption("activeButtonClass"))},setInactive:function(){this.button.classList.remove(this.getEditorOption("activeButtonClass")),delete this.knownState},setActive:function(){this.button.classList.add(this.getEditorOption("activeButtonClass")),delete this.knownState},queryCommandState:function(){var a=null;return this.useQueryState&&(a=this.base.queryCommandState(this.getAction())),a},isAlreadyApplied:function(a){var b,c,d=!1,e=this.getTagNames();return this.knownState===!1||this.knownState===!0?this.knownState:(e&&e.length>0&&(d=-1!==e.indexOf(a.nodeName.toLowerCase())),!d&&this.style&&(b=this.style.value.split("|"),c=this.window.getComputedStyle(a,null).getPropertyValue(this.style.prop),b.forEach(function(a){this.knownState||(d=-1!==c.indexOf(a),(d||"text-decoration"!==this.style.prop)&&(this.knownState=d))},this)),d)}});b.isBuiltInButton=function(b){return"string"==typeof b&&a.extensions.button.prototype.defaults.hasOwnProperty(b)},a.extensions.button=b}(),function(){a.extensions.button.prototype.defaults={bold:{name:"bold",action:"bold",aria:"bold",tagNames:["b","strong"],style:{prop:"font-weight",value:"700|bold"},useQueryState:!0,contentDefault:"B",contentFA:''},italic:{name:"italic",action:"italic",aria:"italic",tagNames:["i","em"],style:{prop:"font-style",value:"italic"},useQueryState:!0,contentDefault:"I",contentFA:''},underline:{name:"underline",action:"underline",aria:"underline",tagNames:["u"],style:{prop:"text-decoration",value:"underline"},useQueryState:!0,contentDefault:"U",contentFA:''},strikethrough:{name:"strikethrough",action:"strikethrough",aria:"strike through",tagNames:["strike"],style:{prop:"text-decoration",value:"line-through"},useQueryState:!0,contentDefault:"A",contentFA:''},superscript:{name:"superscript",action:"superscript",aria:"superscript",tagNames:["sup"],contentDefault:"x1",contentFA:''},subscript:{name:"subscript",action:"subscript",aria:"subscript",tagNames:["sub"],contentDefault:"x1",contentFA:''},image:{name:"image",action:"image",aria:"image",tagNames:["img"],contentDefault:"image",contentFA:''},html:{name:"html",action:"html",aria:"evaluate html",tagNames:["iframe","object"],contentDefault:"html",contentFA:''},orderedlist:{name:"orderedlist",action:"insertorderedlist",aria:"ordered list",tagNames:["ol"],useQueryState:!0,contentDefault:"1.",contentFA:''},unorderedlist:{name:"unorderedlist",action:"insertunorderedlist",aria:"unordered list",tagNames:["ul"],useQueryState:!0,contentDefault:"",contentFA:''},indent:{name:"indent",action:"indent",aria:"indent",tagNames:[],contentDefault:"",contentFA:''},outdent:{name:"outdent",action:"outdent",aria:"outdent",tagNames:[],contentDefault:"",contentFA:''},justifyCenter:{name:"justifyCenter",action:"justifyCenter",aria:"center justify",tagNames:[],style:{prop:"text-align",value:"center"},contentDefault:"C",contentFA:''},justifyFull:{name:"justifyFull",action:"justifyFull",aria:"full justify",tagNames:[],style:{prop:"text-align",value:"justify"},contentDefault:"J",contentFA:''},justifyLeft:{name:"justifyLeft",action:"justifyLeft",aria:"left justify",tagNames:[],style:{prop:"text-align",value:"left"},contentDefault:"L",contentFA:''},justifyRight:{name:"justifyRight",action:"justifyRight",aria:"right justify",tagNames:[],style:{prop:"text-align",value:"right"},contentDefault:"R",contentFA:''},removeFormat:{name:"removeFormat",aria:"remove formatting",action:"removeFormat",contentDefault:"X",contentFA:''},quote:{name:"quote",action:"append-blockquote",aria:"blockquote",tagNames:["blockquote"],contentDefault:"",contentFA:''},pre:{name:"pre",action:"append-pre",aria:"preformatted text",tagNames:["pre"],contentDefault:"0101",contentFA:''},h1:{name:"h1",action:"append-h1",aria:"header type one",tagNames:["h1"],contentDefault:"H1",contentFA:'1'},h2:{name:"h2",action:"append-h2",aria:"header type two",tagNames:["h2"],contentDefault:"H2",contentFA:'2'},h3:{name:"h3",action:"append-h3",aria:"header type three",tagNames:["h3"],contentDefault:"H3",contentFA:'3'},h4:{name:"h4",action:"append-h4",aria:"header type four",tagNames:["h4"],contentDefault:"H4",contentFA:'4'},h5:{name:"h5",action:"append-h5",aria:"header type five",tagNames:["h5"],contentDefault:"H5",contentFA:'5'},h6:{name:"h6",action:"append-h6",aria:"header type six",tagNames:["h6"],contentDefault:"H6",contentFA:'6'}}}(),function(){var b=a.extensions.button.extend({init:function(){a.extensions.button.prototype.init.apply(this,arguments)},formSaveLabel:"✓",formCloseLabel:"×",activeClass:"medium-editor-toolbar-form-active",hasForm:!0,getForm:function(){},isDisplayed:function(){return this.hasForm?this.getForm().classList.contains(this.activeClass):!1},showForm:function(){this.hasForm&&this.getForm().classList.add(this.activeClass)},hideForm:function(){this.hasForm&&this.getForm().classList.remove(this.activeClass)},showToolbarDefaultActions:function(){var a=this.base.getExtensionByName("toolbar");a&&a.showToolbarDefaultActions()},hideToolbarDefaultActions:function(){var a=this.base.getExtensionByName("toolbar");a&&a.hideToolbarDefaultActions()},setToolbarPosition:function(){var a=this.base.getExtensionByName("toolbar");a&&a.setToolbarPosition()}});a.extensions.form=b}(),function(){var b=a.extensions.form.extend({customClassOption:null,customClassOptionText:"Button",linkValidation:!1,placeholderText:"Paste or type a link",targetCheckbox:!1,targetCheckboxText:"Open in new window",name:"anchor",action:"createLink",aria:"link",tagNames:["a"],contentDefault:"#",contentFA:'',init:function(){a.extensions.form.prototype.init.apply(this,arguments),this.subscribe("editableKeydown",this.handleKeydown.bind(this))},handleClick:function(b){b.preventDefault(),b.stopPropagation();var c=a.selection.getSelectionRange(this.document);return"a"===c.startContainer.nodeName.toLowerCase()||"a"===c.endContainer.nodeName.toLowerCase()||a.util.getClosestTag(a.selection.getSelectedParentElement(c),"a")?this.execAction("unlink"):(this.isDisplayed()||this.showForm(),!1)},handleKeydown:function(b){a.util.isKey(b,a.util.keyCode.K)&&a.util.isMetaCtrlKey(b)&&!b.shiftKey&&this.handleClick(b)},getForm:function(){return this.form||(this.form=this.createForm()),this.form},getTemplate:function(){var a=[''];return a.push('',"fontawesome"===this.getEditorOption("buttonLabels")?'':this.formSaveLabel,""),a.push('',"fontawesome"===this.getEditorOption("buttonLabels")?'':this.formCloseLabel,""),this.targetCheckbox&&a.push('