diff --git a/config/webpacker.yml b/config/webpacker.yml index 7b5a11c..d6444cc 100644 --- a/config/webpacker.yml +++ b/config/webpacker.yml @@ -8,7 +8,7 @@ default: &default # Additional paths webpack should lookup modules # ['app/assets', 'engine/foo/app/assets'] - resolved_paths: [] + resolved_paths: ['vendor/assets'] # Reload manifest.json on all requests so we reload latest compiled packs cache_manifest: false diff --git a/vendor/assets/redactor/redactor.css b/vendor/assets/redactor/redactor.css new file mode 100644 index 0000000..03099f8 --- /dev/null +++ b/vendor/assets/redactor/redactor.css @@ -0,0 +1,1352 @@ +/* + Redactor 3 + + http://imperavi.com/redactor/ + + Copyright (c) 2009-2018, Imperavi LLC. + License: http://imperavi.com/redactor/license/ +*/ +@keyframes fadeIn { + from { + opacity: 0; } + to { + opacity: 1; } } + +@keyframes fadeOut { + from { + opacity: 1; } + to { + opacity: 0; } } + +.redactor-animate-hide { + display: none !important; } + +.redactor-fadeIn { + opacity: 0; + animation: fadeIn .5s ease-in-out; } + +.redactor-fadeOut { + opacity: 1; + animation: fadeOut .5s ease-in-out; } + +@font-face { + font-family: 'Redactor'; + src: url("data:application/x-font-ttf;charset=utf-8;base64,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") format("truetype"); + font-weight: normal; + font-style: normal; } + +[class^="re-icon-"], [class*=" re-icon-"] { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'Redactor' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +.re-icon-aligncenter:before { + content: "\e900"; } + +.re-icon-alignment:before, +.re-icon-alignleft:before { + content: "\e901"; } + +.re-icon-alignright:before { + content: "\e902"; } + +.re-icon-bold:before { + content: "\e903"; } + +.re-icon-bookmark:before { + content: "\e904"; } + +.re-icon-clips:before { + content: "\e905"; } + +.re-icon-codesnippets:before { + content: "\e906"; } + +.re-icon-deleted:before { + content: "\e907"; } + +.re-icon-expand:before { + content: "\e908"; } + +.re-icon-file:before { + content: "\e909"; } + +.re-icon-fontcolor:before { + content: "\e90a"; } + +.re-icon-fontfamily:before { + content: "\e90b"; } + +.re-icon-fontsize:before { + content: "\e90c"; } + +.re-icon-format:before { + content: "\e90d"; } + +.re-icon-html:before { + content: "\e90e"; } + +.re-icon-imagecenter:before { + content: "\e90f"; } + +.re-icon-imageleft:before { + content: "\e910"; } + +.re-icon-imageright:before { + content: "\e911"; } + +.re-icon-image:before { + content: "\e912"; } + +.re-icon-indent:before { + content: "\e913"; } + +.re-icon-inline:before { + content: "\e914"; } + +.re-icon-italic:before { + content: "\e915"; } + +.re-icon-line:before, +.re-icon-horizontalrule:before { + content: "\e916"; } + +.re-icon-link:before { + content: "\e917"; } + +.re-icon-ol:before, +.re-icon-ordered:before { + content: "\e918"; } + +.re-icon-outdent:before { + content: "\e919"; } + +.re-icon-properties:before { + content: "\e91a"; } + +.re-icon-readmore:before { + content: "\e91b"; } + +.re-icon-redo:before { + content: "\e91c"; } + +.re-icon-retract:before { + content: "\e91d"; } + +.re-icon-specialcharacters:before { + content: "\e91e"; } + +.re-icon-sub:before { + content: "\e91f"; } + +.re-icon-sup:before { + content: "\e920"; } + +.re-icon-table:before { + content: "\e921"; } + +.re-icon-textdirection:before { + content: "\e922"; } + +.re-icon-toggle:before { + content: "\e923"; } + +.re-icon-underline:before { + content: "\e924"; } + +.re-icon-undo:before { + content: "\e925"; } + +.re-icon-ul:before, +.re-icon-lists:before, +.re-icon-unordered:before { + content: "\e926"; } + +.re-icon-variable:before { + content: "\e927"; } + +.re-icon-video:before { + content: "\e928"; } + +.re-icon-widget:before { + content: "\e929"; } + +.redactor-box, +.redactor-box textarea { + z-index: auto; } + +.redactor-box { + position: relative; + box-sizing: border-box; } + .redactor-box.redactor-styles-on { + margin: 0; + padding: 0; + background: #fff; + border: 1px solid rgba(0, 0, 0, 0.075); + border-radius: 3px; + box-shadow: none; } + .redactor-box.redactor-inline { + position: static; } + +.redactor-focus.redactor-styles-on, +.redactor-focus:focus.redactor-styles-on { + border-color: #82b7ec !important; } + +.redactor-over:hover.redactor-styles-on { + border-color: #ee698a !important; } + +.redactor-source-view, +.redactor-source-view.redactor-styles-on { + border-color: #000 !important; } + +.redactor-in { + position: relative; + overflow: auto; + white-space: normal; + box-sizing: border-box; } + .redactor-in:focus { + outline: none; } + +.redactor-inline .redactor-in { + overflow: hidden; } + +.redactor-in *, +.redactor-read-only * { + outline: none !important; } + +.redactor-in h1:empty, +.redactor-in h2:empty, +.redactor-in h3:empty, +.redactor-in h4:empty, +.redactor-in h5:empty, +.redactor-in h6:empty, +.redactor-in p:empty, +.redactor-in blockquote:empty { + min-height: 1.5em; } + +.redactor-in strong:empty, .redactor-in b:empty, .redactor-in em:empty, .redactor-in i:empty, .redactor-in span:empty, .redactor-in sup:empty, .redactor-in sub:empty, .redactor-in u:empty, .redactor-in ins:empty { + display: inline-block; + min-width: 1px; + min-height: 1rem; } + +.redactor-in table { + empty-cells: show; } + +.redactor-in li figure { + width: auto; + display: inline-block; + margin: 0; + vertical-align: top; } + +.redactor-in figcaption:focus, +.redactor-in figure code:focus, +.redactor-in figure pre:focus, +.redactor-in table td:focus, +.redactor-in table th:focus { + outline: none; } + +.redactor-in figure[data-redactor-type=line] { + margin-top: 1em; + padding: 6px 0; + vertical-align: baseline; } + .redactor-in figure[data-redactor-type=line] hr { + margin: 0; + height: 3px; + border: none; + background: rgba(0, 0, 0, 0.1); } + +.redactor-component { + position: relative; } + +.redactor-component[data-redactor-type="widget"]:before, +.redactor-component[data-redactor-type="video"]:before { + width: 100%; + height: 100%; + content: ""; + display: block; + position: absolute; + z-index: 1; } + +.redactor-component[data-redactor-type=image], +.redactor-component[data-redactor-type=widget] { + clear: both; } + +.redactor-component[data-redactor-type=variable] { + white-space: nowrap; + background: rgba(0, 125, 255, 0.75); + color: #fff; + display: inline-block; + padding: 3px 6px; + line-height: 1; + border-radius: 4px; + cursor: pointer; } + +.redactor-component-active { + outline: 5px solid rgba(0, 125, 255, 0.5) !important; } + +.redactor-component-active[data-redactor-type=image] { + outline: none !important; } + .redactor-component-active[data-redactor-type=image] img { + outline: 5px solid rgba(0, 125, 255, 0.5) !important; } + +.redactor-component-active[data-redactor-type=variable] { + outline: none !important; + background: #ee698a; } + +.redactor-component-active[data-redactor-type=video] { + outline: none !important; } + .redactor-component-active[data-redactor-type=video] iframe { + outline: 5px solid rgba(0, 125, 255, 0.5) !important; } + +.redactor-blur.redactor-styles-on .redactor-component-active { + outline: 5px solid #ddd !important; } + .redactor-blur.redactor-styles-on .redactor-component-active[data-redactor-type=image] { + outline: none !important; } + .redactor-blur.redactor-styles-on .redactor-component-active[data-redactor-type=image] img { + outline: 5px solid #ddd !important; } + .redactor-blur.redactor-styles-on .redactor-component-active[data-redactor-type=video] { + outline: none !important; } + .redactor-blur.redactor-styles-on .redactor-component-active[data-redactor-type=video] iframe { + outline: 5px solid #ddd !important; } + .redactor-blur.redactor-styles-on .redactor-component-active[data-redactor-type=variable] { + outline: none !important; + background: #ddd; } + +.redactor-component-caret { + position: absolute; + left: -9999px; } + +.redactor-textnodes-wrapper { + display: inline-block; } + +#redactor-image-resizer { + position: absolute; + z-index: 1050; + background-color: rgba(0, 125, 255, 0.9); + width: 13px; + height: 13px; + border: 1px solid #fff; + cursor: move; + cursor: nwse-resize; } + +.redactor-file-item { + display: inline-block; + line-height: 1; + padding: 4px 12px; + border-radius: 16px; + border: 1px solid rgba(0, 0, 0, 0.2); } + +.redactor-file-remover { + margin-left: 2px; + position: relative; + right: -3px; + display: inline-block; + padding: 0 3px; + cursor: pointer; + opacity: .5; } + .redactor-file-remover:hover { + opacity: 1; } + +#redactor-overlay { + position: fixed; + z-index: 1051; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(16, 16, 18, 0.18); } + #redactor-overlay > .redactor-close { + position: fixed; + top: 1rem; + right: 1rem; } + +.redactor-source, +.redactor-source:hover, +.redactor-source:focus { + text-align: left; + box-sizing: border-box; + font-family: Consolas, Menlo, Monaco, "Courier New", monospace; + width: 100%; + display: block; + margin: 0; + border: none; + box-shadow: none; + border-radius: 0; + background: #252525; + color: #ccc; + font-size: 15px; + outline: none; + padding: 10px 18px 20px 18px; + line-height: 1.5; + resize: vertical; } + +.redactor-box[dir="rtl"] .redactor-source { + direction: ltr; } + +.redactor-placeholder:before { + position: absolute; + content: attr(placeholder); + color: rgba(0, 0, 0, 0.4); + font-weight: normal; } + +.redactor-in figcaption[placeholder]:empty:before { + content: attr(placeholder); + color: rgba(0, 0, 0, 0.4); + font-weight: normal; } + +.redactor-in figcaption[placeholder]:empty:focus:before { + content: ""; } + +.redactor-statusbar { + font-family: Consolas, Menlo, Monaco, "Courier New", monospace; + margin: 0; + padding: 8px 10px; + position: relative; + overflow: hidden; + list-style: none; + background: #f8f8f8; + box-sizing: border-box; + border: none; } + .redactor-statusbar li { + float: left; + font-size: 12px; + color: rgba(0, 0, 0, 0.5); + padding: 0 10px; + line-height: 16px; + border-right: 1px solid rgba(0, 0, 0, 0.1); } + .redactor-statusbar li:last-child { + border-right-color: transparent; } + .redactor-statusbar a { + color: rgba(0, 0, 0, 0.5); + text-decoration: underline; } + .redactor-statusbar a:hover { + color: #f03c69; + text-decoration: underline; } + .redactor-statusbar:empty { + display: none; } + +.redactor-toolbar-wrapper { + position: relative; } + +.redactor-toolbar, +.redactor-air { + z-index: 100; + font-family: "Trebuchet MS", "Helvetica Neue", Helvetica, Tahoma, sans-serif; + position: relative; + margin: 0 !important; + padding: 0; + list-style: none !important; + line-height: 1 !important; + background: none; + border: none; + box-sizing: border-box; } + +.redactor-box.redactor-styles-on .redactor-toolbar { + padding: 18px 16px 0 16px; } + +.redactor-toolbar a, +.redactor-air a { + display: inline-block; + box-sizing: border-box; + font-size: 14px; + text-align: center; + padding: 10px 15px 9px 15px; + cursor: pointer; + outline: none; + border: none; + vertical-align: middle; + text-decoration: none; + zoom: 1; + position: relative; + color: rgba(0, 0, 0, 0.85); + border-radius: 2px; + background: rgba(255, 255, 255, 0.97); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.22); + margin-right: 5px; + margin-bottom: 4px; } + +.redactor-toolbar a.re-button-icon, +.redactor-air a.re-button-icon { + font-size: 16px; + padding: 9px 15px 6px 15px; } + +.redactor-toolbar a:hover, +.redactor-air a:hover { + outline: none; + color: #fff; + background: #449aef; } + +.redactor-toolbar a.redactor-button-active { + background: rgba(245, 245, 245, 0.95); + color: rgba(0, 0, 0, 0.4); } + +.redactor-toolbar a.redactor-button-disabled, +.redactor-air a.redactor-button-disabled { + opacity: 0.3; } + .redactor-toolbar a.redactor-button-disabled:hover, + .redactor-air a.redactor-button-disabled:hover { + color: #333; + outline: none; + background-color: transparent !important; + cursor: default; } + +.redactor-source-view .redactor-toolbar { + background: #252525; } + +.redactor-source-view .redactor-toolbar a { + background: #000; + color: #fff; } + .redactor-source-view .redactor-toolbar a:hover { + background: #449aef; } + +.redactor-source-view .redactor-toolbar a.redactor-button-disabled:hover { + color: #fff !important; + background-color: #000 !important; } + +.re-button-tooltip { + display: none; + position: absolute; + white-space: nowrap; + top: 0; + z-index: 1052; + background: rgba(0, 0, 0, 0.9); + border-radius: 3px; + padding: 5px 9px; + color: rgba(255, 255, 255, 0.8); + font-size: 12px; + line-height: 1; + font-family: Consolas, Menlo, Monaco, "Courier New", monospace; } + .re-button-tooltip:after { + bottom: 100%; + left: 50%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-color: none; + border-bottom-color: rgba(0, 0, 0, 0.9); + border-width: 4px; + margin-left: -4px; } + +.redactor-toolbar-wrapper-air { + position: absolute; + z-index: 100; } + +.redactor-air { + padding: 6px 3px 2px 8px; + max-width: 576px; + min-width: 200px; + border-radius: 4px; + background: rgba(0, 0, 0, 0.97); } + +.redactor-air a { + background: rgba(37, 37, 37, 0.95); + box-shadow: none; + color: rgba(255, 255, 255, 0.9); } + +.redactor-air a:hover { + background: #3d79f2; } + +.redactor-air a.redactor-button-active { + background-color: rgba(255, 255, 255, 0.15); + color: #fff; } + +.redactor-air a.redactor-button-disabled:hover { + color: #fff; } + +.redactor-air-helper { + position: absolute; + right: 0; + top: 0; + line-height: 1; + font-size: 15px; + color: #000; + background: rgba(255, 255, 255, 0.85); + border-bottom-left-radius: 4px; + padding: 7px 10px 6px 10px; + cursor: pointer; } + .redactor-air-helper:hover { + background: #fff; } + +.redactor-voice-label { + display: none; } + +.redactor-context-toolbar { + position: absolute; + top: 0; + left: 0; + z-index: 1051; + background-color: rgba(0, 0, 0, 0.95); + color: #555; + border-radius: 4px; + padding: 6px 18px 7px 18px; + line-height: 1.5; + font-family: Consolas, Menlo, Monaco, "Courier New", monospace; } + .redactor-context-toolbar a { + font-size: 12px; + color: #ccc; + text-decoration: none; + display: inline-block; + padding: 2px 0 1px 12px; } + .redactor-context-toolbar a:first-child { + padding-left: 0; } + .redactor-context-toolbar a i { + position: relative; + top: 3px; + font-size: 16px; } + .redactor-context-toolbar a:before { + content: ''; + padding-left: 10px; + border-left: 1px solid rgba(255, 255, 255, 0.3); } + .redactor-context-toolbar a:hover { + color: #fff; } + .redactor-context-toolbar a:first-child:before { + padding-left: 0; + border-left: none; } + +.redactor-context-toolbar[dir="rtl"] a { + padding: 2px 12px 1px 0; } + +.redactor-context-toolbar[dir="rtl"] a:first-child { + padding-right: 0; } + +.redactor-context-toolbar[dir="rtl"] a:before { + padding-left: 0px; + padding-right: 10px; + border-right: 1px solid rgba(255, 255, 255, 0.3); + border-left: none; } + +.redactor-context-toolbar[dir="rtl"] a:first-child:before { + padding-right: 0; + border-right: none; } + +.redactor-dropdown { + font-family: "Trebuchet MS", "Helvetica Neue", Helvetica, Tahoma, sans-serif; + display: none; + position: absolute; + z-index: 1051; + background-color: #fff; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2); + border-radius: 2px; + width: 264px; + max-height: 250px; + margin: 0; + margin-top: -1px; + overflow: auto; + font-size: 15px; + padding: 0; } + .redactor-dropdown a span { + display: inline-block; + line-height: 1; + padding: 2px 4px; + border-radius: 3px; } + .redactor-dropdown a { + display: block; + text-decoration: none; + padding: 10px 8px; + white-space: nowrap; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); } + .redactor-dropdown a:last-child { + border-bottom-color: transparent; } + .redactor-dropdown a { + color: #000; } + .redactor-dropdown a:hover { + color: #fff !important; + background-color: #449aef !important; } + .redactor-dropdown a.redactor-dropdown-item-disabled { + color: rgba(0, 0, 0, 0.4); + background: #fff; } + +.redactor-dropdown-cells { + margin: 10px auto; } + .redactor-dropdown-cells a, + .redactor-dropdown-cells span { + float: left; + cursor: pointer; + box-sizing: border-box; + text-align: center; + padding: 0; + margin: 0; + font-size: 14px; } + +.redactor-dropdown-selector { + display: flex; + text-align: center; } + .redactor-dropdown-selector span { + flex-grow: 1; + font-size: 12px; + padding: 8px; + cursor: pointer; } + .redactor-dropdown-selector span:hover { + background: #eee; } + .redactor-dropdown-selector span.active { + cursor: text; + color: rgba(0, 0, 0, 0.3); + background: #eee; } + +.redactor-dropdown-format .redactor-dropdown-item-blockquote { + color: rgba(0, 0, 0, 0.4); + font-style: italic; } + +.redactor-dropdown-format .redactor-dropdown-item-pre { + font-family: monospace, sans-serif; } + +.redactor-dropdown-format .redactor-dropdown-item-h1 { + font-size: 40px; + font-weight: bold; + line-height: 32px; } + +.redactor-dropdown-format .redactor-dropdown-item-h2 { + font-size: 32px; + font-weight: bold; + line-height: 32px; } + +.redactor-dropdown-format .redactor-dropdown-item-h3 { + font-size: 24px; + font-weight: bold; + line-height: 24px; } + +.redactor-dropdown-format .redactor-dropdown-item-h4 { + font-size: 21px; + font-weight: bold; + line-height: 24px; } + +.redactor-dropdown-format .redactor-dropdown-item-h5 { + font-size: 18px; + font-weight: bold; + line-height: 24px; } + +.redactor-dropdown-format .redactor-dropdown-item-h6 { + font-size: 14px; + text-transform: uppercase; + font-weight: bold; + line-height: 24px; } + +#redactor-modal { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + overflow-x: hidden; + overflow-y: auto; + z-index: 1051; + font-family: "Trebuchet MS", "Helvetica Neue", Helvetica, Tahoma, sans-serif; + line-height: 24px; } + +.redactor-modal { + position: relative; + margin: 16px auto; + padding: 0; + background: #fff; + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07), 0 2px 15px rgba(80, 80, 80, 0.25); + border-radius: 3px; + color: #000; } + .redactor-modal form { + margin: 0; + padding: 0; + box-sizing: border-box; } + .redactor-modal input, + .redactor-modal select, + .redactor-modal textarea { + box-sizing: border-box; + display: block; + width: 100%; + font-family: inherit; + font-size: 16px; + height: 40px; + outline: none; + vertical-align: middle; + background-color: #fff; + border: 1px solid #cacfd4; + border-radius: 0.1875em; + box-shadow: none; + padding: 0 .5em; } + .redactor-modal textarea { + padding: .5em; + height: auto; + line-height: 1.5; + vertical-align: top; } + .redactor-modal select { + -webkit-appearance: none; + background-image: url('data:image/svg+xml;utf8,'); + background-repeat: no-repeat; + background-position: right .65em center; + padding-right: 28px; } + .redactor-modal select[multiple] { + background-image: none; + height: auto; + padding: .5em .75em; } + .redactor-modal input[type="file"] { + width: auto; + border: none; + padding: 0; + height: auto; + background: none; + box-shadow: none; + display: inline-block; } + .redactor-modal input[type="radio"], + .redactor-modal input[type="checkbox"] { + display: inline-block; + width: auto; + height: auto; + padding: 0; + vertical-align: middle; + position: relative; + bottom: 0.15rem; + font-size: 115%; + margin-right: 3px; } + .redactor-modal .form-item { + margin-bottom: 20px; } + .redactor-modal .form-item:last-child { + margin-bottom: 0; } + .redactor-modal fieldset { + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 3px; + padding: 16px; + padding-bottom: 20px; + margin-bottom: 20px; } + .redactor-modal fieldset .form-item { + margin-bottom: 12px; } + .redactor-modal label { + display: block; + color: #555; + margin-bottom: 0.25em; + font-size: 14px; } + .redactor-modal label .desc, + .redactor-modal label .success, + .redactor-modal label .error { + text-transform: none; + font-weight: normal; } + .redactor-modal label.checkbox { + font-size: 16px; + line-height: 1.5; + cursor: pointer; + color: inherit; } + .redactor-modal .form-checkboxes label.checkbox { + display: inline-block; + margin-right: 1em; } + .redactor-modal input:hover, + .redactor-modal textarea:hover, + .redactor-modal select:hover { + outline: none; + background-color: #fff; + border-color: #969fa9; + box-shadow: none; } + .redactor-modal input:focus, + .redactor-modal textarea:focus, + .redactor-modal select:focus { + transition: all linear .2s; + outline: none; + background-color: #fff; + border-color: rgba(0, 125, 255, 0.5); + box-shadow: 0 0 3px rgba(0, 125, 255, 0.5); } + .redactor-modal input.error, + .redactor-modal textarea.error, + .redactor-modal select.error { + background-color: rgba(255, 50, 101, 0.1); + border: 1px solid #ff7f9e; } + .redactor-modal input.error:focus, + .redactor-modal textarea.error:focus, + .redactor-modal select.error:focus { + border-color: #ff3265; + box-shadow: 0 0 1px #ff3265; } + .redactor-modal input.success, + .redactor-modal textarea.success, + .redactor-modal select.success { + background-color: rgba(47, 196, 182, 0.1); + border: 1px solid #65dacf; } + .redactor-modal input.success:focus, + .redactor-modal textarea.success:focus, + .redactor-modal select.success:focus { + border-color: #2fc4b6; + box-shadow: 0 0 1px #2fc4b6; } + .redactor-modal input:disabled, .redactor-modal input:disabled:hover, .redactor-modal input.disabled, .redactor-modal input.disabled:hover, + .redactor-modal textarea:disabled, + .redactor-modal textarea:disabled:hover, + .redactor-modal textarea.disabled, + .redactor-modal textarea.disabled:hover, + .redactor-modal select:disabled, + .redactor-modal select:disabled:hover, + .redactor-modal select.disabled, + .redactor-modal select.disabled:hover { + resize: none; + opacity: .6; + cursor: default; + font-style: italic; + color: rgba(0, 0, 0, 0.5); + border: 1px solid #cacfd4; + box-shadow: none; + background-color: #fff; } + .redactor-modal .req { + position: relative; + top: 1px; + font-weight: bold; + color: #ff3265; + font-size: 110%; } + .redactor-modal .desc { + color: rgba(51, 51, 51, 0.5); + font-size: 12px; } + .redactor-modal span.desc { + margin-left: 0.25em; } + .redactor-modal div.desc { + margin-top: 0.25em; } + .redactor-modal span.success, + .redactor-modal span.error { + font-size: 12px; + margin-left: 0.25em; } + .redactor-modal div.desc { + margin-bottom: -0.5em; } + .redactor-modal .redactor-close { + position: absolute; + top: 16px; + right: 12px; + font-size: 30px; + line-height: 30px; + padding: 0px 4px; + color: #000; + opacity: .3; + cursor: pointer; } + .redactor-modal .redactor-close:hover { + opacity: 1; } + .redactor-modal .redactor-close:before { + content: '\00d7'; } + .redactor-modal button { + display: inline-flex; + align-items: center; + text-decoration: none; + text-align: center; + font-family: inherit; + font-size: 15px; + font-weight: 500; + color: #007dff; + background-color: #fff; + border-radius: 3px; + border: 2px solid #007dff; + min-height: 40px; + outline: none; + padding: 0.5em 1.25em; + cursor: pointer; + line-height: 1.2; + vertical-align: middle; + -webkit-appearance: none; } + .redactor-modal button:hover { + outline: none; + text-decoration: none; + background: none; + color: rgba(0, 125, 255, 0.6); + border-color: rgba(0, 125, 255, 0.5); } + .redactor-modal button.redactor-button-secondary { + border-color: #2a2e34; + color: #2a2e34; } + .redactor-modal button.redactor-button-secondary:hover { + color: rgba(42, 46, 52, 0.6); + border-color: rgba(42, 46, 52, 0.5); } + .redactor-modal button.redactor-button-danger, + .redactor-modal button.redactor-button-unstyled { + background: none; + border-color: transparent; + color: rgba(42, 46, 52, 0.6); } + .redactor-modal button.redactor-button-danger:hover, + .redactor-modal button.redactor-button-unstyled:hover { + background: none; + border-color: transparent; + color: #ff3265; + text-decoration: underline; } + .redactor-modal .redactor-modal-group:after { + content: ""; + display: table; + clear: both; } + .redactor-modal .redactor-modal-side { + float: left; + width: 30%; + margin-right: 4%; } + .redactor-modal .redactor-modal-side img { + max-width: 100%; + height: auto; + display: block; } + .redactor-modal .redactor-modal-area { + float: left; + width: 66%; } + +.redactor-modal[dir="rtl"] .redactor-close { + left: 12px; + right: auto; } + +.redactor-modal[dir="rtl"] textarea { + direction: ltr; + text-align: left; } + +.redactor-modal[dir="rtl"] .redactor-modal-footer button.redactor-button-unstyled { + float: left; + margin-left: 0; } + +.redactor-modal-header { + padding: 20px; + font-size: 18px; + line-height: 24px; + font-weight: bold; + color: #000; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); } + .redactor-modal-header:empty { + display: none; } + +.redactor-modal-body { + padding: 32px 48px; + padding-bottom: 40px; } + +.redactor-modal-footer { + padding: 24px; + border-top: 1px solid rgba(0, 0, 0, 0.05); + overflow: hidden; } + .redactor-modal-footer button { + margin-right: 4px; } + .redactor-modal-footer button.redactor-button-unstyled { + margin-right: 0; + float: right; } + .redactor-modal-footer:empty { + display: none; } + +.redactor-modal-tabs { + display: flex; + border-bottom: 2px solid rgba(0, 0, 0, 0.05); + margin-bottom: 1em; } + .redactor-modal-tabs a { + font-size: 15px; + padding: 2px 0; + text-decoration: none; + color: rgba(0, 0, 0, 0.5); + border-bottom: 2px solid transparent; + margin-bottom: -2px; + margin-right: 14px; } + .redactor-modal-tabs a:hover { + transition: all linear .2s; } + .redactor-modal-tabs a:hover, + .redactor-modal-tabs a.active { + font-weight: 500; + color: #007dff; + border-bottom-color: #007dff; } + +.redactor-styles { + margin: 0; + padding: 16px 18px; + color: #333; + font-family: "Trebuchet MS", "Helvetica Neue", Helvetica, Tahoma, sans-serif; + font-size: 1em; + line-height: 1.5; + box-sizing: border-box; } + .redactor-styles *, + .redactor-styles *:before, + .redactor-styles *:after { + box-sizing: inherit; } + .redactor-styles[dir="rtl"] { + direction: rtl; + unicode-bidi: embed; } + .redactor-styles[dir="rtl"] ul li, + .redactor-styles[dir="rtl"] ol li { + text-align: right; } + .redactor-styles[dir="rtl"] ul, + .redactor-styles[dir="rtl"] ol, + .redactor-styles[dir="rtl"] ul ul, + .redactor-styles[dir="rtl"] ol ol, + .redactor-styles[dir="rtl"] ul ol, + .redactor-styles[dir="rtl"] ol ul { + margin: 0 1.5em 0 0; } + .redactor-styles[dir="rtl"] figcaption { + text-align: right; } + .redactor-styles a, + .redactor-styles a:hover { + color: #3397ff; } + .redactor-styles p, + .redactor-styles dl, + .redactor-styles blockquote, + .redactor-styles hr, + .redactor-styles pre, + .redactor-styles table, + .redactor-styles figure, + .redactor-styles address { + padding: 0; + margin: 0; + margin-bottom: 1em; } + .redactor-styles ul, + .redactor-styles ol { + padding: 0; } + .redactor-styles ul, + .redactor-styles ul ul, + .redactor-styles ul ol, + .redactor-styles ol, + .redactor-styles ol ul, + .redactor-styles ol ol { + margin: 0 0 0 1.5em; } + .redactor-styles ul li, + .redactor-styles ol li { + text-align: left; } + .redactor-styles ol ol li { + list-style-type: lower-alpha; } + .redactor-styles ol ol ol li { + list-style-type: lower-roman; } + .redactor-styles ul, + .redactor-styles ol { + margin-bottom: 1em; } + .redactor-styles h1, + .redactor-styles h2, + .redactor-styles h3, + .redactor-styles h4, + .redactor-styles h5, + .redactor-styles h6 { + font-weight: bold; + color: #111; + text-rendering: optimizeLegibility; + margin: 0; + padding: 0; + margin-bottom: 0.5em; + line-height: 1.2; } + .redactor-styles h1 { + font-size: 2.0736em; } + .redactor-styles h2 { + font-size: 1.728em; } + .redactor-styles h3 { + font-size: 1.44em; } + .redactor-styles h4 { + font-size: 1.2em; } + .redactor-styles h5 { + font-size: 1em; } + .redactor-styles h6 { + font-size: 0.83333em; + text-transform: uppercase; + letter-spacing: .035em; } + .redactor-styles blockquote { + font-style: italic; + color: rgba(0, 0, 0, 0.5); + border: none; } + .redactor-styles table { + width: 100%; } + .redactor-styles time, .redactor-styles small, .redactor-styles var, .redactor-styles code, .redactor-styles kbd, .redactor-styles mark { + display: inline-block; + font-family: Consolas, Menlo, Monaco, "Courier New", monospace; + font-size: 87.5%; + line-height: 1; + color: rgba(51, 51, 51, 0.9); } + .redactor-styles var, .redactor-styles cite { + opacity: .6; } + .redactor-styles var { + font-style: normal; } + .redactor-styles dfn, + .redactor-styles abbr { + text-transform: uppercase; } + .redactor-styles dfn[title], + .redactor-styles abbr[title] { + text-decoration: none; + border-bottom: 1px dotted rgba(0, 0, 0, 0.5); + cursor: help; } + .redactor-styles code, .redactor-styles kbd { + position: relative; + top: -1px; + padding: 0.25em; + padding-bottom: 0.2em; + border-radius: 2px; } + .redactor-styles code { + background-color: #eff1f2; } + .redactor-styles mark { + border-radius: 2px; + padding: 0.125em 0.25em; + background-color: #fdb833; } + .redactor-styles kbd { + border: 1px solid #e5e7e9; } + .redactor-styles sub, + .redactor-styles sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + .redactor-styles sub { + bottom: -0.25em; } + .redactor-styles sup { + top: -0.5em; } + .redactor-styles pre { + font-family: Consolas, Menlo, Monaco, "Courier New", monospace; + font-size: .9em; } + .redactor-styles pre, + .redactor-styles pre code { + background-color: #f6f7f8; + padding: 0; + top: 0; + display: block; + line-height: 1.5; + color: rgba(51, 51, 51, 0.85); + overflow: none; + white-space: pre-wrap; } + .redactor-styles pre { + padding: 1rem; } + .redactor-styles table { + border-collapse: collapse; + max-width: 100%; + width: 100%; } + .redactor-styles table caption { + text-transform: uppercase; + padding: 0; + color: rgba(0, 0, 0, 0.5); + font-size: 11px; } + .redactor-styles table th, + .redactor-styles table td { + border: 1px solid #eee; + padding: 16px; + padding-bottom: 15px; } + .redactor-styles table tfoot th, + .redactor-styles table tfoot td { + color: rgba(0, 0, 0, 0.5); } + .redactor-styles img, + .redactor-styles video, + .redactor-styles audio, + .redactor-styles embed, + .redactor-styles object { + max-width: 100%; } + .redactor-styles img, + .redactor-styles video, + .redactor-styles embed, + .redactor-styles object { + height: auto !important; } + .redactor-styles img { + vertical-align: middle; + -ms-interpolation-mode: bicubic; } + .redactor-styles figcaption { + display: block; + opacity: .6; + font-size: 12px; + font-style: italic; + text-align: left; } + +.upload-redactor-box { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + box-sizing: border-box; + border: 5px dashed rgba(0, 125, 255, 0.15); + position: relative; + width: 100%; + min-height: 220px; + background: #fff; + cursor: pointer; + overflow: hidden; + text-align: center; } + +.upload-redactor-placeholder { + font-size: 15px; + line-height: 1.5; + color: rgba(0, 0, 0, 0.3); + font-style: italic; } + +.upload-redactor-hover { + background-color: rgba(0, 125, 255, 0.075); } + +.upload-redactor-error { + background-color: rgba(255, 50, 101, 0.075); } + +.upload-redactor-box-hover { + outline: 5px dashed rgba(0, 125, 255, 0.3); } + +.upload-redactor-box-error { + outline: 5px dashed rgba(255, 50, 101, 0.3); } + +.redactor-structure h1, .redactor-structure h2, .redactor-structure h3, .redactor-structure h4, .redactor-structure h5, .redactor-structure h6, .redactor-structure div { + position: relative; } + .redactor-structure h1:before, .redactor-structure h2:before, .redactor-structure h3:before, .redactor-structure h4:before, .redactor-structure h5:before, .redactor-structure h6:before, .redactor-structure div:before { + width: 24px; + position: absolute; + font-size: 10px; + font-weight: normal; + opacity: .3; + left: -26px; + top: 50%; + margin-top: -7px; + text-align: right; } + +.redactor-structure h1:before { + content: "h1"; } + +.redactor-structure h2:before { + content: "h2"; } + +.redactor-structure h3:before { + content: "h3"; } + +.redactor-structure h4:before { + content: "h4"; } + +.redactor-structure h5:before { + content: "h5"; } + +.redactor-structure h6:before { + content: "h6"; } + +.redactor-structure div:before { + content: "div"; } + +#redactor-progress { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 1000000; + height: 10px; } + +#redactor-progress span { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; + display: block; + width: 100%; + height: 100%; + background-color: #007dff; + background-size: 40px 40px; } + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +.redactor-box-fullscreen { + z-index: 1051; + position: fixed; + top: 0; + left: 0; + width: 100%; } + +.redactor-box-fullscreen-target { + position: absolute !important; } + +.redactor-body-fullscreen .redactor-dropdown, +.redactor-body-fullscreen .redactor-context-toolbar { + z-index: 1052; } + +.redactor-body-fullscreen #redactor-overlay { + z-index: 1098; } + +.redactor-body-fullscreen #redactor-modal { + z-index: 1099; } diff --git a/vendor/assets/redactor/redactor.js b/vendor/assets/redactor/redactor.js new file mode 100644 index 0000000..878a549 --- /dev/null +++ b/vendor/assets/redactor/redactor.js @@ -0,0 +1,17910 @@ +/* + Redactor + Version 3.1.4 + Updated: October 25, 2018 + + http://imperavi.com/redactor/ + + Copyright (c) 2009-2018, Imperavi Ltd. + License: http://imperavi.com/redactor/license/ +*/ +(function() { +var Ajax = {}; + +Ajax.settings = {}; +Ajax.post = function(options) { return new AjaxRequest('post', options); }; +Ajax.get = function(options) { return new AjaxRequest('get', options); }; + +var AjaxRequest = function(method, options) +{ + var defaults = { + method: method, + url: '', + before: function() {}, + success: function() {}, + error: function() {}, + data: false, + async: true, + headers: {} + }; + + this.p = this.extend(defaults, options); + this.p = this.extend(this.p, Ajax.settings); + this.p.method = this.p.method.toUpperCase(); + + this.prepareData(); + + this.xhr = new XMLHttpRequest(); + this.xhr.open(this.p.method, this.p.url, this.p.async); + + this.setHeaders(); + + var before = (typeof this.p.before === 'function') ? this.p.before(this.xhr) : true; + if (before !== false) + { + this.send(); + } +}; + +AjaxRequest.prototype = { + extend: function(obj1, obj2) + { + if (obj2) for (var name in obj2) { obj1[name] = obj2[name]; } + return obj1; + }, + prepareData: function() + { + if (this.p.method === 'POST' && !this.isFormData()) this.p.headers['Content-Type'] = 'application/x-www-form-urlencoded'; + if (typeof this.p.data === 'object' && !this.isFormData()) this.p.data = this.toParams(this.p.data); + if (this.p.method === 'GET') this.p.url = (this.p.data) ? this.p.url + '?' + this.p.data : this.p.url; + }, + setHeaders: function() + { + this.xhr.setRequestHeader('X-Requested-With', this.p.headers['X-Requested-With'] || 'XMLHttpRequest'); + for (var name in this.p.headers) + { + this.xhr.setRequestHeader(name, this.p.headers[name]); + } + }, + isFormData: function() + { + return (typeof window.FormData !== 'undefined' && this.p.data instanceof window.FormData); + }, + isComplete: function() + { + return !(this.xhr.status < 200 || this.xhr.status >= 300 && this.xhr.status !== 304); + }, + send: function() + { + if (this.p.async) + { + this.xhr.onload = this.loaded.bind(this); + this.xhr.send(this.p.data); + } + else + { + this.xhr.send(this.p.data); + this.loaded.call(this); + } + }, + loaded: function() + { + if (this.isComplete()) + { + var response = this.xhr.response; + var json = this.parseJson(response); + response = (json) ? json : response; + + if (typeof this.p.success === 'function') this.p.success(response, this.xhr); + } + else + { + if (typeof this.p.error === 'function') this.p.error(this.xhr.statusText); + } + }, + parseJson: function(str) + { + try { + var o = JSON.parse(str); + if (o && typeof o === 'object') + { + return o; + } + + } catch (e) {} + + return false; + }, + toParams: function (obj) + { + return Object.keys(obj).map( + function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); } + ).join('&'); + } +}; +var DomCache = [0]; +var DomExpando = 'data' + +new Date(); +var DomHClass = 'is-hidden'; +var DomHMClass = 'is-hidden-mobile'; + +var Dom = function(selector, context) +{ + return this.parse(selector, context); +}; + +Dom.ready = function(fn) +{ + if (document.readyState != 'loading') fn(); + else document.addEventListener('DOMContentLoaded', fn); +}; + +Dom.prototype = { + get dom() + { + return true; + }, + get length() + { + return this.nodes.length; + }, + parse: function(selector, context) + { + var nodes; + var reHtmlTest = /^\s*<(\w+|!)[^>]*>/; + + if (!selector) + { + nodes = []; + } + else if (selector.dom) + { + this.nodes = selector.nodes; + return selector; + } + else if (typeof selector !== 'string') + { + if (selector.nodeType && selector.nodeType === 11) + { + nodes = selector.childNodes; + } + else + { + nodes = (selector.nodeType || selector === window) ? [selector] : selector; + } + } + else if (reHtmlTest.test(selector)) + { + nodes = this.create(selector); + } + else + { + nodes = this._query(selector, context); + } + + this.nodes = this._slice(nodes); + }, + create: function(html) + { + if (/^<(\w+)\s*\/?>(?:<\/\1>|)$/.test(html)) + { + return [document.createElement(RegExp.$1)]; + } + + var elements = []; + var container = document.createElement('div'); + var children = container.childNodes; + + container.innerHTML = html; + + for (var i = 0, l = children.length; i < l; i++) + { + elements.push(children[i]); + } + + return elements; + }, + + // add + add: function(nodes) + { + this.nodes = this.nodes.concat(this._toArray(nodes)); + }, + + // get + get: function(index) + { + return this.nodes[(index || 0)] || false; + }, + getAll: function() + { + return this.nodes; + }, + eq: function(index) + { + return new Dom(this.nodes[index]); + }, + first: function() + { + return new Dom(this.nodes[0]); + }, + last: function() + { + return new Dom(this.nodes[this.nodes.length - 1]); + }, + contents: function() + { + return this.get().childNodes; + }, + + // loop + each: function(callback) + { + var len = this.nodes.length; + for (var i = 0; i < len; i++) + { + callback.call(this, (this.nodes[i].dom) ? this.nodes[i].get() : this.nodes[i], i); + } + + return this; + }, + + // traversing + is: function(selector) + { + return (this.filter(selector).length > 0); + }, + filter: function (selector) + { + var callback; + if (selector === undefined) + { + return this; + } + else if (typeof selector === 'function') + { + callback = selector; + } + else + { + callback = function(node) + { + if (selector instanceof Node) + { + return (selector === node); + } + else if (selector && selector.dom) + { + return ((selector.nodes).indexOf(node) !== -1); + } + else + { + node.matches = node.matches || node.msMatchesSelector || node.webkitMatchesSelector; + return (node.nodeType === 1) ? node.matches(selector || '*') : false; + } + }; + } + + return new Dom(this.nodes.filter(callback)); + }, + not: function(filter) + { + return this.filter(function(node) + { + return !new Dom(node).is(filter || true); + }); + }, + find: function(selector) + { + var nodes = []; + this.each(function(node) + { + var ns = this._query(selector || '*', node); + for (var i = 0; i < ns.length; i++) + { + nodes.push(ns[i]); + } + }); + + return new Dom(nodes); + }, + children: function(selector) + { + var nodes = []; + this.each(function(node) + { + if (node.children) + { + var ns = node.children; + for (var i = 0; i < ns.length; i++) + { + nodes.push(ns[i]); + } + } + }); + + return new Dom(nodes).filter(selector); + }, + parent: function(selector) + { + var nodes = []; + this.each(function(node) + { + if (node.parentNode) nodes.push(node.parentNode); + }); + + return new Dom(nodes).filter(selector); + }, + parents: function(selector, context) + { + context = this._getContext(context); + + var nodes = []; + this.each(function(node) + { + var parent = node.parentNode; + while (parent && parent !== context) + { + if (selector) + { + if (new Dom(parent).is(selector)) { nodes.push(parent); } + } + else + { + nodes.push(parent); + } + + parent = parent.parentNode; + } + }); + + return new Dom(nodes); + }, + closest: function(selector, context) + { + context = this._getContext(context); + selector = (selector.dom) ? selector.get() : selector; + + var nodes = []; + var isNode = (selector && selector.nodeType); + this.each(function(node) + { + do { + if ((isNode && node === selector) || new Dom(node).is(selector)) return nodes.push(node); + } while ((node = node.parentNode) && node !== context); + }); + + return new Dom(nodes); + }, + next: function(selector) + { + return this._getSibling(selector, 'nextSibling'); + }, + nextElement: function(selector) + { + return this._getSibling(selector, 'nextElementSibling'); + }, + prev: function(selector) + { + return this._getSibling(selector, 'previousSibling'); + }, + prevElement: function(selector) + { + return this._getSibling(selector, 'previousElementSibling'); + }, + + // css + css: function(name, value) + { + if (value === undefined && (typeof name !== 'object')) + { + var node = this.get(); + if (name === 'width' || name === 'height') + { + return (node.style) ? this._getHeightOrWidth(name, node, false) + 'px' : undefined; + } + else + { + return (node.style) ? getComputedStyle(node, null)[name] : undefined; + } + } + + // set + return this.each(function(node) + { + var obj = {}; + if (typeof name === 'object') obj = name; + else obj[name] = value; + + for (var key in obj) + { + if (node.style) node.style[key] = obj[key]; + } + }); + }, + + // attr + attr: function(name, value, data) + { + data = (data) ? 'data-' : ''; + + if (value === undefined && (typeof name !== 'object')) + { + var node = this.get(); + if (node && node.nodeType !== 3) + { + return (name === 'checked') ? node.checked : this._getBooleanFromStr(node.getAttribute(data + name)); + } + else return; + } + + // set + return this.each(function(node) + { + var obj = {}; + if (typeof name === 'object') obj = name; + else obj[name] = value; + + for (var key in obj) + { + if (node.nodeType !== 3) + { + if (key === 'checked') node.checked = obj[key]; + else node.setAttribute(data + key, obj[key]); + } + } + }); + }, + data: function(name, value) + { + if (name === undefined) + { + var reDataAttr = /^data\-(.+)$/; + var attrs = this.get().attributes; + + var data = {}; + var replacer = function (g) { return g[1].toUpperCase(); }; + + for (var key in attrs) + { + if (reDataAttr.test(attrs[key].nodeName)) + { + var dataName = attrs[key].nodeName.match(reDataAttr)[1]; + var val = attrs[key].value; + dataName = dataName.replace(/-([a-z])/g, replacer); + + if (this._isObjectString(val)) val = this._toObject(val); + else val = (this._isNumber(val)) ? parseFloat(val) : this._getBooleanFromStr(val); + + data[dataName] = val; + } + } + + return data; + } + + return this.attr(name, value, true); + }, + val: function(value) + { + if (value === undefined) + { + var el = this.get(); + if (el.type && el.type === 'checkbox') return el.checked; + else return el.value; + } + + return this.each(function(node) + { + node.value = value; + }); + }, + removeAttr: function(value) + { + return this.each(function(node) + { + var rmAttr = function(name) { if (node.nodeType !== 3) node.removeAttribute(name); }; + value.split(' ').forEach(rmAttr); + }); + }, + removeData: function(value) + { + return this.each(function(node) + { + var rmData = function(name) { if (node.nodeType !== 3) node.removeAttribute('data-' + name); }; + value.split(' ').forEach(rmData); + }); + }, + + // dataset/dataget + dataset: function(key, value) + { + return this.each(function(node) + { + DomCache[this.dataindex(node)][key] = value; + }); + }, + dataget: function(key) + { + return DomCache[this.dataindex(this.get())][key]; + }, + dataindex: function(el) + { + var cacheIndex = el[DomExpando]; + var nextCacheIndex = DomCache.length; + + if (!cacheIndex) + { + cacheIndex = el[DomExpando] = nextCacheIndex; + DomCache[cacheIndex] = {}; + } + + return cacheIndex; + }, + + + // class + addClass: function(value) + { + return this._eachClass(value, 'add'); + }, + removeClass: function(value) + { + return this._eachClass(value, 'remove'); + }, + toggleClass: function(value) + { + return this._eachClass(value, 'toggle'); + }, + hasClass: function(value) + { + return this.nodes.some(function(node) + { + return (node.classList) ? node.classList.contains(value) : false; + }); + }, + + // html & text + empty: function() + { + return this.each(function(node) + { + node.innerHTML = ''; + }); + }, + html: function(html) + { + return (html === undefined) ? (this.get().innerHTML || '') : this.empty().append(html); + }, + text: function(text) + { + return (text === undefined) ? (this.get().textContent || '') : this.each(function(node) { node.textContent = text; }); + }, + + // manipulation + after: function(html) + { + return this._inject(html, function(frag, node) + { + if (typeof frag === 'string') + { + node.insertAdjacentHTML('afterend', frag); + } + else + { + var elms = (frag instanceof Node) ? [frag] : this._toArray(frag).reverse(); + for (var i = 0; i < elms.length; i++) + { + node.parentNode.insertBefore(elms[i], node.nextSibling); + } + } + + return node; + + }); + }, + before: function(html) + { + return this._inject(html, function(frag, node) + { + if (typeof frag === 'string') + { + node.insertAdjacentHTML('beforebegin', frag); + } + else + { + var elms = (frag instanceof Node) ? [frag] : this._toArray(frag); + for (var i = 0; i < elms.length; i++) + { + node.parentNode.insertBefore(elms[i], node); + } + } + + return node; + }); + }, + append: function(html) + { + return this._inject(html, function(frag, node) + { + if (typeof frag === 'string' || typeof frag === 'number') + { + node.insertAdjacentHTML('beforeend', frag); + } + else + { + var elms = (frag instanceof Node) ? [frag] : this._toArray(frag); + for (var i = 0; i < elms.length; i++) + { + node.appendChild(elms[i]); + } + } + + return node; + }); + }, + prepend: function(html) + { + return this._inject(html, function(frag, node) + { + if (typeof frag === 'string' || typeof frag === 'number') + { + node.insertAdjacentHTML('afterbegin', frag); + } + else + { + var elms = (frag instanceof Node) ? [frag] : this._toArray(frag).reverse(); + for (var i = 0; i < elms.length; i++) + { + node.insertBefore(elms[i], node.firstChild); + } + } + + return node; + }); + }, + wrap: function(html) + { + return this._inject(html, function(frag, node) + { + var wrapper = (typeof frag === 'string' || typeof frag === 'number') ? this.create(frag)[0] : (frag instanceof Node) ? frag : this._toArray(frag)[0]; + + if (node.parentNode) + { + node.parentNode.insertBefore(wrapper, node); + } + + wrapper.appendChild(node); + + return new Dom(wrapper); + + }); + }, + unwrap: function() + { + return this.each(function(node) + { + var $node = new Dom(node); + + return $node.replaceWith($node.contents()); + }); + }, + replaceWith: function(html) + { + return this._inject(html, function(frag, node) + { + var docFrag = document.createDocumentFragment(); + var elms = (typeof frag === 'string' || typeof frag === 'number') ? this.create(frag) : (frag instanceof Node) ? [frag] : this._toArray(frag); + + for (var i = 0; i < elms.length; i++) + { + docFrag.appendChild(elms[i]); + } + + var result = docFrag.childNodes[0]; + node.parentNode.replaceChild(docFrag, node); + + return result; + + }); + }, + remove: function() + { + return this.each(function(node) + { + if (node.parentNode) node.parentNode.removeChild(node); + }); + }, + clone: function(events) + { + var nodes = []; + this.each(function(node) + { + var copy = this._clone(node); + if (events) copy = this._cloneEvents(node, copy); + nodes.push(copy); + }); + + return new Dom(nodes); + }, + + // show/hide + show: function() + { + return this.each(function(node) + { + if (!node.style || !this._hasDisplayNone(node)) return; + + var target = node.getAttribute('domTargetShow'); + var isHidden = (node.classList) ? node.classList.contains(DomHClass) : false; + var isHiddenMobile = (node.classList) ? node.classList.contains(DomHMClass) : false; + var type; + + if (isHidden) + { + type = DomHClass; + node.classList.remove(DomHClass); + } + else if (isHiddenMobile) + { + type = DomHMClass; + node.classList.remove(DomHMClass); + } + else + { + node.style.display = (target) ? target : 'block'; + } + + if (type) node.setAttribute('domTargetHide', type); + node.removeAttribute('domTargetShow'); + + }.bind(this)); + }, + hide: function() + { + return this.each(function(node) + { + if (!node.style || this._hasDisplayNone(node)) return; + + var display = node.style.display; + var target = node.getAttribute('domTargetHide'); + + if (target === DomHClass) + { + node.classList.add(DomHClass); + } + else if (target === DomHMClass) + { + node.classList.add(DomHMClass); + } + else + { + if (display !== 'block') node.setAttribute('domTargetShow', display); + node.style.display = 'none'; + } + + node.removeAttribute('domTargetHide'); + + }); + }, + + // dimensions + scrollTop: function(value) + { + var node = this.get(); + var isWindow = (node === window); + var isDocument = (node.nodeType === 9); + var el = (isDocument) ? (document.scrollingElement || document.body.parentNode || document.body || document.documentElement) : node; + + if (value !== undefined) + { + if (isWindow) window.scrollTo(0, value); + else el.scrollTop = value; + return; + } + + if (isDocument) + { + return (typeof window.pageYOffset != 'undefined') ? window.pageYOffset : ((document.documentElement.scrollTop) ? document.documentElement.scrollTop : ((document.body.scrollTop) ? document.body.scrollTop : 0)); + } + else + { + return (isWindow) ? window.pageYOffset : el.scrollTop; + } + }, + offset: function() + { + return this._getDim('Offset'); + }, + position: function() + { + return this._getDim('Position'); + }, + width: function(value, adjust) + { + return this._getSize('width', 'Width', value, adjust); + }, + height: function(value, adjust) + { + return this._getSize('height', 'Height', value, adjust); + }, + outerWidth: function() + { + return this._getInnerOrOuter('width', 'outer'); + }, + outerHeight: function() + { + return this._getInnerOrOuter('height', 'outer'); + }, + innerWidth: function() + { + return this._getInnerOrOuter('width', 'inner'); + }, + innerHeight: function() + { + return this._getInnerOrOuter('height', 'inner'); + }, + + // events + click: function() + { + return this._triggerEvent('click'); + }, + focus: function() + { + return this._triggerEvent('focus'); + }, + trigger: function(names) + { + return this.each(function(node) + { + var events = names.split(' '); + for (var i = 0; i < events.length; i++) + { + var ev; + var opts = { bubbles: true, cancelable: true }; + + try { + ev = new window.CustomEvent(events[i], opts); + } catch(e) { + ev = document.createEvent('CustomEvent'); + ev.initCustomEvent(events[i], true, true); + } + + node.dispatchEvent(ev); + } + }); + }, + on: function(names, handler, one) + { + return this.each(function(node) + { + var events = names.split(' '); + for (var i = 0; i < events.length; i++) + { + var event = this._getEventName(events[i]); + var namespace = this._getEventNamespace(events[i]); + + handler = (one) ? this._getOneHandler(handler, names) : handler; + node.addEventListener(event, handler); + + node._e = node._e || {}; + node._e[namespace] = node._e[namespace] || {}; + node._e[namespace][event] = node._e[namespace][event] || []; + node._e[namespace][event].push(handler); + } + + }); + }, + one: function(events, handler) + { + return this.on(events, handler, true); + }, + off: function(names, handler) + { + var testEvent = function(name, key, event) { return (name === event); }; + var testNamespace = function(name, key, event, namespace) { return (key === namespace); }; + var testEventNamespace = function(name, key, event, namespace) { return (name === event && key === namespace); }; + var testPositive = function() { return true; }; + + if (names === undefined) + { + // ALL + return this.each(function(node) + { + this._offEvent(node, false, false, handler, testPositive); + }); + } + + return this.each(function(node) + { + var events = names.split(' '); + + for (var i = 0; i < events.length; i++) + { + var event = this._getEventName(events[i]); + var namespace = this._getEventNamespace(events[i]); + + // 1) event without namespace + if (namespace === '_events') this._offEvent(node, event, namespace, handler, testEvent); + // 2) only namespace + else if (!event && namespace !== '_events') this._offEvent(node, event, namespace, handler, testNamespace); + // 3) event + namespace + else this._offEvent(node, event, namespace, handler, testEventNamespace); + } + }); + }, + + // form + serialize: function(asObject) + { + var obj = {}; + var elms = this.get().elements; + for (var i = 0; i < elms.length; i++) + { + var el = elms[i]; + if (/(checkbox|radio)/.test(el.type) && !el.checked) continue; + if (!el.name || el.disabled || el.type === 'file') continue; + + if (el.type === 'select-multiple') + { + for (var z = 0; z < el.options.length; z++) + { + var opt = el.options[z]; + if (opt.selected) obj[el.name] = opt.value; + } + } + + obj[el.name] = (this._isNumber(el.value)) ? parseFloat(el.value) : this._getBooleanFromStr(el.value); + } + + return (asObject) ? obj : this._toParams(obj); + }, + ajax: function(success, error) + { + if (typeof AjaxRequest !== 'undefined') + { + var method = this.attr('method') || 'post'; + var options = { + url: this.attr('action'), + data: this.serialize(), + success: success, + error: error + }; + + return new AjaxRequest(method, options); + } + }, + + // private + _queryContext: function(selector, context) + { + context = this._getContext(context); + + return (context.nodeType !== 3 && typeof context.querySelectorAll === 'function') ? context.querySelectorAll(selector) : []; + }, + _query: function(selector, context) + { + if (context) + { + return this._queryContext(selector, context); + } + else if (/^[.#]?[\w-]*$/.test(selector)) + { + if (selector[0] === '#') + { + var element = document.getElementById(selector.slice(1)); + return element ? [element] : []; + } + + if (selector[0] === '.') + { + return document.getElementsByClassName(selector.slice(1)); + } + + return document.getElementsByTagName(selector); + } + + return document.querySelectorAll(selector); + }, + _getContext: function(context) + { + context = (typeof context === 'string') ? document.querySelector(context) : context; + + return (context && context.dom) ? context.get() : (context || document); + }, + _inject: function(html, fn) + { + var len = this.nodes.length; + var nodes = []; + while (len--) + { + var res = (typeof html === 'function') ? html.call(this, this.nodes[len]) : html; + var el = (len === 0) ? res : this._clone(res); + var node = fn.call(this, el, this.nodes[len]); + + if (node) + { + if (node.dom) nodes.push(node.get()); + else nodes.push(node); + } + } + + return new Dom(nodes); + }, + _cloneEvents: function(node, copy) + { + var events = node._e; + if (events) + { + copy._e = events; + for (var name in events._events) + { + for (var i = 0; i < events._events[name].length; i++) + { + copy.addEventListener(name, events._events[name][i]); + } + } + } + + return copy; + }, + _clone: function(node) + { + if (typeof node === 'undefined') return; + if (typeof node === 'string') return node; + else if (node instanceof Node || node.nodeType) return node.cloneNode(true); + else if ('length' in node) + { + return [].map.call(this._toArray(node), function(el) { return el.cloneNode(true); }); + } + }, + _slice: function(obj) + { + return (!obj || obj.length === 0) ? [] : (obj.length) ? [].slice.call(obj.nodes || obj) : [obj]; + }, + _eachClass: function(value, type) + { + return this.each(function(node) + { + if (value) + { + var setClass = function(name) { if (node.classList) node.classList[type](name); }; + value.split(' ').forEach(setClass); + } + }); + }, + _triggerEvent: function(name) + { + var node = this.get(); + if (node && node.nodeType !== 3) node[name](); + return this; + }, + _getOneHandler: function(handler, events) + { + var self = this; + return function() + { + handler.apply(this, arguments); + self.off(events); + }; + }, + _getEventNamespace: function(event) + { + var arr = event.split('.'); + var namespace = (arr[1]) ? arr[1] : '_events'; + return (arr[2]) ? namespace + arr[2] : namespace; + }, + _getEventName: function(event) + { + return event.split('.')[0]; + }, + _offEvent: function(node, event, namespace, handler, condition) + { + for (var key in node._e) + { + for (var name in node._e[key]) + { + if (condition(name, key, event, namespace)) + { + var handlers = node._e[key][name]; + for (var i = 0; i < handlers.length; i++) + { + if (typeof handler !== 'undefined' && handlers[i].toString() !== handler.toString()) + { + continue; + } + + node.removeEventListener(name, handlers[i]); + node._e[key][name].splice(i, 1); + + if (node._e[key][name].length === 0) delete node._e[key][name]; + if (Object.keys(node._e[key]).length === 0) delete node._e[key]; + } + } + } + } + }, + _getInnerOrOuter: function(method, type) + { + return this[method](undefined, type); + }, + _getDocSize: function(node, type) + { + var body = node.body, html = node.documentElement; + return Math.max(body['scroll' + type], body['offset' + type], html['client' + type], html['scroll' + type], html['offset' + type]); + }, + _getSize: function(type, captype, value, adjust) + { + if (value === undefined) + { + var el = this.get(); + if (el.nodeType === 3) value = 0; + else if (el.nodeType === 9) value = this._getDocSize(el, captype); + else if (el === window) value = window['inner' + captype]; + else value = this._getHeightOrWidth(type, el, adjust || 'normal'); + + return Math.round(value); + } + + return this.each(function(node) + { + value = parseFloat(value); + value = value + this._adjustResultHeightOrWidth(type, node, adjust || 'normal'); + + new Dom(node).css(type, value + 'px'); + + }.bind(this)); + }, + _getHeightOrWidth: function(type, el, adjust) + { + if (!el) return 0; + + var name = type.charAt(0).toUpperCase() + type.slice(1); + var result = 0; + var style = getComputedStyle(el, null); + var $el = new Dom(el); + var $targets = $el.parents().filter(function(node) + { + return (node.nodeType === 1 && getComputedStyle(node, null).display === 'none') ? node : false; + }); + + if (style.display === 'none') $targets.add(el); + if ($targets.length !== 0) + { + var fixStyle = 'visibility: hidden !important; display: block !important;'; + var tmp = []; + + $targets.each(function(node) + { + var $node = new Dom(node); + var thisStyle = $node.attr('style'); + if (thisStyle !== null) tmp.push(thisStyle); + $node.attr('style', (thisStyle !== null) ? thisStyle + ';' + fixStyle : fixStyle); + }); + + result = $el.get()['offset' + name] - this._adjustResultHeightOrWidth(type, el, adjust); + + $targets.each(function(node, i) + { + var $node = new Dom(node); + if (tmp[i] === undefined) $node.removeAttr('style'); + else $node.attr('style', tmp[i]); + }); + } + else + { + result = el['offset' + name] - this._adjustResultHeightOrWidth(type, el, adjust); + } + + return result; + }, + _adjustResultHeightOrWidth: function(type, el, adjust) + { + if (!el || adjust === false) return 0; + + var fix = 0; + var style = getComputedStyle(el, null); + var isBorderBox = (style.boxSizing === "border-box"); + + if (type === 'height') + { + if (adjust === 'inner' || (adjust === 'normal' && isBorderBox)) + { + fix += (parseFloat(style.borderTopWidth) || 0) + (parseFloat(style.borderBottomWidth) || 0); + } + + if (adjust === 'outer') fix -= (parseFloat(style.marginTop) || 0) + (parseFloat(style.marginBottom) || 0); + } + else + { + if (adjust === 'inner' || (adjust === 'normal' && isBorderBox)) + { + fix += (parseFloat(style.borderLeftWidth) || 0) + (parseFloat(style.borderRightWidth) || 0); + } + + if (adjust === 'outer') fix -= (parseFloat(style.marginLeft) || 0) + (parseFloat(style.marginRight) || 0); + } + + return fix; + }, + _getDim: function(type) + { + var node = this.get(); + return (node.nodeType === 3) ? { top: 0, left: 0 } : this['_get' + type](node); + }, + _getPosition: function(node) + { + return { top: node.offsetTop, left: node.offsetLeft }; + }, + _getOffset: function(node) + { + var rect = node.getBoundingClientRect(); + var doc = node.ownerDocument; + var docElem = doc.documentElement; + var win = doc.defaultView; + + return { + top: rect.top + win.pageYOffset - docElem.clientTop, + left: rect.left + win.pageXOffset - docElem.clientLeft + }; + }, + _getSibling: function(selector, method) + { + selector = (selector && selector.dom) ? selector.get() : selector; + + var isNode = (selector && selector.nodeType); + var sibling; + + this.each(function(node) + { + while (node = node[method]) + { + if ((isNode && node === selector) || new Dom(node).is(selector)) + { + sibling = node; + return; + } + } + }); + + return new Dom(sibling); + }, + _toArray: function(obj) + { + if (obj instanceof NodeList) + { + var arr = []; + for (var i = 0; i < obj.length; i++) + { + arr[i] = obj[i]; + } + + return arr; + } + else if (obj === undefined) return []; + else + { + return (obj.dom) ? obj.nodes : obj; + } + }, + _toParams: function(obj) + { + var params = ''; + for (var key in obj) + { + params += '&' + this._encodeUri(key) + '=' + this._encodeUri(obj[key]); + } + + return params.replace(/^&/, ''); + }, + _toObject: function(str) + { + return (new Function("return " + str))(); + }, + _encodeUri: function(str) + { + return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'); + }, + _isNumber: function(str) + { + return !isNaN(str) && !isNaN(parseFloat(str)); + }, + _isObjectString: function(str) + { + return (str.search(/^{/) !== -1); + }, + _getBooleanFromStr: function(str) + { + if (str === 'true') return true; + else if (str === 'false') return false; + + return str; + }, + _hasDisplayNone: function(el) + { + return (el.style.display === 'none') || ((el.currentStyle) ? el.currentStyle.display : getComputedStyle(el, null).display) === 'none'; + } +}; +// Unique ID +var uuid = 0; + +// Wrapper +var $R = function(selector, options) +{ + return RedactorApp(selector, options, [].slice.call(arguments, 2)); +}; + +// Globals +$R.app = []; +$R.version = '3.1.4'; +$R.options = {}; +$R.modules = {}; +$R.services = {}; +$R.classes = {}; +$R.plugins = {}; +$R.mixins = {}; +$R.modals = {}; +$R.lang = {}; +$R.dom = function(selector, context) { return new Dom(selector, context); }; +$R.ajax = Ajax; +$R.Dom = Dom; +$R.keycodes = { + BACKSPACE: 8, + DELETE: 46, + UP: 38, + DOWN: 40, + ENTER: 13, + SPACE: 32, + ESC: 27, + TAB: 9, + CTRL: 17, + META: 91, + SHIFT: 16, + ALT: 18, + RIGHT: 39, + LEFT: 37 +}; +$R.env = { + 'plugin': 'plugins', + 'module': 'modules', + 'service': 'services', + 'class': 'classes', + 'mixin': 'mixins' +}; + +// jQuery Wrapper +/*eslint-env jquery*/ +if (typeof jQuery !== 'undefined') +{ + (function($) { $.fn.redactor = function(options) { return RedactorApp(this.toArray(), options, [].slice.call(arguments, 1)); }; })(jQuery); +} + +// Class +var RedactorApp = function(selector, options, args) +{ + var namespace = 'redactor'; + var nodes = (Array.isArray(selector)) ? selector : (selector && selector.nodeType) ? [selector] : document.querySelectorAll(selector); + var isApi = (typeof options === 'string' || typeof options === 'function'); + var value = []; + var instance; + + for (var i = 0; i < nodes.length; i++) + { + var el = nodes[i]; + var $el = $R.dom(el); + + instance = $el.dataget(namespace); + if (!instance && !isApi) + { + // Initialization + instance = new App(el, options, uuid); + $el.dataset(namespace, instance); + $R.app[uuid] = instance; + uuid++; + } + + // API + if (instance && isApi) + { + var isDestroy = (options === 'destroy'); + options = (isDestroy) ? 'stop' : options; + + var methodValue; + if (typeof options === 'function') + { + methodValue = options.apply(instance, args); + } + else + { + args.unshift(options); + methodValue = instance.api.apply(instance, args); + } + if (methodValue !== undefined) value.push(methodValue); + + if (isDestroy) $el.dataset(namespace, false); + } + } + + return (value.length === 0 || value.length === 1) ? ((value.length === 0) ? instance : value[0]) : value; +}; + +// add +$R.add = function(type, name, obj) +{ + if (typeof $R.env[type] === 'undefined') return; + + // translations + if (obj.translations) + { + $R.lang = $R.extend(true, {}, $R.lang, obj.translations); + } + + // modals + if (obj.modals) + { + $R.modals = $R.extend(true, {}, $R.modals, obj.modals); + } + + // mixin + if (type === 'mixin') + { + $R[$R.env[type]][name] = obj; + } + else + { + // prototype + var F = function() {}; + F.prototype = obj; + + // mixins + if (obj.mixins) + { + for (var i = 0; i < obj.mixins.length; i++) + { + $R.inherit(F, $R.mixins[obj.mixins[i]]); + } + } + + $R[$R.env[type]][name] = F; + } +}; + +// add lang +$R.addLang = function(lang, obj) +{ + if (typeof $R.lang[lang] === 'undefined') + { + $R.lang[lang] = {}; + } + + $R.lang[lang] = $R.extend($R.lang[lang], obj); +}; + +// create +$R.create = function(name) +{ + var arr = name.split('.'); + var args = [].slice.call(arguments, 1); + + var type = 'classes'; + if (typeof $R.env[arr[0]] !== 'undefined') + { + type = $R.env[arr[0]]; + name = arr.slice(1).join('.'); + } + + // construct + var instance = new $R[type][name](); + + // init + if (instance.init) + { + var res = instance.init.apply(instance, args); + + return (res) ? res : instance; + } + + return instance; +}; + +// inherit +$R.inherit = function(current, parent) +{ + var F = function () {}; + F.prototype = parent; + var f = new F(); + + for (var prop in current.prototype) + { + if (current.prototype.__lookupGetter__(prop)) f.__defineGetter__(prop, current.prototype.__lookupGetter__(prop)); + else f[prop] = current.prototype[prop]; + } + + current.prototype = f; + current.prototype.super = parent; + + return current; +}; + +// error +$R.error = function(exception) +{ + throw exception; +}; + +// extend +$R.extend = function() +{ + var extended = {}; + var deep = false; + var i = 0; + var length = arguments.length; + + if (Object.prototype.toString.call( arguments[0] ) === '[object Boolean]') + { + deep = arguments[0]; + i++; + } + + var merge = function(obj) + { + for (var prop in obj) + { + if (Object.prototype.hasOwnProperty.call(obj, prop)) + { + if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') extended[prop] = $R.extend(true, extended[prop], obj[prop]); + else extended[prop] = obj[prop]; + } + } + }; + + for (; i < length; i++ ) + { + var obj = arguments[i]; + merge(obj); + } + + return extended; +}; +$R.opts = { + animation: true, + lang: 'en', + direction: 'ltr', + spellcheck: true, + structure: false, + scrollTarget: false, + styles: true, + stylesClass: 'redactor-styles', + placeholder: false, + + source: true, + showSource: false, + + inline: false, + + breakline: false, + markup: 'p', + enterKey: true, + + clickToEdit: false, + clickToSave: false, + clickToCancel: false, + + focus: false, + focusEnd: false, + + minHeight: false, // string, '100px' + maxHeight: false, // string, '100px' + maxWidth: false, // string, '700px' + + plugins: [], // array + callbacks: {}, + + // pre & tab + preClass: false, // string + preSpaces: 4, // or false + tabindex: false, // int + tabAsSpaces: false, // true or number of spaces + tabKey: true, + + // autosave + autosave: false, // false or url + autosaveName: false, + autosaveData: false, + + // toolbar + toolbar: true, + toolbarFixed: true, + toolbarFixedTarget: document, + toolbarFixedTopOffset: 0, // pixels + toolbarExternal: false, // ID selector + toolbarContext: true, + + // air + air: false, + + // formatting + formatting: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], + formattingAdd: false, + formattingHide: false, + + // buttons + buttons: ['html', 'format', 'bold', 'italic', 'deleted', 'lists', 'image', 'file', 'link'], + // + 'line', 'redo', 'undo', 'underline', 'ol', 'ul', 'indent', 'outdent' + buttonsTextLabeled: false, + buttonsAdd: [], + buttonsAddFirst: [], + buttonsAddAfter: false, + buttonsAddBefore: false, + buttonsHide: [], + buttonsHideOnMobile: [], + + // image + imageUpload: false, + imageUploadParam: 'file', + imageData: false, + imageEditable: true, + imageCaption: true, + imageLink: true, + imagePosition: false, + imageResizable: false, + imageFloatMargin: '10px', + imageFigure: true, + + // file + fileUpload: false, + fileUploadParam: 'file', + fileData: false, + fileAttachment: false, + + // upload opts + uploadData: false, + dragUpload: true, + multipleUpload: true, + clipboardUpload: true, + uploadBase64: false, + + // link + linkTarget: false, + linkTitle: false, + linkNewTab: false, + linkNofollow: false, + linkSize: 30, + linkValidation: true, + + // clean + cleanOnEnter: true, + cleanInlineOnEnter: false, + paragraphize: true, + removeScript: true, + removeNewLines: false, + removeComments: true, + replaceTags: { + 'b': 'strong', + 'i': 'em', + 'strike': 'del' + }, + + // paste + pastePlainText: false, + pasteLinkTarget: false, + pasteImages: true, + pasteLinks: true, + pasteClean: true, + pasteKeepStyle: [], + pasteKeepClass: [], + pasteKeepAttrs: ['td', 'th'], + pasteBlockTags: ['pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'tbody', 'thead', 'tfoot', 'th', 'tr', 'td', 'ul', 'ol', 'li', 'blockquote', 'p', 'figure', 'figcaption'], + pasteInlineTags: ['a', 'img', 'br', 'strong', 'ins', 'code', 'del', 'span', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small', 'b', 'u', 'em', 'i', 'abbr'], + + // active buttons + activeButtons: { + b: 'bold', + strong: 'bold', + i: 'italic', + em: 'italic', + del: 'deleted', + strike: 'deleted', + u: 'underline' + }, + activeButtonsAdd: {}, + activeButtonsObservers: {}, + + // autoparser + autoparse: true, + autoparseStart: true, + autoparsePaste: true, + autoparseLinks: true, + autoparseImages: true, + autoparseVideo: true, + + // shortcodes + shortcodes: { + 'p.': { format: 'p' }, + 'quote.': { format: 'blockquote' }, + 'pre.': { format: 'pre' }, + 'h1.': { format: 'h1' }, + 'h2.': { format: 'h2' }, + 'h3.': { format: 'h3' }, + 'h4.': { format: 'h4' }, + 'h5.': { format: 'h5' }, + 'h6.': { format: 'h6' }, + //'1.': { format: 'ol' }, + '*.': { format: 'ul' } + }, + shortcodesAdd: false, // object + + // shortcuts + shortcuts: { + 'ctrl+shift+m, meta+shift+m': { api: 'module.inline.clearformat' }, + 'ctrl+b, meta+b': { api: 'module.inline.format', args: 'b' }, + 'ctrl+i, meta+i': { api: 'module.inline.format', args: 'i' }, + 'ctrl+u, meta+u': { api: 'module.inline.format', args: 'u' }, + 'ctrl+h, meta+h': { api: 'module.inline.format', args: 'sup' }, + 'ctrl+l, meta+l': { api: 'module.inline.format', args: 'sub' }, + 'ctrl+k, meta+k': { api: 'module.link.open' }, + 'ctrl+alt+0, meta+alt+0': { api: 'module.block.format', args: 'p' }, + 'ctrl+alt+1, meta+alt+1': { api: 'module.block.format', args: 'h1' }, + 'ctrl+alt+2, meta+alt+2': { api: 'module.block.format', args: 'h2' }, + 'ctrl+alt+3, meta+alt+3': { api: 'module.block.format', args: 'h3' }, + 'ctrl+alt+4, meta+alt+4': { api: 'module.block.format', args: 'h4' }, + 'ctrl+alt+5, meta+alt+5': { api: 'module.block.format', args: 'h5' }, + 'ctrl+alt+6, meta+alt+6': { api: 'module.block.format', args: 'h6' }, + 'ctrl+shift+7, meta+shift+7': { api: 'module.list.toggle', args: 'ol' }, + 'ctrl+shift+8, meta+shift+8': { api: 'module.list.toggle', args: 'ul' } + }, + shortcutsAdd: false, // object + + // misc + grammarly: true, + + // private + bufferLimit: 100, + emptyHtml: '
', + markerChar: '\ufeff', + imageTypes: ['image/png', 'image/jpeg', 'image/gif'], + inlineTags: ['a', 'span', 'strong', 'strike', 'b', 'u', 'em', 'i', 'code', 'del', 'ins', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small', 'abbr'], + blockTags: ['pre', 'ul', 'ol', 'li', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dl', 'dt', 'dd', 'div', 'table', 'tbody', 'thead', 'tfoot', 'tr', 'th', 'td', 'blockquote', 'output', 'figcaption', 'figure', 'address', 'section', 'header', 'footer', 'aside', 'article', 'iframe'], + regex: { + youtube: /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gi, + vimeo: /(http|https)?:\/\/(?:www.|player.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^\/]*)\/videos\/|album\/(?:\d+)\/video\/|video\/|)(\d+)(?:[a-zA-Z0-9_-]+)?/gi, + imageurl: /((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/gi, + url: /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi + }, + input: true, + zindex: false, + modes: { + "inline": { + pastePlainText: true, + pasteImages: false, + enterKey: false, + toolbar: false, + autoparse: false, + source: false, + showSource: false, + styles: false, + air: false + }, + "original": { + styles: false + } + } +}; +$R.lang['en'] = { + "format": "Format", + "image": "Image", + "file": "File", + "link": "Link", + "bold": "Bold", + "italic": "Italic", + "deleted": "Strikethrough", + "underline": "Underline", + "superscript": "Superscript", + "subscript": "Subscript", + "bold-abbr": "B", + "italic-abbr": "I", + "deleted-abbr": "S", + "underline-abbr": "U", + "superscript-abbr": "Sup", + "subscript-abbr": "Sub", + "lists": "Lists", + "link-insert": "Insert Link", + "link-edit": "Edit Link", + "link-in-new-tab": "Open link in new tab", + "unlink": "Unlink", + "cancel": "Cancel", + "close": "Close", + "insert": "Insert", + "save": "Save", + "delete": "Delete", + "text": "Text", + "edit": "Edit", + "title": "Title", + "paragraph": "Normal text", + "quote": "Quote", + "code": "Code", + "heading1": "Heading 1", + "heading2": "Heading 2", + "heading3": "Heading 3", + "heading4": "Heading 4", + "heading5": "Heading 5", + "heading6": "Heading 6", + "filename": "Name", + "optional": "optional", + "unorderedlist": "Unordered List", + "orderedlist": "Ordered List", + "outdent": "Outdent", + "indent": "Indent", + "horizontalrule": "Line", + "upload": "Upload", + "upload-label": "Drop files here or click to upload", + "accessibility-help-label": "Rich text editor", + "caption": "Caption", + "bulletslist": "Bullets", + "numberslist": "Numbers", + "image-position": "Position", + "none": "None", + "left": "Left", + "right": "Right", + "center": "Center", + "undo": "Undo", + "redo": "Redo" +}; +$R.buttons = { + html: { + title: 'HTML', + icon: true, + api: 'module.source.toggle' + }, + undo: { + title: '## undo ##', + icon: true, + api: 'module.buffer.undo' + }, + redo: { + title: '## redo ##', + icon: true, + api: 'module.buffer.redo' + }, + format: { + title: '## format ##', + icon: true, + dropdown: { + p: { + title: '## paragraph ##', + api: 'module.block.format', + args: { + tag: 'p' + } + }, + blockquote: { + title: '## quote ##', + api: 'module.block.format', + args: { + tag: 'blockquote' + } + }, + pre: { + title: '## code ##', + api: 'module.block.format', + args: { + tag: 'pre' + } + }, + h1: { + title: '## heading1 ##', + api: 'module.block.format', + args: { + tag: 'h1' + } + }, + h2: { + title: '## heading2 ##', + api: 'module.block.format', + args: { + tag: 'h2' + } + }, + h3: { + title: '## heading3 ##', + api: 'module.block.format', + args: { + tag: 'h3' + } + }, + h4: { + title: '## heading4 ##', + api: 'module.block.format', + args: { + tag: 'h4' + } + }, + h5: { + title: '## heading5 ##', + api: 'module.block.format', + args: { + tag: 'h5' + } + }, + h6: { + title: '## heading6 ##', + api: 'module.block.format', + args: { + tag: 'h6' + } + } + } + }, + bold: { + title: '## bold-abbr ##', + icon: true, + tooltip: '## bold ##', + api: 'module.inline.format', + args: { + tag: 'b' + } + }, + italic: { + title: '## italic-abbr ##', + icon: true, + tooltip: '## italic ##', + api: 'module.inline.format', + args: { + tag: 'i' + } + }, + deleted: { + title: '## deleted-abbr ##', + icon: true, + tooltip: '## deleted ##', + api: 'module.inline.format', + args: { + tag: 'del' + } + }, + underline: { + title: '## underline-abbr ##', + icon: true, + tooltip: '## underline ##', + api: 'module.inline.format', + args: { + tag: 'u' + } + }, + sup: { + title: '## superscript-abbr ##', + icon: true, + tooltip: '## superscript ##', + api: 'module.inline.format', + args: { + tag: 'sup' + } + }, + sub: { + title: '## subscript-abbr ##', + icon: true, + tooltip: '## subscript ##', + api: 'module.inline.format', + args: { + tag: 'sub' + } + }, + lists: { + title: '## lists ##', + icon: true, + observe: 'list', + dropdown: { + observe: 'list', + unorderedlist: { + title: '• ## unorderedlist ##', + api: 'module.list.toggle', + args: 'ul' + }, + orderedlist: { + title: '1. ## orderedlist ##', + api: 'module.list.toggle', + args: 'ol' + }, + outdent: { + title: '< ## outdent ##', + api: 'module.list.outdent' + }, + indent: { + title: '> ## indent ##', + api: 'module.list.indent' + } + } + }, + ul: { + title: '• ## bulletslist ##', + icon: true, + api: 'module.list.toggle', + observe: 'list', + args: 'ul' + }, + ol: { + title: '1. ## numberslist ##', + icon: true, + api: 'module.list.toggle', + observe: 'list', + args: 'ol' + }, + outdent: { + title: '## outdent ##', + icon: true, + api: 'module.list.outdent', + observe: 'list' + }, + indent: { + title: '## indent ##', + icon: true, + api: 'module.list.indent', + observe: 'list' + }, + image: { + title: '## image ##', + icon: true, + api: 'module.image.open' + }, + file: { + title: '## file ##', + icon: true, + api: 'module.file.open' + }, + link: { + title: '## link ##', + icon: true, + observe: 'link', + dropdown: { + observe: 'link', + link: { + title: '## link-insert ##', + api: 'module.link.open' + }, + unlink: { + title: '## unlink ##', + api: 'module.link.unlink' + } + } + }, + line: { + title: '## horizontalrule ##', + icon: true, + api: 'module.line.insert' + } +}; +var App = function(element, options, uuid) +{ + this.module = {}; + this.plugin = {}; + this.instances = {}; + + // start/stop + this.started = false; + this.stopped = false; + + // environment + this.uuid = uuid; + this.rootElement = element; + this.rootOpts = options; + this.dragInside = false; + this.dragComponentInside = false; + this.keycodes = $R.keycodes; + this.namespace = 'redactor'; + this.$win = $R.dom(window); + this.$doc = $R.dom(document); + this.$body = $R.dom('body'); + this.editorReadOnly = false; + + // core services + this.opts = $R.create('service.options', options, element); + this.lang = $R.create('service.lang', this); + + // build + this.buildServices(); + this.buildModules(); + this.buildPlugins(); + + // start + this.start(); +}; + +App.prototype = { + start: function() + { + // start + this.stopped = false; + this.broadcast('start'); + this.broadcast('startcode'); + + if (this.opts.clickToEdit) + { + this.broadcast('startclicktoedit'); + } + else + { + this.broadcast('enable'); + if (this.opts.showSource) this.broadcast('startcodeshow'); + this.broadcast('enablefocus'); + } + + // started + this.broadcast('started'); + this.started = true; + }, + stop: function() + { + this.started = false; + this.stopped = true; + + this.broadcast('stop'); + this.broadcast('disable'); + this.broadcast('stopped'); + }, + + // started & stopped + isStarted: function() + { + return this.started; + }, + isStopped: function() + { + return this.stopped; + }, + + // build + buildServices: function() + { + var core = ['options', 'lang']; + var bindable = ['uuid', 'keycodes', 'opts', 'lang', '$win', '$doc', '$body']; + var services = []; + for (var name in $R.services) + { + if (core.indexOf(name) === -1) + { + this[name] = $R.create('service.' + name, this); + services.push(name); + bindable.push(name); + } + } + + // binding + for (var i = 0; i < services.length; i++) + { + var service = services[i]; + for (var z = 0; z < bindable.length; z++) + { + var inj = bindable[z]; + if (service !== inj) + { + this[service][inj] = this[inj]; + } + } + } + }, + buildModules: function() + { + for (var name in $R.modules) + { + this.module[name] = $R.create('module.' + name, this); + this.instances[name] = this.module[name]; + } + }, + buildPlugins: function() + { + var plugins = this.opts.plugins; + for (var i = 0; i < plugins.length; i++) + { + var name = plugins[i]; + if (typeof $R.plugins[name] !== 'undefined') + { + this.plugin[name] = $R.create('plugin.' + name, this); + this.instances[name] = this.plugin[name]; + } + } + }, + + // draginside + isDragInside: function() + { + return this.dragInside; + }, + setDragInside: function(dragInside) + { + this.dragInside = dragInside; + }, + isDragComponentInside: function() + { + return this.dragComponentInside; + }, + setDragComponentInside: function(dragInside) + { + this.dragComponentInside = dragInside; + }, + getDragComponentInside: function() + { + return this.dragComponentInside; + }, + + // readonly + isReadOnly: function() + { + return this.editorReadOnly; + }, + enableReadOnly: function() + { + this.editorReadOnly = true; + this.broadcast('enablereadonly'); + this.component.clearActive(); + this.toolbar.disableButtons(); + }, + disableReadOnly: function() + { + this.editorReadOnly = false; + this.broadcast('disablereadonly'); + this.toolbar.enableButtons(); + }, + + // messaging + callMessageHandler: function(instance, name, args) + { + var arr = name.split('.'); + if (arr.length === 1) + { + if (typeof instance['on' + name] === 'function') + { + instance['on' + name].apply(instance, args); + } + } + else + { + arr[0] = 'on' + arr[0]; + + var func = this.utils.checkProperty(instance, arr); + if (typeof func === 'function') + { + func.apply(instance, args); + } + } + }, + broadcast: function(name) + { + var args = [].slice.call(arguments, 1); + for (var moduleName in this.instances) + { + this.callMessageHandler(this.instances[moduleName], name, args); + } + + // callback + return this.callback.trigger(name, args); + }, + + // callback + on: function(name, func) + { + this.callback.add(name, func); + }, + off: function(name, func) + { + this.callback.remove(name, func); + }, + + // api + api: function(name) + { + if (!this.isStarted() && name !== 'start') return; + if (this.isReadOnly() && name !== 'disableReadOnly') return; + + this.broadcast('state'); + + var args = [].slice.call(arguments, 1); + var arr = name.split('.'); + + var isApp = (arr.length === 1); + var isCallback = (arr[0] === 'on' || arr[0] === 'off'); + var isService = (!isCallback && arr.length === 2); + var isPlugin = (arr[0] === 'plugin'); + var isModule = (arr[0] === 'module'); + + // app + if (isApp) + { + if (typeof this[arr[0]] === 'function') + { + return this.callInstanceMethod(this, arr[0], args); + } + } + // callback + else if (isCallback) + { + return (arr[0] === 'on') ? this.on(arr[1], args[0]) : this.off(arr[1], args[0] || undefined); + } + // service + else if (isService) + { + if (this.isInstanceExists(this, arr[0])) + { + return this.callInstanceMethod(this[arr[0]], arr[1], args); + } + else + { + $R.error(new Error('Service "' + arr[0] + '" not found')); + } + } + // plugin + else if (isPlugin) + { + if (this.isInstanceExists(this.plugin, arr[1])) + { + return this.callInstanceMethod(this.plugin[arr[1]], arr[2], args); + } + else + { + $R.error(new Error('Plugin "' + arr[1] + '" not found')); + } + } + // module + else if (isModule) + { + if (this.isInstanceExists(this.module, arr[1])) + { + return this.callInstanceMethod(this.module[arr[1]], arr[2], args); + } + else + { + $R.error(new Error('Module "' + arr[1] + '" not found')); + } + } + + }, + isInstanceExists: function(obj, name) + { + return (typeof obj[name] !== 'undefined'); + }, + callInstanceMethod: function(instance, method, args) + { + if (typeof instance[method] === 'function') + { + return instance[method].apply(instance, args); + } + } +}; +$R.add('mixin', 'formatter', { + + // public + buildArgs: function(args) + { + this.args = { + 'class': args['class'] || false, + 'style': args['style'] || false, + 'attr': args['attr'] || false + }; + + if (!this.args['class'] && !this.args['style'] && !this.args['attr']) + { + this.args = false; + } + }, + applyArgs: function(nodes, selection) + { + if (this.args) + { + nodes = this[this.type](this.args, false, nodes, selection); + } + else + { + nodes = this._clearAll(nodes, selection); + } + + return nodes; + }, + clearClass: function(tags, nodes) + { + this.selection.save(); + + var $elements = (nodes) ? $R.dom(nodes) : this.getElements(tags, true); + $elements.removeAttr('class'); + + nodes = this._unwrapSpanWithoutAttr($elements.getAll()); + + this.selection.restore(); + + return nodes; + }, + clearStyle: function(tags, nodes) + { + this.selection.save(); + + var $elements = (nodes) ? $R.dom(nodes) : this.getElements(tags, true); + $elements.removeAttr('style'); + + nodes = this._unwrapSpanWithoutAttr($elements.getAll()); + + this.selection.restore(); + + return nodes; + }, + clearAttr: function(tags, nodes) + { + this.selection.save(); + + var $elements = (nodes) ? $R.dom(nodes) : this.getElements(tags, true); + this._removeAllAttr($elements); + + nodes = this._unwrapSpanWithoutAttr($elements.getAll()); + + this.selection.restore(); + + return nodes; + }, + set: function(args, tags, nodes, selection) + { + if (selection !== false) this.selection.save(); + + var $elements = (nodes) ? $R.dom(nodes) : this.getElements(tags); + + if (args['class']) + { + $elements.removeAttr('class'); + $elements.addClass(args['class']); + } + + if (args['style']) + { + $elements.removeAttr('style'); + $elements.css(args['style']); + $elements.each(function(node) + { + var $node = $R.dom(node); + $node.attr('data-redactor-style-cache', $node.attr('style')); + }); + } + + if (args['attr']) + { + this._removeAllAttr($elements); + $elements.attr(args['attr']); + } + + if (selection !== false) this.selection.restore(); + + return $elements.getAll(); + }, + toggle: function(args, tags, nodes, selection) + { + if (selection !== false) this.selection.save(); + + var $elements = (nodes) ? $R.dom(nodes) : this.getElements(tags); + + if (args['class']) + { + $elements.toggleClass(args['class']); + $elements.each(function(node) + { + if (node.className === '') node.removeAttribute('class'); + }); + } + + var params; + if (args['style']) + { + params = args['style']; + $elements.each(function(node) + { + var $node = $R.dom(node); + for (var key in params) + { + var newVal = params[key]; + var oldVal = $node.css(key); + + oldVal = (this.utils.isRgb(oldVal)) ? this.utils.rgb2hex(oldVal) : oldVal.replace(/"/g, ''); + newVal = (this.utils.isRgb(newVal)) ? this.utils.rgb2hex(newVal) : newVal.replace(/"/g, ''); + + oldVal = this.utils.hex2long(oldVal); + newVal = this.utils.hex2long(newVal); + + var compareNew = (typeof newVal === 'string') ? newVal.toLowerCase() : newVal; + var compareOld = (typeof oldVal === 'string') ? oldVal.toLowerCase() : oldVal; + + if (compareNew === compareOld) $node.css(key, ''); + else $node.css(key, newVal); + } + + this._convertStyleQuotes($node); + if (this.utils.removeEmptyAttr(node, 'style')) + { + $node.removeAttr('data-redactor-style-cache'); + } + else + { + $node.attr('data-redactor-style-cache', $node.attr('style')); + } + + }.bind(this)); + } + + if (args['attr']) + { + params = args['attr']; + $elements.each(function(node) + { + var $node = $R.dom(node); + for (var key in params) + { + if ($node.attr(key)) $node.removeAttr(key); + else $node.attr(key, params[key]); + } + }); + + } + + if (selection !== false) this.selection.restore(); + + return $elements.getAll(); + }, + add: function(args, tags, nodes, selection) + { + if (selection !== false) this.selection.save(); + + var $elements = (nodes) ? $R.dom(nodes) : this.getElements(tags); + + if (args['class']) + { + $elements.addClass(args['class']); + } + + if (args['style']) + { + var params = args['style']; + $elements.each(function(node) + { + var $node = $R.dom(node); + $node.css(params); + $node.attr('data-redactor-style-cache', $node.attr('style')); + + this._convertStyleQuotes($node); + + }.bind(this)); + } + + if (args['attr']) + { + $elements.attr(args['attr']); + } + + if (selection !== false) this.selection.restore(); + + return $elements.getAll(); + }, + remove: function(args, tags, nodes, selection) + { + if (selection !== false) this.selection.save(); + + var $elements = (nodes) ? $R.dom(nodes) : this.getElements(tags); + + if (args['class']) + { + $elements.removeClass(args['class']); + $elements.each(function(node) + { + if (node.className === '') node.removeAttribute('class'); + }); + } + + if (args['style']) + { + var name = args['style']; + $elements.each(function(node) + { + var $node = $R.dom(node); + $node.css(name, ''); + + if (this.utils.removeEmptyAttr(node, 'style')) + { + $node.removeAttr('data-redactor-style-cache'); + } + else + { + $node.attr('data-redactor-style-cache', $node.attr('style')); + } + + }.bind(this)); + } + + if (args['attr']) + { + $elements.removeAttr(args['attr']); + } + + nodes = this._unwrapSpanWithoutAttr($elements.getAll()); + + if (selection !== false) this.selection.restore(); + + return nodes; + }, + + // private + _removeAllAttr: function($elements) + { + $elements.each(function(node) + { + for (var i = node.attributes.length; i-->0;) + { + var nodeAttr = node.attributes[i]; + var name = nodeAttr.name; + if (name !== 'style' && name !== 'class') + { + node.removeAttributeNode(nodeAttr); + } + } + }); + }, + _convertStyleQuotes: function($node) + { + var style = $node.attr('style'); + if (style) $node.attr('style', style.replace(/"/g, '\'')); + }, + _clearAll: function(nodes, selection) + { + if (selection !== false) this.selection.save(); + + for (var i = 0; i < nodes.length; i++) + { + var node = nodes[i]; + while (node.attributes.length > 0) + { + node.removeAttribute(node.attributes[0].name); + } + } + + nodes = this._unwrapSpanWithoutAttr(nodes); + + if (selection !== false) this.selection.restore(); + + return nodes; + }, + _unwrapSpanWithoutAttr: function(nodes) + { + var finalNodes = []; + for (var i = 0; i < nodes.length; i++) + { + var node = nodes[i]; + var len = node.attributes.length; + if (len <= 0 && node.nodeType !== 3 && node.tagName === 'SPAN') + { + $R.dom(node).unwrap(); + } + else + { + finalNodes.push(node); + } + } + + return finalNodes; + } +}); +$R.add('mixin', 'dom', $R.Dom.prototype); +$R.add('mixin', 'component', { + get cmnt() + { + return true; + } +}); +$R.add('service', 'options', { + init: function(options, element) + { + var $el = $R.dom(element); + var opts = $R.extend({}, $R.opts, (element) ? $el.data() : {}, $R.options); + opts = $R.extend(true, opts, options); + + return opts; + } +}); +$R.add('service', 'lang', { + init: function(app) + { + this.app = app; + this.opts = app.opts; + + // build + this.vars = this._build(this.opts.lang); + }, + + // public + rebuild: function(lang) + { + this.opts.lang = lang; + this.vars = this._build(lang); + }, + extend: function(obj) + { + this.vars = $R.extend(this.vars, obj); + }, + parse: function(str) + { + if (str === undefined) + { + return ''; + } + + var matches = str.match(/## (.*?) ##/g); + if (matches) + { + for (var i = 0; i < matches.length; i++) + { + var key = matches[i].replace(/^##\s/g, '').replace(/\s##$/g, ''); + str = str.replace(matches[i], this.get(key)); + } + } + + return str; + }, + get: function(name) + { + var str = ''; + if (typeof this.vars[name] !== 'undefined') + { + str = this.vars[name]; + } + else if (this.opts.lang !== 'en' && typeof $R.lang['en'][name] !== 'undefined') + { + str = $R.lang['en'][name]; + } + + return str; + }, + + // private + _build: function(lang) + { + var vars = $R.lang['en']; + if (lang !== 'en') + { + vars = ($R.lang[lang] !== undefined) ? $R.lang[lang] : vars; + } + + return vars; + } +}); +$R.add('service', 'callback', { + init: function(app) + { + this.app = app; + this.opts = app.opts; + + // local + this.callbacks = {}; + + // build + if (this.opts.callbacks) + { + this._set(this.opts.callbacks, ''); + } + }, + stop: function() + { + this.callbacks = {}; + }, + add: function(name, handler) + { + if (!this.callbacks[name]) this.callbacks[name] = []; + this.callbacks[name].push(handler); + }, + remove: function(name, handler) + { + if (handler === undefined) + { + delete this.callbacks[name]; + } + else + { + for (var i = 0; i < this.callbacks[name].length; i++) + { + this.callbacks[name].splice(i, 1); + } + + if (Object.keys(this.callbacks[name]).length === 0) delete this.callbacks[name]; + } + }, + trigger: function(name, args) + { + var value = this._loop(name, args, this.callbacks); + return (typeof value === 'undefined' && args && args[0] !== false) ? args[0] : value; + }, + + // private + _set: function(obj, name) + { + for (var key in obj) + { + var path = (name === '') ? key : name + '.' + key; + if (typeof obj[key] === 'object') + { + this._set(obj[key], path); + } + else + { + this.callbacks[path] = []; + this.callbacks[path].push(obj[key]); + } + } + }, + _loop: function(name, args, obj) + { + var value; + for (var key in obj) + { + if (name === key) + { + for (var i = 0; i < obj[key].length; i++) + { + value = obj[key][i].apply(this.app, args); + } + } + } + + return value; + } +}); +$R.add('service', 'animate', { + init: function(app) + { + this.animationOpt = app.opts.animation; + }, + start: function(element, animation, options, callback) + { + var defaults = { + duration: false, + iterate: false, + delay: false, + timing: false, + prefix: 'redactor-' + }; + + defaults = (typeof options === 'function') ? defaults : $R.extend(defaults, options); + callback = (typeof options === 'function') ? options : callback; + + // play + return new $R.AnimatePlay(element, animation, defaults, callback, this.animationOpt); + }, + stop: function(element) + { + this.$el = $R.dom(element); + this.$el.removeClass('redactor-animated'); + + var effect = this.$el.attr('redactor-animate-effect'); + this.$el.removeClass(effect); + + this.$el.removeAttr('redactor-animate-effect'); + var hide = this.$el.attr('redactor-animate-hide'); + if (hide) + { + this.$el.addClass(hide).removeAttr('redactor-animate-hide'); + } + + this.$el.off('animationend webkitAnimationEnd'); + } +}); + +$R.AnimatePlay = function(element, animation, defaults, callback, animationOpt) +{ + this.hidableEffects = ['fadeOut', 'flipOut', 'slideUp', 'zoomOut', 'slideOutUp', 'slideOutRight', 'slideOutLeft']; + this.prefixes = ['', '-webkit-']; + + this.$el = $R.dom(element); + this.$body = $R.dom('body'); + this.callback = callback; + this.animation = (!animationOpt) ? this.buildAnimationOff(animation) : animation; + this.defaults = defaults; + + if (this.animation === 'slideUp') + { + this.$el.height(this.$el.height()); + } + + // animate + return (this.isInanimate()) ? this.inanimate() : this.animate(); +}; + +$R.AnimatePlay.prototype = { + buildAnimationOff: function(animation) + { + return (this.isHidable(animation)) ? 'hide' : 'show'; + }, + buildHideClass: function() + { + return 'redactor-animate-hide'; + }, + isInanimate: function() + { + return (this.animation === 'show' || this.animation === 'hide'); + }, + isAnimated: function() + { + return this.$el.hasClass('redactor-animated'); + }, + isHidable: function(effect) + { + return (this.hidableEffects.indexOf(effect) !== -1); + }, + inanimate: function() + { + this.defaults.timing = 'linear'; + + var hide; + if (this.animation === 'show') + { + hide = this.buildHideClass(); + this.$el.attr('redactor-animate-hide', hide); + this.$el.removeClass(hide); + } + else + { + hide = this.$el.attr('redactor-animate-hide'); + this.$el.addClass(hide).removeAttr('redactor-animate-hide'); + } + + if (typeof this.callback === 'function') this.callback(this); + + return this; + }, + animate: function() + { + var delay = (this.defaults.delay) ? this.defaults.delay : 0; + setTimeout(function() + { + this.$body.addClass('no-scroll-x'); + this.$el.addClass('redactor-animated'); + if (!this.$el.attr('redactor-animate-hide')) + { + var hide = this.buildHideClass(); + this.$el.attr('redactor-animate-hide', hide); + this.$el.removeClass(hide); + } + + this.$el.addClass(this.defaults.prefix + this.animation); + this.$el.attr('redactor-animate-effect', this.defaults.prefix + this.animation); + + this.set(this.defaults.duration + 's', this.defaults.iterate, this.defaults.timing); + this.complete(); + + }.bind(this), delay * 1000); + + return this; + }, + set: function(duration, iterate, timing) + { + var len = this.prefixes.length; + + while (len--) + { + if (duration !== false || duration === '') this.$el.css(this.prefixes[len] + 'animation-duration', duration); + if (iterate !== false || iterate === '') this.$el.css(this.prefixes[len] + 'animation-iteration-count', iterate); + if (timing !== false || timing === '') this.$el.css(this.prefixes[len] + 'animation-timing-function', timing); + } + }, + clean: function() + { + this.$body.removeClass('no-scroll-x'); + this.$el.removeClass('redactor-animated'); + this.$el.removeClass(this.defaults.prefix + this.animation); + this.$el.removeAttr('redactor-animate-effect'); + + this.set('', '', ''); + }, + complete: function() + { + this.$el.one('animationend webkitAnimationEnd', function() + { + if (this.$el.hasClass(this.defaults.prefix + this.animation)) this.clean(); + if (this.isHidable(this.animation)) + { + var hide = this.$el.attr('redactor-animate-hide'); + this.$el.addClass(hide).removeAttr('redactor-animate-hide'); + } + + if (this.animation === 'slideUp') this.$el.height(''); + if (typeof this.callback === 'function') this.callback(this.$el); + + }.bind(this)); + } +}; +$R.add('service', 'caret', { + init: function(app) + { + this.app = app; + }, + + // set + setStart: function(el) + { + this._setCaret('Start', el); + }, + setEnd: function(el) + { + this._setCaret('End', el); + }, + setBefore: function(el) + { + this._setCaret('Before', el); + }, + setAfter: function(el) + { + this._setCaret('After', el); + }, + + // is + isStart: function(el) + { + return this._isStartOrEnd(el, 'First'); + }, + isEnd: function(el) + { + return this._isStartOrEnd(el, 'Last'); + }, + + // set side + setAtEnd: function(node) + { + var data = this.inspector.parse(node); + var tag = data.getTag(); + var range = document.createRange(); + if (this._isInPage(node)) + { + if (tag === 'a') + { + var textNode = this.utils.createInvisibleChar(); + node.appendChild(textNode); + + range.setStartBefore(textNode); + range.collapse(true); + } + else + { + range.selectNodeContents(node); + range.collapse(false); + } + + this.selection.setRange(range); + } + }, + setAtStart: function(node) + { + var range = document.createRange(); + var data = this.inspector.parse(node); + if (this._isInPage(node)) + { + range.setStart(node, 0); + range.collapse(true); + + if (data.isInline() || this.utils.isEmpty(node)) + { + var textNode = this.utils.createInvisibleChar(); + range.insertNode(textNode); + range.selectNodeContents(textNode); + range.collapse(false); + } + + this.selection.setRange(range); + } + }, + setAtBefore: function(node) + { + var data = this.inspector.parse(node); + var range = document.createRange(); + if (this._isInPage(node)) + { + range.setStartBefore(node); + range.collapse(true); + + if (data.isInline()) + { + var textNode = this.utils.createInvisibleChar(); + node.parentNode.insertBefore(textNode, node); + range.selectNodeContents(textNode); + range.collapse(false); + } + + this.selection.setRange(range); + } + }, + setAtAfter: function(node) + { + + var range = document.createRange(); + if (this._isInPage(node)) + { + range.setStartAfter(node); + range.collapse(true); + + var textNode = this.utils.createInvisibleChar(); + range.insertNode(textNode); + range.selectNodeContents(textNode); + range.collapse(false); + + this.selection.setRange(range); + } + }, + setAtPrev: function(node) + { + var prev = node.previousSibling; + if (prev) + { + prev = (prev.nodeType === 3 && this._isEmptyTextNode(prev)) ? prev.previousElementSibling : prev; + if (prev) this.setEnd(prev); + } + }, + setAtNext: function(node) + { + var next = node.nextSibling; + if (next) + { + next = (next.nodeType === 3 && this._isEmptyTextNode(next)) ? next.nextElementSibling : next; + if (next) this.setStart(next); + } + }, + + // private + _setCaret: function(type, el) + { + var data = this.inspector.parse(el); + var node = data.getNode(); + + if (node) + { + this.component.clearActive(); + this['_set' + type](node, data, data.getTag()); + } + }, + _setStart: function(node, data, tag) + { + // 1. text + if (data.isText()) + { + this.editor.focus(); + return this.setAtStart(node); + } + // 2. ul, ol + else if (tag === 'ul' || tag === 'ol') + { + node = data.findFirstNode('li'); + + var item = this.utils.getFirstElement(node); + var dataItem = this.inspector.parse(item); + if (item && dataItem.isComponent()) + { + return this.setStart(dataItem.getComponent()); + } + } + // 3. dl + else if (tag === 'dl') + { + node = data.findFirstNode('dt'); + } + // 4. br / hr + else if (tag === 'br' || tag === 'hr') + { + return this.setBefore(node); + } + // 5. th, td + else if (tag === 'td' || tag === 'th') + { + var el = data.getFirstElement(node); + if (el) + { + return this.setStart(el); + } + } + // 6. table + else if (tag === 'table' || tag === 'tr') + { + return this.setStart(data.findFirstNode('th, td')); + } + // 7. figure code + else if (data.isComponentType('code') && !data.isFigcaption()) + { + var code = data.findLastNode('pre, code'); + + this.editor.focus(); + return this.setAtStart(code); + } + // 8. table component + else if (tag === 'figure' && data.isComponentType('table')) + { + var table = data.getTable(); + var tableData = this.inspector.parse(table); + + return this.setStart(tableData.findFirstNode('th, td')); + } + // 9. non editable components + else if (!data.isComponentType('table') && data.isComponent() && !data.isFigcaption()) + { + return this.component.setActive(node); + } + + this.editor.focus(); + + // set + if (!this._setInline(node, 'Start')) + { + this.setAtStart(node); + } + }, + _setEnd: function(node, data, tag) + { + // 1. text + if (data.isText()) + { + this.editor.focus(); + return this.setAtEnd(node); + } + // 2. ul, ol + else if (tag === 'ul' || tag === 'ol') + { + node = data.findLastNode('li'); + + var item = this.utils.getLastElement(node); + var dataItem = this.inspector.parse(item); + if (item && dataItem.isComponent()) + { + return this.setEnd(dataItem.getComponent()); + } + } + // 3. dl + else if (tag === 'dl') + { + node = data.findLastNode('dd'); + } + // 4. br / hr + else if (tag === 'br' || tag === 'hr') + { + return this.setAfter(node); + } + // 5. th, td + else if (tag === 'td' || tag === 'th') + { + var el = data.getLastElement(); + if (el) + { + return this.setEnd(el); + } + } + // 6. table + else if (tag === 'table' || tag === 'tr') + { + return this.setEnd(data.findLastNode('th, td')); + } + // 7. figure code + else if (data.isComponentType('code') && !data.isFigcaption()) + { + var code = data.findLastNode('pre, code'); + + this.editor.focus(); + return this.setAtEnd(code); + } + // 8. table component + else if (tag === 'figure' && data.isComponentType('table')) + { + var table = data.getTable(); + var tableData = this.inspector.parse(table); + + return this.setEnd(tableData.findLastNode('th, td')); + } + // 9. non editable components + else if (!data.isComponentType('table') && data.isComponent() && !data.isFigcaption()) + { + return this.component.setActive(node); + } + + this.editor.focus(); + + // set + if (!this._setInline(node, 'End')) + { + // is element empty + if (this.utils.isEmpty(node)) + { + return this.setStart(node); + } + + this.setAtEnd(node); + } + }, + _setBefore: function(node, data, tag) + { + // text + if (node.nodeType === 3) + { + return this.setAtBefore(node); + } + // inline + else if (data.isInline()) + { + return this.setAtBefore(node); + } + // td / th + else if (data.isFirstTableCell()) + { + return this.setAtPrev(data.getComponent()); + } + else if (tag === 'td' || tag === 'th') + { + return this.setAtPrev(node); + } + // li + else if (data.isFirstListItem()) + { + return this.setAtPrev(data.getList()); + } + // figcaption + else if (data.isFigcaption()) + { + return this.setStart(data.getComponent()); + } + // component + else if (!data.isComponentType('table') && data.isComponent()) + { + return this.setAtPrev(data.getComponent()); + } + // block + else if (data.isBlock()) + { + return this.setAtPrev(node); + } + + this.editor.focus(); + this.setAtBefore(node); + + }, + _setAfter: function(node, data, tag) + { + // text + if (node.nodeType === 3) + { + return this.setAtAfter(node); + } + // inline + else if (data.isInline()) + { + return this.setAtAfter(node); + } + // td / th + else if (data.isLastTableCell()) + { + return this.setAtNext(data.getComponent()); + } + else if (tag === 'td' || tag === 'th') + { + return this.setAtNext(node); + } + // li + else if (data.isFirstListItem()) + { + return this.setAtNext(data.getList()); + } + // component + else if (!data.isComponentType('table') && data.isComponent()) + { + return this.setAtNext(data.getComponent()); + } + // block + else if (data.isBlock()) + { + return this.setAtNext(node); + } + + this.editor.focus(); + this.setAtAfter(node); + }, + _setInline: function(node, type) + { + // is first element inline (FF only) + var inline = this._hasInlineChild(node, (type === 'Start') ? 'first' : 'last'); + if (inline) + { + if (type === 'Start') + { + this.setStart(inline); + } + else + { + this.setEnd(inline); + } + + return true; + } + }, + _isStartOrEnd: function(el, type) + { + var node = this.utils.getNode(el); + if (!node) return false; + + var data = this.inspector.parse(node); + node = this._getStartEndNode(node, data, type); + + if (node && (node.nodeType !== 3 && node.tagName !== 'LI')) + { + var html = (node.nodeType === 3) ? node.textContent : node.innerHTML; + html = this.utils.trimSpaces(html); + if (html === '') return true; + } + + if (!data.isFigcaption() && data.isComponent() && !data.isComponentEditable()) + { + return true; + } + + var offset = this.offset.get(node, true); + if (offset) + { + return (type === 'First') ? (offset.start === 0) : (offset.end === this.offset.size(node, true)); + } + else + { + return false; + } + }, + _isInPage: function(node) + { + if (node && node.nodeType) + { + return (node === document.body) ? false : document.body.contains(node); + } + else + { + return false; + } + }, + _hasInlineChild: function(el, pos) + { + var data = this.inspector.parse(el); + var node = (pos === 'first') ? data.getFirstNode() : data.getLastNode(); + var $node = $R.dom(node); + + if (node && node.nodeType !== 3 + && this.inspector.isInlineTag(node.tagName) + && !$node.hasClass('redactor-component') + && !$node.hasClass('non-editable')) + { + return node; + } + }, + _isEmptyTextNode: function(node) + { + var text = node.textContent.trim().replace(/\n/, ''); + text = this.utils.removeInvisibleChars(text); + + return (text === ''); + }, + _getStartEndNode: function(node, data, type) + { + if (data.isFigcaption()) + { + node = data.getFigcaption(); + } + else if (data.isTable()) + { + node = data['find' + type + 'Node']('th, td'); + } + else if (data.isList()) + { + node = data['find' + type + 'Node']('li'); + } + else if (data.isComponentType('code')) + { + node = data.findLastNode('pre, code'); + } + + return node; + } +}); +$R.add('service', 'selection', { + init: function(app) + { + this.app = app; + }, + // is + is: function() + { + var sel = this.get(); + if (sel) + { + var node = sel.anchorNode; + var data = this.inspector.parse(node); + + return (data.isInEditor() || data.isEditor()); + } + + return false; + }, + isCollapsed: function() + { + var sel = this.get(); + var range = this.getRange(); + + if (sel && sel.isCollapsed) return true; + else if (range && range.toString().length === 0) return true; + + return false; + }, + isBackwards: function() + { + var backwards = false; + var sel = this.get(); + + if (sel && !sel.isCollapsed) + { + var range = document.createRange(); + range.setStart(sel.anchorNode, sel.anchorOffset); + range.setEnd(sel.focusNode, sel.focusOffset); + backwards = range.collapsed; + range.detach(); + } + + return backwards; + }, + isIn: function(el) + { + var node = $R.dom(el).get(); + var current = this.getCurrent(); + + return (current && node) ? node.contains(current) : false; + }, + isText: function() + { + var sel = this.get(); + if (sel) + { + var el = sel.anchorNode; + var block = this.getBlock(el); + var blocks = this.getBlocks(); + + // td, th or hasn't block + if ((block && this.inspector.isTableCellTag(block.tagName)) || (block === false && blocks.length === 0)) + { + return true; + } + } + + return false; + }, + isAll: function(el) + { + var node = this.utils.getNode(el); + if (!node) return false; + + var isEditor = this.editor.isEditor(node); + var data = this.inspector.parse(node); + + // component + if (!data.isFigcaption() && this.component.isNonEditable(node) && this.component.isActive(node)) + { + return true; + } + + if (isEditor) + { + var $editor = this.editor.getElement(); + var output = $editor.html().replace(/<\/p>$/i, ''); + var htmlLen = this.getHtml(false).length; + var outputLen = output.length; + + if (htmlLen !== outputLen) + { + return false; + } + } + + // editor empty or collapsed + if ((isEditor && this.editor.isEmpty()) || this.isCollapsed()) + { + return false; + } + + // all + var offset = this.offset.get(node, true); + var size = this.offset.size(node, true); + + // pre, table, or pre/code in figure + if (!isEditor && data.isComponentType('code')) + { + size = this.getText().trim().length; + } + + if (offset && offset.start === 0 && offset.end === size) + { + return true; + } + + return false; + }, + + // has + hasNonEditable: function() + { + var selected = this.getHtml(); + var $wrapper = $R.dom('
<\/p>$/i, '');
+ }
+
+ return html;
+ },
+
+ // clear
+ clear: function()
+ {
+ this.component.clearActive();
+ this.get().removeAllRanges();
+ },
+
+ // collapse
+ collapseToStart: function()
+ {
+ var sel = this.get();
+ if (sel && !sel.isCollapsed) sel.collapseToStart();
+ },
+ collapseToEnd: function()
+ {
+ var sel = this.get();
+ if (sel && !sel.isCollapsed) sel.collapseToEnd();
+ },
+
+ // save
+ saveActiveComponent: function()
+ {
+ var activeComponent = this.component.getActive();
+ if (activeComponent)
+ {
+ this.savedComponent = activeComponent;
+ return true;
+ }
+
+ return false;
+ },
+ restoreActiveComponent: function()
+ {
+ if (this.savedComponent)
+ {
+ this.component.setActive(this.savedComponent);
+ return true;
+ }
+
+ return false;
+ },
+ save: function()
+ {
+ this._clearSaved();
+
+ var el = this.getElement();
+ var tags = ['TD', 'TH', 'P', 'DIV', 'PRE', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'LI', 'BLOCKQUOTE'];
+ if (el && (tags.indexOf(el.tagName) !== -1) && (el.innerHTML === '' || el.innerHTML === '
'))
+ {
+ this.savedElement = el;
+ }
+ else if (!this.saveActiveComponent())
+ {
+ this.saved = this.offset.get();
+ }
+ },
+ restore: function()
+ {
+ if (!this.saved && !this.savedComponent && !this.savedElement) return;
+
+ this.editor.saveScroll();
+
+ if (this.savedElement)
+ {
+ this.caret.setStart(this.savedElement);
+ }
+ else if (!this.restoreActiveComponent())
+ {
+ this.offset.set(this.saved);
+ }
+
+ this._clearSaved();
+ this.editor.restoreScroll();
+ },
+ saveMarkers: function()
+ {
+ this._clearSaved();
+
+ if (!this.saveActiveComponent())
+ {
+ this.marker.insert();
+ }
+ },
+ restoreMarkers: function()
+ {
+ this.editor.saveScroll();
+
+ if (!this.restoreActiveComponent())
+ {
+ this.marker.restore();
+ }
+
+ this._clearSaved();
+ this.editor.restoreScroll();
+ },
+
+ // private
+ _getNextNode: function(node)
+ {
+ if (node.hasChildNodes()) return node.firstChild;
+
+ while (node && !node.nextSibling)
+ {
+ node = node.parentNode;
+ }
+
+ if (!node) return null;
+
+ return node.nextSibling;
+ },
+ _getNodesComponent: function(component)
+ {
+ var current = this.getCurrent();
+ var data = this.inspector.parse(current);
+
+ return (data.isFigcaption()) ? [data.getFigcaption()] : [component];
+ },
+ _getRangeSelectedNodes: function()
+ {
+ var nodes = [];
+ var range = this.getRange();
+ var node = range.startContainer;
+ var startNode = range.startContainer;
+ var endNode = range.endContainer;
+ var $editor = this.editor.getElement();
+
+ // editor
+ if (startNode === $editor.get() && this.isAll())
+ {
+ nodes = this.utils.getChildNodes($editor);
+ }
+ // single node
+ else if (node == endNode)
+ {
+ nodes = [node];
+ }
+ else
+ {
+ while (node && node != endNode)
+ {
+ nodes.push(node = this._getNextNode(node));
+ }
+
+ node = range.startContainer;
+ while (node && node != range.commonAncestorContainer)
+ {
+ nodes.unshift(node);
+ node = node.parentNode;
+ }
+ }
+
+ return nodes;
+ },
+ _isInNodesArray: function(nodes, node)
+ {
+ return (nodes.indexOf(node) !== -1);
+ },
+ _filterEditor: function(nodes)
+ {
+ var filteredNodes = [];
+ for (var i = 0; i < nodes.length; i++)
+ {
+ var data = this.inspector.parse(nodes[i]);
+ if (data.isInEditor())
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ }
+
+ return filteredNodes;
+ },
+ _filterServicesNodes: function(nodes)
+ {
+ var filteredNodes = [];
+ for (var i = 0; i < nodes.length; i++)
+ {
+ var $el = $R.dom(nodes[i]);
+ var skip = false;
+
+ if (nodes[i] && nodes[i].nodeType === 3 && this.utils.isEmpty(nodes[i])) skip = true;
+ if ($el.hasClass('redactor-script-tag')
+ || $el.hasClass('redactor-component-caret')
+ || $el.hasClass('redactor-selection-marker')
+ || $el.hasClass('non-editable')) skip = true;
+
+ if (!skip)
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ }
+
+ return filteredNodes;
+ },
+ _filterNodesTexts: function(nodes, options)
+ {
+ var filteredNodes = [];
+ for (var i = 0; i < nodes.length; i++)
+ {
+ if (nodes[i].nodeType === 3 || (options.keepbr && nodes[i].tagName === 'BR'))
+ {
+ var inline = this.getInline(nodes[i]);
+ var isInline = (inline && options && options.inline === false);
+ if (!isInline)
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ }
+ }
+
+ return filteredNodes;
+ },
+ _filterNodesElements: function(nodes)
+ {
+ var filteredNodes = [];
+ for (var i = 0; i < nodes.length; i++)
+ {
+ if (nodes[i].nodeType !== 3)
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ }
+
+ return filteredNodes;
+ },
+ _filterNodesByTags: function(nodes, tags, passtexts)
+ {
+ var filteredNodes = [];
+ for (var i = 0; i < nodes.length; i++)
+ {
+ if (passtexts && nodes[i].nodeType === 3)
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ else if (nodes[i].nodeType !== 3)
+ {
+ var nodeTag = nodes[i].tagName.toLowerCase();
+ if (tags.indexOf(nodeTag.toLowerCase()) !== -1)
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ }
+ }
+
+ return filteredNodes;
+ },
+ _filterBlocksFirst: function(nodes)
+ {
+ var filteredNodes = [];
+ for (var i = 0; i < nodes.length; i++)
+ {
+ var $node = $R.dom(nodes[i]);
+ var parent = $node.parent().get();
+ var isFirst = ($node.parent().hasClass('redactor-in'));
+ var isCellParent = (parent && (parent.tagName === 'TD' || parent.tagName === 'TH'));
+ if (isFirst || isCellParent)
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ }
+
+ return filteredNodes;
+ },
+ _filterInlinesInside: function(nodes)
+ {
+ var filteredNodes = [];
+ for (var i = 0; i < nodes.length; i++)
+ {
+ if (window.getSelection().containsNode(nodes[i], true))
+ {
+ filteredNodes.push(nodes[i]);
+ }
+ }
+
+ return filteredNodes;
+ },
+ _isTextSelected: function(node, selected)
+ {
+ var text = this.utils.removeInvisibleChars(node.textContent);
+
+ return (
+ selected === text
+ || text.search(selected) !== -1
+ || selected.search(new RegExp('^' + text)) !== -1
+ || selected.search(new RegExp(text + '$')) !== -1
+ );
+ },
+ _isInlineNode: function(node)
+ {
+ var data = this.inspector.parse(node);
+
+ return (this.inspector.isInlineTag(node.tagName) && data.isInEditor());
+ },
+ _clearSaved: function()
+ {
+ this.saved = false;
+ this.savedComponent = false;
+ this.savedElement = false;
+ }
+});
+$R.add('service', 'element', {
+ init: function(app)
+ {
+ this.app = app;
+ this.rootElement = app.rootElement;
+
+ // local
+ this.$element = {};
+ this.type = 'inline';
+ },
+ start: function()
+ {
+ this._build();
+ this._buildType();
+ },
+
+ // public
+ isType: function(type)
+ {
+ return (type === this.type);
+ },
+ getType: function()
+ {
+ return this.type;
+ },
+ getElement: function()
+ {
+ return this.$element;
+ },
+
+ // private
+ _build: function()
+ {
+ this.$element = $R.dom(this.rootElement);
+ },
+ _buildType: function()
+ {
+ var tag = this.$element.get().tagName;
+
+ this.type = (tag === 'TEXTAREA') ? 'textarea' : this.type;
+ this.type = (tag === 'DIV') ? 'div' : this.type;
+ this.type = (this.opts.inline) ? 'inline' : this.type;
+ }
+});
+$R.add('service', 'editor', {
+ init: function(app)
+ {
+ this.app = app;
+
+ // local
+ this.scrolltop = false;
+ this.pasting = false;
+ },
+
+ // start
+ start: function()
+ {
+ this._build();
+ },
+
+ // focus
+ focus: function()
+ {
+ if (!this.isFocus() && !this._isContenteditableFocus())
+ {
+ this.saveScroll();
+ this.$editor.focus();
+ this.restoreScroll();
+ }
+ },
+ startFocus: function()
+ {
+ this.caret.setStart(this.getFirstNode());
+ },
+ endFocus: function()
+ {
+ this.caret.setEnd(this.getLastNode());
+ },
+
+ // pasting
+ isPasting: function()
+ {
+ return this.pasting;
+ },
+ enablePasting: function()
+ {
+ this.pasting = true;
+ },
+ disablePasting: function()
+ {
+ this.pasting = false;
+ },
+
+ // scroll
+ saveScroll: function()
+ {
+ this.scrolltop = this._getScrollTarget().scrollTop();
+ },
+ restoreScroll: function()
+ {
+ if (this.scrolltop !== false)
+ {
+ this._getScrollTarget().scrollTop(this.scrolltop);
+ this.scrolltop = false;
+ }
+ },
+
+ // non editables
+ disableNonEditables: function()
+ {
+ this.$noneditables = this.$editor.find('[contenteditable=false]');
+ this.$noneditables.attr('contenteditable', true);
+ },
+ enableNonEditables: function()
+ {
+ if (this.$noneditables)
+ {
+ setTimeout(function() { this.$noneditables.attr('contenteditable', false); }.bind(this), 1);
+ }
+ },
+
+ // nodes
+ getFirstNode: function()
+ {
+ return this.$editor.contents()[0];
+ },
+ getLastNode: function()
+ {
+ var nodes = this.$editor.contents();
+
+ return nodes[nodes.length-1];
+ },
+
+ // utils
+ isSourceMode: function()
+ {
+ var $source = this.source.getElement();
+
+ return $source.hasClass('redactor-source-open');
+ },
+ isEditor: function(el)
+ {
+ var node = $R.dom(el).get();
+
+ return (node === this.$editor.get());
+ },
+ isEmpty: function(keeplists)
+ {
+ return this.utils.isEmptyHtml(this.$editor.html(), false, keeplists);
+ },
+ isFocus: function()
+ {
+ var $active = $R.dom(document.activeElement);
+ var isComponentSelected = (this.$editor.find('.redactor-component-active').length !== 0);
+
+ return (isComponentSelected || $active.closest('.redactor-in-' + this.uuid).length !== 0);
+ },
+ setEmpty: function()
+ {
+ this.$editor.html(this.opts.emptyHtml);
+ },
+
+ // element
+ getElement: function()
+ {
+ return this.$editor;
+ },
+
+ // private
+ _build: function()
+ {
+ var $element = this.element.getElement();
+ var editableElement = (this.element.isType('textarea')) ? '