diff --git a/fonts/sd_icons.eot b/fonts/sd_icons.eot index e0fa573809..4eb6f19db2 100755 Binary files a/fonts/sd_icons.eot and b/fonts/sd_icons.eot differ diff --git a/fonts/sd_icons.svg b/fonts/sd_icons.svg index 143e00c356..266c4d6751 100755 --- a/fonts/sd_icons.svg +++ b/fonts/sd_icons.svg @@ -10,9 +10,9 @@ - + - + @@ -47,9 +47,9 @@ - + - + @@ -58,19 +58,19 @@ - + - - + + - + @@ -79,7 +79,7 @@ - + @@ -90,26 +90,26 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - + @@ -126,4 +126,19 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/sd_icons.ttf b/fonts/sd_icons.ttf index ede7e3c1c0..c5f33407ac 100755 Binary files a/fonts/sd_icons.ttf and b/fonts/sd_icons.ttf differ diff --git a/fonts/sd_icons.woff b/fonts/sd_icons.woff index 118bae4b7d..d8448f0c18 100755 Binary files a/fonts/sd_icons.woff and b/fonts/sd_icons.woff differ diff --git a/scripts/apps/authoring/authoring/directives/ArticleEditDirective.js b/scripts/apps/authoring/authoring/directives/ArticleEditDirective.js index f207463db0..1811df74b0 100644 --- a/scripts/apps/authoring/authoring/directives/ArticleEditDirective.js +++ b/scripts/apps/authoring/authoring/directives/ArticleEditDirective.js @@ -62,6 +62,7 @@ export function ArticleEditDirective( scope.editSignOff = false; scope.mediaLoading = false; scope.validator = config.validatorMediaMetadata; + scope.features = config.features; var mainEditScope = scope.$parent.$parent; var autopopulateByline = config.features && config.features.autopopulateByline; diff --git a/scripts/apps/authoring/authoring/directives/SendItem.js b/scripts/apps/authoring/authoring/directives/SendItem.js index 21c90a2094..1339ef2c0b 100644 --- a/scripts/apps/authoring/authoring/directives/SendItem.js +++ b/scripts/apps/authoring/authoring/directives/SendItem.js @@ -2,11 +2,11 @@ import _ from 'lodash'; SendItem.$inject = ['$q', 'api', 'desks', 'notify', 'authoringWorkspace', 'superdeskFlags', '$location', 'macros', '$rootScope', - 'authoring', 'send', 'editor', 'confirm', 'archiveService', + 'authoring', 'send', 'editorResolver', 'confirm', 'archiveService', 'preferencesService', 'multi', 'datetimeHelper', 'config', 'privileges', 'storage']; export function SendItem($q, api, desks, notify, authoringWorkspace, superdeskFlags, $location, macros, $rootScope, - authoring, send, editor, confirm, archiveService, + authoring, send, editorResolver, confirm, archiveService, preferencesService, multi, datetimeHelper, config, privileges, storage) { return { scope: { @@ -26,6 +26,8 @@ export function SendItem($q, api, desks, notify, authoringWorkspace, controllerAs: 'vm', templateUrl: 'scripts/apps/authoring/views/send-item.html', link: function sendItemLink(scope, elem, attrs, ctrl) { + const editor = editorResolver.get(); + scope.mode = scope.mode || 'authoring'; scope.desks = null; scope.stages = null; diff --git a/scripts/apps/authoring/editor/find-replace.js b/scripts/apps/authoring/editor/find-replace.js index 97b27fc219..0bd327ced5 100644 --- a/scripts/apps/authoring/editor/find-replace.js +++ b/scripts/apps/authoring/editor/find-replace.js @@ -7,16 +7,14 @@ * AUTHORS and LICENSE files distributed with this source code, or * at https://www.sourcefabric.org/apps/license */ -FindReplaceDirective.$inject = ['editor', 'editor3', 'macros', 'authoring']; +FindReplaceDirective.$inject = ['editorResolver', 'macros']; /** * using directive here so that it can return focus */ -function FindReplaceDirective(editor2, editor3, macros, authoring) { +function FindReplaceDirective(editorResolver, macros) { return { link: function(scope, elem) { - // use the editor service of editor3, if it's active - const isEditor3 = authoring.editor.body_html.editor3; - const editor = isEditor3 ? editor3 : editor2; + const editor = editorResolver.get(); scope.to = ''; scope.from = ''; diff --git a/scripts/apps/authoring/macros/macros.js b/scripts/apps/authoring/macros/macros.js index ace385cd9b..0cbb7e3ec0 100644 --- a/scripts/apps/authoring/macros/macros.js +++ b/scripts/apps/authoring/macros/macros.js @@ -234,12 +234,14 @@ function MacrosController($scope, macros, desks, autosave, $rootScope, storage) * apply the results of triggered macro with the use of available set of methods such that next, * prev and replace */ -MacrosReplaceDirective.$inject = ['editor']; -function MacrosReplaceDirective(editor) { +MacrosReplaceDirective.$inject = ['editorResolver']; +function MacrosReplaceDirective(editorResolver) { return { scope: true, templateUrl: 'scripts/apps/authoring/macros/views/macros-replace.html', link: function(scope) { + const editor = editorResolver.get(); + scope.diff = null; scope.$on('macro:diff', (evt, diff) => { diff --git a/scripts/apps/authoring/tests/authoring.spec.js b/scripts/apps/authoring/tests/authoring.spec.js index e8579be658..cc69c5cfdd 100644 --- a/scripts/apps/authoring/tests/authoring.spec.js +++ b/scripts/apps/authoring/tests/authoring.spec.js @@ -2274,9 +2274,15 @@ describe('authoring themes', () => { describe('send item directive', () => { beforeEach(window.module(($provide) => { - $provide.constant('config', {server: {url: undefined}, iframely: {key: '123'}, editor: {}}); + $provide.constant('config', { + server: {url: undefined}, + iframely: {key: '123'}, + editor: {}, + features: {onlyEditor3: false} + }); })); + beforeEach(window.module('superdesk.core.editor3')); beforeEach(window.module('superdesk.apps.editor2')); beforeEach(window.module('superdesk.core.preferences')); beforeEach(window.module('superdesk.apps.authoring')); diff --git a/scripts/apps/authoring/views/article-edit.html b/scripts/apps/authoring/views/article-edit.html index 9aff3d820f..eb5b212677 100644 --- a/scripts/apps/authoring/views/article-edit.html +++ b/scripts/apps/authoring/views/article-edit.html @@ -1,4 +1,4 @@ -
+
{{item.headline}}
-
+
-
+
-
+
-
+
@@ -198,12 +199,13 @@
-
+
-
{{item.description_text}}
-
+
{{ :: 'Editing' | translate }} "{{ editing.form.label }}" + +
diff --git a/scripts/apps/workspace/content/views/schema-editor.html b/scripts/apps/workspace/content/views/schema-editor.html index 17400b80be..5ec0ef4e5f 100644 --- a/scripts/apps/workspace/content/views/schema-editor.html +++ b/scripts/apps/workspace/content/views/schema-editor.html @@ -17,10 +17,6 @@

Schema Configuration

-
- -
-
diff --git a/scripts/core/editor3/components/Editor3.jsx b/scripts/core/editor3/components/Editor3.jsx index 2edef56713..1c4f72bff7 100644 --- a/scripts/core/editor3/components/Editor3.jsx +++ b/scripts/core/editor3/components/Editor3.jsx @@ -69,7 +69,9 @@ export class Editor3Component extends React.Component { return; } - const toolbarStyle = editorRect.top < pageRect.top + 50 ? 'fixed' : 'relative'; + const isToolbarOut = editorRect.top < pageRect.top + 50; + const isBottomOut = editorRect.bottom < pageRect.top + 60; + const toolbarStyle = isToolbarOut && !isBottomOut ? 'fixed' : 'relative'; if (toolbarStyle !== this.state.toolbarStyle) { this.setState({toolbarStyle}); @@ -99,7 +101,12 @@ export class Editor3Component extends React.Component { * @description Handles key commands in the editor. */ handleKeyCommand(command) { - const {editorState, onChange} = this.props; + const {editorState, onChange, singleLine} = this.props; + + if (singleLine && command === 'split-block') { + return 'handled'; + } + const newState = RichUtils.handleKeyCommand(editorState, command); if (newState) { @@ -142,6 +149,7 @@ export class Editor3Component extends React.Component { let cx = classNames({ 'Editor3-root Editor3-editor': true, 'floating-toolbar': toolbarStyle === 'fixed', + 'no-toolbar': !showToolbar, 'read-only': readOnly }); @@ -174,7 +182,8 @@ Editor3Component.propTypes = { unsetReadOnly: React.PropTypes.func, onTab: React.PropTypes.func, dragDrop: React.PropTypes.func, - scrollContainer: React.PropTypes.object + scrollContainer: React.PropTypes.string, + singleLine: React.PropTypes.bool }; const mapStateToProps = (state) => ({ diff --git a/scripts/core/editor3/components/embeds/EmbedButton.jsx b/scripts/core/editor3/components/embeds/EmbedButton.jsx index c72b80454a..6574116993 100644 --- a/scripts/core/editor3/components/embeds/EmbedButton.jsx +++ b/scripts/core/editor3/components/embeds/EmbedButton.jsx @@ -45,7 +45,7 @@ export class EmbedButton extends Component { return (
- embed + {dialogOpen ? : null}
); diff --git a/scripts/core/editor3/components/images/ImageButton.jsx b/scripts/core/editor3/components/images/ImageButton.jsx index f2f24b565b..c2cadea9ca 100644 --- a/scripts/core/editor3/components/images/ImageButton.jsx +++ b/scripts/core/editor3/components/images/ImageButton.jsx @@ -11,7 +11,7 @@ import * as actions from '../../actions'; */ const ImageButtonComponent = ({insertImages}) =>
- img +
; ImageButtonComponent.propTypes = { diff --git a/scripts/core/editor3/components/links/LinkButton.jsx b/scripts/core/editor3/components/links/LinkButton.jsx index f45eb51b04..eb7b05cde2 100644 --- a/scripts/core/editor3/components/links/LinkButton.jsx +++ b/scripts/core/editor3/components/links/LinkButton.jsx @@ -79,7 +79,9 @@ export class LinkButtonComponent extends Component { return (
- link + + + {entityType === 'LINK' ? - tbl +
); } diff --git a/scripts/core/editor3/components/tests/editor3.spec.jsx b/scripts/core/editor3/components/tests/editor3.spec.jsx index ba53db4b6d..126a95c41d 100644 --- a/scripts/core/editor3/components/tests/editor3.spec.jsx +++ b/scripts/core/editor3/components/tests/editor3.spec.jsx @@ -9,14 +9,7 @@ describe('editor3.component', () => { const wrapper = shallow(); expect(wrapper.find('DraftEditor').length).toBe(1); - expect(wrapper.find('Toolbar').length).toBe(0); - }); - - it('should show toolbar when enabled', () => { - const wrapper = shallow(); - - expect(wrapper.find('DraftEditor').length).toBe(1); - expect(wrapper.find('Toolbar').length).toBe(1); + expect(wrapper.find('.Editor3-controls').length).toBe(0); }); it('should mount and put client rect inside attribute on update', () => { diff --git a/scripts/core/editor3/components/tests/links.spec.jsx b/scripts/core/editor3/components/tests/links.spec.jsx index c0b656d3bb..4f69d981be 100644 --- a/scripts/core/editor3/components/tests/links.spec.jsx +++ b/scripts/core/editor3/components/tests/links.spec.jsx @@ -27,9 +27,7 @@ function getWrapper(es = null, shallowMount = false) { describe('editor3.components.link-button', () => { it('should render button text', () => { const {wrapper} = getShallowWrapper(); - const button = wrapper.find('span').first(); - expect(button.text()).toBe('link'); expect(wrapper.find('LinkPopover').length).toBe(0); }); diff --git a/scripts/core/editor3/components/tests/styles.spec.jsx b/scripts/core/editor3/components/tests/styles.spec.jsx index 674b13eedd..d25e2cbd9c 100644 --- a/scripts/core/editor3/components/tests/styles.spec.jsx +++ b/scripts/core/editor3/components/tests/styles.spec.jsx @@ -7,10 +7,10 @@ import {InlineStyleControlsComponent as InlineStyleControls} from '../toolbar/In describe('editor3.components.toolbar', () => { it('(StyleButton) should render label', () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.hasClass('Editor3-styleButton')).toBe(true); - expect(wrapper.text()).toBe('button_label'); + expect(wrapper.find('i.icon-heading-1').length).toBe(1); }); it('(StyleButton) should become active when prop is set to true', () => { diff --git a/scripts/core/editor3/components/toolbar/StyleButton.jsx b/scripts/core/editor3/components/toolbar/StyleButton.jsx index c782100049..4dc968cba1 100644 --- a/scripts/core/editor3/components/toolbar/StyleButton.jsx +++ b/scripts/core/editor3/components/toolbar/StyleButton.jsx @@ -1,4 +1,21 @@ import React from 'react'; +import classNames from 'classnames'; + +const StyleIcons = { + bold: 'icon-bold', + italic: 'icon-italic', + underline: 'icon-underline', + strikethrough: 'icon-strikethrough', + h1: 'icon-heading-1', + h2: 'icon-heading-2', + h3: 'icon-heading-3', + h4: 'icon-heading-4', + h5: 'icon-heading-5', + h6: 'icon-heading-6', + quote: 'icon-quote', + ul: 'icon-unordered-list', + ol: 'icon-ordered-list' +}; /** * @ngdoc React @@ -18,15 +35,16 @@ export default class StyleButton extends React.Component { } render() { - let className = 'Editor3-styleButton'; + const {active, label} = this.props; - if (this.props.active) { - className += ' Editor3-activeButton'; - } + const cx = classNames({ + 'Editor3-styleButton': true, + 'Editor3-activeButton': active + }); return ( - - {this.props.label} + + ); } diff --git a/scripts/core/editor3/components/toolbar/index.js b/scripts/core/editor3/components/toolbar/index.js index 55f1ae71e1..48c3080c1f 100644 --- a/scripts/core/editor3/components/toolbar/index.js +++ b/scripts/core/editor3/components/toolbar/index.js @@ -5,6 +5,7 @@ import {LinkButton} from '../links'; import {ImageButton} from '../images'; import {EmbedButton} from '../embeds'; import {TableButton} from '../tables'; +import {connect} from 'react-redux'; import classNames from 'classnames'; /** @@ -15,9 +16,10 @@ import classNames from 'classnames'; * @param {boolean} disabled Disables clicking on the toolbar, if true. * @description Holds the editor's toolbar. */ -export default class Toolbar extends Component { +class ToolbarComponent extends Component { render() { - const {editorRect, disabled} = this.props; + const {editorRect, disabled, editorFormat} = this.props; + const has = (opt) => editorFormat.indexOf(opt) > -1; const cx = classNames({ 'Editor3-controls': true, disabled: disabled @@ -27,16 +29,23 @@ export default class Toolbar extends Component {
- - - - + {has('anchor') ? : null} + {has('picture') ? : null} + {has('embed') ? : null} + {has('table') ? : null}
); } } -Toolbar.propTypes = { +ToolbarComponent.propTypes = { editorRect: React.PropTypes.object.isRequired, - disabled: React.PropTypes.bool + disabled: React.PropTypes.bool, + editorFormat: React.PropTypes.array }; + +const mapStateToProps = (state) => ({editorFormat: state.editorFormat}); + +const Toolbar = connect(mapStateToProps, null)(ToolbarComponent); + +export default Toolbar; diff --git a/scripts/core/editor3/directive.js b/scripts/core/editor3/directive.js index d9fb250b28..8352df883b 100644 --- a/scripts/core/editor3/directive.js +++ b/scripts/core/editor3/directive.js @@ -24,25 +24,88 @@ class Editor3Directive { this.controller = ['$element', 'editor3', '$scope', this.initialize]; this.bindToController = { + /** + * @type {String} + * @description If set, it will be used to make sure the toolbar is always + * visible when scrolling. If not set, window object is used as reference. + * Any valid jQuery selector will do. + */ scrollContainer: '@', - config: '=', - editorFormat: '=', - language: '=', - onChange: '&', + + /** + * @type {Boolean} + * @description Whether this editor is the target for find & replace + * operations. The Find & Replace service can only have one editor as + * target. + */ + findReplaceTarget: '@', + + /** + * @type {Object} + * @description Editor format options that are enabled and should be displayed + * in the toolbar. + */ + editorFormat: '=?', + + /** + * @type {Object} + * @description A JSON object representing the Content State of the Draft + * editor. When available, it is used to show content, using `convertFromRaw`. + * Either this, or value have to be set. Use this for most accurate behavior. + */ + editorState: '=?', + + /** + * @type {String} + * @description HTML value of editor. Used by the outside world. + */ value: '=', - editorState: '=', - readOnly: '=' + + /** + * @type {Boolean} + * @description If true, editor is read-only. + */ + readOnly: '=?', + + /** + * @type {Function} + * @description Function that gets called on every content change. + */ + onChange: '&', + + /** + * @type {String} + * @description Spellchecker's language. + */ + language: '=?', + + /** + * @type {Boolean} + * @description Disables the Enter key if the attribute is set. + */ + singleLine: '@' }; } initialize($element, editor3, $scope) { + // defaults + this.language = this.language || 'en'; + this.readOnly = this.readOnly || false; + this.findReplaceTarget = typeof this.findReplaceTarget !== 'undefined'; + this.singleLine = typeof this.singleLine !== 'undefined'; + const store = createStore(this); - editor3.setStore(store); + if (this.findReplaceTarget) { + editor3.setStore(store); + $scope.$on('$destroy', editor3.unsetStore); + } ReactDOM.render( - + , $element.get(0) ); } diff --git a/scripts/core/editor3/index.js b/scripts/core/editor3/index.js index 2c01b1711e..65620434c6 100644 --- a/scripts/core/editor3/index.js +++ b/scripts/core/editor3/index.js @@ -2,6 +2,7 @@ import './styles.scss'; import {EditorService} from './service'; import {sdEditor3} from './directive'; +import ng from 'core/services/ng'; /** * @ngdoc module @@ -12,4 +13,14 @@ import {sdEditor3} from './directive'; */ export default angular.module('superdesk.core.editor3', ['superdesk.apps.spellcheck']) .service('editor3', EditorService) + .service('editorResolver', ['editor', 'editor3', 'config', function(editor2, editor3, config) { + // Enables the use of editor2 and editor3 in parallel. + // Resolves to old editor in case editor3 is inactive. + this.get = function() { + const authoring = ng.get('authoring'); + const editor3Active = authoring.editor && authoring.editor.body_html && authoring.editor.body_html.editor3; + + return config.features.onlyEditor3 || editor3Active ? editor3 : editor2; + }; + }]) .directive('sdEditor3', sdEditor3); diff --git a/scripts/core/editor3/reducers/find-replace.jsx b/scripts/core/editor3/reducers/find-replace.jsx index 59dc887949..72cb944686 100644 --- a/scripts/core/editor3/reducers/find-replace.jsx +++ b/scripts/core/editor3/reducers/find-replace.jsx @@ -157,7 +157,7 @@ export default findReplace; * @param {Object} state * @description Returns the number of occurences of the search criteria inside the current editor content. */ -const countOccurrences = (state) => { +export const countOccurrences = (state) => { const content = state.editorState.getCurrentContent(); const {pattern, caseSensitive} = state.searchTerm; const re = new RegExp(pattern, 'g' + (caseSensitive ? '' : 'i')); @@ -233,7 +233,7 @@ const createSelection = (key, start, end) => * @description Searches the content for the given pattern and calls the given callback * for each occurrence, passing it the index of the match and its SelectionState. */ -const forEachMatch = (content, pattern, caseSensitive, cb) => { +export const forEachMatch = (content, pattern, caseSensitive, cb) => { if (!pattern) { return false; } diff --git a/scripts/core/editor3/service.js b/scripts/core/editor3/service.js index 1086291438..e59c171853 100644 --- a/scripts/core/editor3/service.js +++ b/scripts/core/editor3/service.js @@ -1,4 +1,6 @@ import * as action from './actions/find-replace'; +import ng from 'core/services/ng'; +import {countOccurrences, forEachMatch} from './reducers/find-replace'; /** * @type {Object} Redux store @@ -23,9 +25,22 @@ export class EditorService { * @description Registers the passed redux store with the service. */ setStore(s) { + if (store !== null) { + console.warn('You\'ve overwritten the find & replace target.'); + } + store = s; } + /** + * @ngdoc method + * @name editor3#unsetStore + * @description Clears the store. + */ + unsetStore() { + store = null; + } + /** * @ngdoc method * @name editor3#selectNext @@ -33,7 +48,7 @@ export class EditorService { * criteria in the editor. */ selectNext() { - store.dispatch(action.findNext()); + ok() && store.dispatch(action.findNext()); } /** @@ -43,7 +58,7 @@ export class EditorService { * criteria in the editor. */ selectPrev() { - store.dispatch(action.findPrev()); + ok() && store.dispatch(action.findPrev()); } /** @@ -53,7 +68,7 @@ export class EditorService { * @description Replaces the currently highlighted search criteria with the given text. */ replace(txt) { - store.dispatch(action.replace(txt)); + ok() && store.dispatch(action.replace(txt)); } /** @@ -63,7 +78,7 @@ export class EditorService { * @description Replaces all the search criteria with the given text. */ replaceAll(txt) { - store.dispatch(action.replaceAll(txt)); + ok() && store.dispatch(action.replaceAll(txt)); } /** @@ -74,6 +89,10 @@ export class EditorService { * @description Updates the search criteria. */ setSettings({findreplace}) { + if (!ok()) { + return; + } + if (findreplace === null) { store.dispatch(action.setHighlightCriteria({pattern: ''})); @@ -92,6 +111,54 @@ export class EditorService { * @description Highlights the current search criteria in the editor. */ render() { - store.dispatch(action.renderHighlights()); + ok() && store.dispatch(action.renderHighlights()); + } + + /** + * @ngdoc method + * @name editor3#countErrors + * @description Not sure what this method is supposed to do. It's needed by + * the interface and it's copied from `core/editor2/editor.js#93`. + */ + countErrors() { + return ng.get('$q').when(countOccurrences(store.getState())); } + + /** + * @ngdoc method + * @name editor3#getActiveText + * @description Gets the text under the current selection. + */ + getActiveText() { + if (!ok()) { + return; + } + + const state = store.getState(); + const {editorState, searchTerm} = state; + const {index, pattern, caseSensitive} = searchTerm; + const content = editorState.getCurrentContent(); + + let txt = pattern; + + // find the active match + forEachMatch(content, pattern, caseSensitive, (i, selection, block) => { + if (i === index) { + const start = selection.getStartOffset(); + const end = selection.getEndOffset(); + + txt = block.getText().slice(start, end); + } + }); + + return txt; + } +} + +function ok() { + if (store === null) { + console.error('No editor set as target in service.'); + } + + return store !== null; } diff --git a/scripts/core/editor3/styles.scss b/scripts/core/editor3/styles.scss index 5288bb34ea..2231e34ee3 100644 --- a/scripts/core/editor3/styles.scss +++ b/scripts/core/editor3/styles.scss @@ -8,6 +8,10 @@ padding: 40px 15px 15px; position: relative; + &.no-toolbar { + padding-top: 5px; + } + &.floating-toolbar .Editor3-controls { position: fixed; top: 132px; @@ -158,6 +162,7 @@ left: 0; padding: 15px; background-color: #fff; + line-height: 100% !important; &.disabled { * { @@ -182,15 +187,15 @@ } input { - height: 33px; - padding: 8px 47px 8px 8px; + height: 53px; + padding: 8px 47px 8px 15px; } } .input-controls { position: absolute; - top: 0; - right: 0; + top: 10px; + right: 5px; margin: 8px; i { @@ -216,17 +221,13 @@ top: 0; input[type="url"] { - height: 33px; - padding: 8px 47px 8px 8px; + height: 53px; + padding: 8px 47px 8px 15px; } } } .Editor3-styleButton { - .inactive { - color: #ccc; - } - .link-button + .link-editor { a { margin-right: 5px; @@ -250,8 +251,54 @@ margin-right: 16px; padding: 2px 0; display: inline-block; + + font-size: 13px; + font-style: normal; + + span { + font-size: 13px; + font-style: normal; + } + + [class*="icon-"] { + color: #999; + + &:hover { + color: #555; + } + } + + .inactive [class*="icon-"] { + color: #ddd; + + &:hover { + color: #ddd; + } + } + + &.Editor3-activeButton [class*="icon-"] { + color: #5890ff; + } } -.Editor3-activeButton { - color: #5890ff; +/** Editor2 CSS Fix for headline **/ +.main-article .headline div.Editor3-root div { + font-size: 14px !important; + line-height: 100% !important; + + .DraftEditor-editorContainer div { + font-size: 28px !important; + line-height: 120% !important; + } +} + +/** Editor2 CSS Fix for abstract **/ +.main-article .abstract div.Editor3-root div { + font-size: 14px !important; + line-height: 100% !important; + + .DraftEditor-editorContainer div { + font-size: 16px !important; + line-height: 150% !important; + } } diff --git a/scripts/core/editor3/tests/editor3core.spec.jsx b/scripts/core/editor3/tests/editor3core.spec.jsx index 78680314ac..93632fb08b 100644 --- a/scripts/core/editor3/tests/editor3core.spec.jsx +++ b/scripts/core/editor3/tests/editor3core.spec.jsx @@ -8,7 +8,9 @@ describe('editor3.service', () => { 'replace', 'replaceAll', 'setSettings', - 'render' + 'render', + 'getActiveText', + 'countErrors' ].forEach((fn) => { expect(typeof editor3[fn]).toBe('function'); }); diff --git a/styles/sass/sd-icon-font.scss b/styles/sass/sd-icon-font.scss index 3412add26f..71affff7cd 100644 --- a/styles/sass/sd-icon-font.scss +++ b/styles/sass/sd-icon-font.scss @@ -344,10 +344,10 @@ .icon-italic:before { content: "\e656"; } -.icon-text-height:before { +.icon-underline:before { content: "\e657"; } -.icon-text-width:before { +.icon-striketrough:before { content: "\e658"; } .icon-align-left:before { @@ -440,3 +440,50 @@ .icon-paste:before { content: "\e676"; } +.icon-arrow-left:before { + content: "\e677"; +} +.icon-arrow-right:before { + content: "\e678"; +} +.icon-info-large:before { + content: "\e679"; +} +.icon-help-large:before { + content: "\e67a"; +} +.icon-attachment:before { + content: "\e67b"; +} +.icon-attachment-large:before { + content: "\e67c"; +} +.icon-table:before { + content: "\e67d"; +} +.icon-ordered-list:before { + content: "\e67e"; +} +.icon-heading-1:before { + content: "\e67f"; +} +.icon-heading-2:before { + content: "\e680"; +} +.icon-heading-3:before { + content: "\e681"; +} +.icon-heading-4:before { + content: "\e682"; +} +.icon-heading-5:before { + content: "\e683"; +} +.icon-heading-6:before { + content: "\e684"; +} +.icon-quote:before { + content: "\e685"; +} + + diff --git a/webpack.config.js b/webpack.config.js index ffb0a5a6b4..0bc5595961 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -216,7 +216,10 @@ function getDefaults(grunt) { // app features features: { // tansa spellchecker - useTansaProofing: false + useTansaProofing: false, + + // replace editor2 + onlyEditor3: false }, // workspace defaults