Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced the editor quick actions toolbar #130

Merged
merged 2 commits into from
Nov 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.0.2",
"karma-firefox-launcher": "^1.3.0",
"karma-coveralls": "^2.1.0",
"karma-firefox-launcher": "^1.3.0",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-sinon": "^1.0.5",
Expand All @@ -84,6 +84,7 @@
"react-dom": "^16.8.1",
"react-redux": "^7.2.0",
"react-rnd": "^10.0.0",
"react-svg-loader": "^3.0.3",
"redux": "^4.0.5",
"sinon": "^7.2.3",
"style-loader": "^1.2.1",
Expand Down
1 change: 1 addition & 0 deletions src/assets/img/arrow-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/img/console.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/img/eye.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/img/play.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/img/read-only.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/img/source.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/img/trash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion src/ckeditorinspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { createStore } from 'redux';
import { Provider } from 'react-redux';

import { reducer } from './data/reducer';
import { setEditors } from './data/actions';
import {
setEditors,
updateCurrentEditorIsReadOnly
} from './data/actions';
import { updateModelState } from './model/data/actions';
import { updateViewState } from './view/data/actions';
import { updateCommandsState } from './commands/data/actions';
Expand Down Expand Up @@ -214,6 +217,9 @@ export default class CKEditorInspector {
}

store.dispatch( updateViewState() );
},
onReadOnlyChange() {
CKEditorInspector._store.dispatch( updateCurrentEditorIsReadOnly() );
}
} );

Expand All @@ -222,6 +228,7 @@ export default class CKEditorInspector {
CKEditorInspector._store = createStore( reducer, {
editors: CKEditorInspector._editors,
currentEditorName: getFirstEditorName( CKEditorInspector._editors ),
currentEditorGlobals: {},
ui: {
isCollapsed: options.isCollapsed
}
Expand Down
7 changes: 5 additions & 2 deletions src/commands/commandinspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import ObjectInspector from '../components/objectinspector';

import Logger from '../logger';

import ConsoleIcon from '../assets/img/console.svg';
import PlayIcon from '../assets/img/play.svg';

class CommandInspector extends Component {
constructor( props ) {
super( props );
Expand Down Expand Up @@ -47,13 +50,13 @@ class CommandInspector extends Component {
</span>,
<Button
key="exec"
type="exec"
icon={<PlayIcon />}
text="Execute command"
onClick={this.handleCommandExecuteButtonClick}
/>,
<Button
key="log"
type="log"
icon={<ConsoleIcon />}
text="Log in console"
onClick={this.handleCommandLogButtonClick}
/>
Expand Down
46 changes: 30 additions & 16 deletions src/components/button.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,47 @@
* For licensing, see LICENSE.md.
*/

.ck-inspector {
--ck-inspector-icon-size: 19px;
--ck-inspector-button-size: calc( 4px + var(--ck-inspector-icon-size) );
--ck-inspector-color-button: #777;
--ck-inspector-color-button-hover: #222;
--ck-inspector-color-button-on: #0F79E2;
}

.ck-inspector .ck-inspector-button {
width: 16px;
height: 16px;
width: var(--ck-inspector-button-size);
height: var(--ck-inspector-button-size);
border: 0;
text-indent: 100px;
overflow: hidden;
opacity: .8;
margin-left: .7em;
flex: 0 0 auto;
border-radius: 2px;
padding: 2px;
color: var(--ck-inspector-color-button);

&:first-of-type {
margin-left: auto;
&.ck-inspector-button_on,
&.ck-inspector-button_on:hover {
color: var(--ck-inspector-color-button-on);
opacity: 1;
}

&:hover {
opacity: 1;
&.ck-inspector-button_disabled {
opacity: .3;
}

&.ck-inspector-button_log {
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZT0iIzZFNkU2RSIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxwYXRoIGQ9Ik0xLjUgNC4xNjVsNS43IDQuMTItNS43IDMuMTUzTTkuNDQ5IDExLjVoNS42NTUiLz48L2c+PC9zdmc+);
& > span {
display: none;
}

&.ck-inspector-button_exec {
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48Y2lyY2xlIHN0cm9rZT0iIzZFNkU2RSIgc3Ryb2tlLXdpZHRoPSIxLjUiIGN4PSI4IiBjeT0iOCIgcj0iNy4yNSIvPjxwYXRoIGZpbGw9IiM2RTZFNkUiIGQ9Ik02LjA5NCA1LjIzNUwxMS4wNzQgOGwtNC45OCAzLjAxOHoiLz48L2c+PC9zdmc+);
&:hover {
color: var(--ck-inspector-color-button-hover);
}

&.ck-inspector-button_scroll {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxNiAxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHRpdGxlPnNlZTwvdGl0bGU+CjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CjxwYXRoIGQ9Im04IDMuNWMtMS44ODM4IDAtMy42MDY5IDAuNjEzNDItNC45MzM5IDEuNDQyOC0xLjUwNTcgMC45NDEwNC0yLjU2NjEgMi4xNjMzLTIuNTY2MSAzLjA1NzJzMS4wNjA0IDIuMTE2MiAyLjU2NjEgMy4wNTcyYzEuMzI3IDAuODI5MzggMy4wNTAxIDEuNDQyOCA0LjkzMzkgMS40NDI4czMuNjA2OS0wLjYxMzQyIDQuOTMzOS0xLjQ0MjhjMS41MDU3LTAuOTQxMDQgMi41NjYxLTIuMTYzMyAyLjU2NjEtMy4wNTcycy0xLjA2MDQtMi4xMTYyLTIuNTY2MS0zLjA1NzJjLTEuMzI3LTAuODI5MzgtMy4wNTAxLTEuNDQyOC00LjkzMzktMS40NDI4eiIgc3Ryb2tlPSIjNkU2RTZFIi8+CjxwYXRoIGQ9Im04IDRjMi4yMDkxIDAgNCAxLjc5MDkgNCA0cy0xLjc5MDkgNC00IDQtNC0xLjc5MDktNC00IDEuNzkwOS00IDQtNHptLTEuNSAxYy0wLjgyODQzIDAtMS41IDAuNjcxNTctMS41IDEuNXMwLjY3MTU3IDEuNSAxLjUgMS41IDEuNS0wLjY3MTU3IDEuNS0xLjUtMC42NzE1Ny0xLjUtMS41LTEuNXoiIGZpbGw9IiM2RTZFNkUiLz4KPC9nPgo8L3N2Zz4K);
& svg {
width: var(--ck-inspector-icon-size);
height: var(--ck-inspector-icon-size);

&, & * {
fill: currentColor;
}
}
}
17 changes: 13 additions & 4 deletions src/components/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@
*/

import React, { PureComponent } from 'react';

import './button.css';

export default class Button extends PureComponent {
render() {
const classes = [
'ck-inspector-button',
this.props.className || '',
this.props.isOn ? 'ck-inspector-button_on' : '',
this.props.isEnabled === false ? 'ck-inspector-button_disabled' : ''
].filter( className => className ).join( ' ' );

return <button
className={`ck-inspector-button ck-inspector-button_${ this.props.type }`}
className={classes}
type="button"
onClick={this.props.onClick}
title={this.props.text}
onClick={this.props.isEnabled === false ? () => {} : this.props.onClick}
title={this.props.title || this.props.text}
>
{this.props.text}
<span>{this.props.text}</span>
{this.props.icon}
</button>;
}
}
17 changes: 13 additions & 4 deletions src/components/objectinspector.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,22 @@
}

& h2 {
display: flex;
align-items: center;
padding: 1em;
overflow: hidden;
text-overflow: ellipsis;

& span {
& > span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: block;
margin-right: 1em;
margin-right: auto;
}

& > .ck-inspector-button {
margin-left: .5em;
}

& a {
Expand All @@ -40,20 +46,23 @@
}

& h3 {
display: flex;
align-items: center;
font-size: 12px;
padding: .4em .7em;

& a {
color: inherit;
font-weight: bold;
margin-right: auto;
}

& .ck-inspector-button {
display: none;
visibility: hidden;
}

&:hover .ck-inspector-button {
display: block
visibility: visible;
}
}

Expand Down
12 changes: 0 additions & 12 deletions src/components/pane.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,6 @@
}

& .ck-inspector-tree__config {
& + .ck-inspector-tree__config {
&::before {
content: "";
border-right: 1px solid var(--ck-inspector-color-border);
display: inline-block;
width: 0px;
height: 20px;
margin: 0 1em;
vertical-align: middle;
}
}

& label {
margin: 0 .5em;
}
Expand Down
5 changes: 5 additions & 0 deletions src/data/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const SET_HEIGHT = 'SET_HEIGHT';
export const SET_SIDE_PANE_WIDTH = 'SET_SIDE_PANE_WIDTH';
export const SET_EDITORS = 'SET_EDITORS';
export const SET_CURRENT_EDITOR_NAME = 'SET_CURRENT_EDITOR_NAME';
export const UPDATE_CURRENT_EDITOR_IS_READ_ONLY = 'UPDATE_CURRENT_EDITOR_IS_READ_ONLY';
export const SET_ACTIVE_INSPECTOR_TAB = 'SET_ACTIVE_INSPECTOR_TAB';

export function toggleIsCollapsed() {
Expand All @@ -33,3 +34,7 @@ export function setCurrentEditorName( editorName ) {
export function setActiveTab( tabName ) {
return { type: SET_ACTIVE_INSPECTOR_TAB, tabName };
}

export function updateCurrentEditorIsReadOnly() {
return { type: UPDATE_CURRENT_EDITOR_IS_READ_ONLY };
}
33 changes: 33 additions & 0 deletions src/data/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import {
SET_SIDE_PANE_WIDTH,
SET_EDITORS,
SET_CURRENT_EDITOR_NAME,
UPDATE_CURRENT_EDITOR_IS_READ_ONLY,
SET_ACTIVE_INSPECTOR_TAB
} from './actions';

import { getFirstEditorName } from '../utils';
import { getCurrentEditor } from './utils';

import LocalStorageManager from '../localstoragemanager';

Expand All @@ -28,6 +30,7 @@ export const LOCAL_STORAGE_SIDE_PANE_WIDTH = 'side-pane-width';
export function reducer( state, action ) {
const newState = appReducer( state, action );

newState.currentEditorGlobals = currentEditorGlobalsReducer( newState, newState.currentEditorGlobals, action );
newState.ui = appUIReducer( newState.ui, action );
newState.model = modelReducer( newState, newState.model, action );
newState.view = viewReducer( newState, newState.view, action );
Expand All @@ -50,6 +53,18 @@ function appReducer( state, action ) {
}
}

function currentEditorGlobalsReducer( state, globalsState, action ) {
switch ( action.type ) {
case SET_EDITORS:
case SET_CURRENT_EDITOR_NAME:
return getCurrentEditorGlobalState( state );
case UPDATE_CURRENT_EDITOR_IS_READ_ONLY:
return getNewCurrentEditorIsReadOnlyState( state, globalsState );
default:
return globalsState;
}
}

function appUIReducer( UIState, action ) {
// This happens when the inspector store is created for the first time only.
// Only #isCollapsed is passed then because it's configurable in inspector options.
Expand Down Expand Up @@ -96,6 +111,24 @@ function getNewCurrentEditorNameState( appState, action ) {
};
}

function getCurrentEditorGlobalState( appState ) {
const isReadOnlyState = getNewCurrentEditorIsReadOnlyState( appState, {} );

return {
...isReadOnlyState
};
}

function getNewCurrentEditorIsReadOnlyState( appState, globalsState ) {
const editor = getCurrentEditor( appState );

return {
...globalsState,

isReadOnly: editor ? editor.isReadOnly : false
};
}

function getNewEditorsState( appState, action ) {
const newState = {
editors: new Map( action.editors )
Expand Down
6 changes: 6 additions & 0 deletions src/data/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ export default class EditorListener {
startListening( currentEditor ) {
currentEditor.model.document.on( 'change', this._config.onModelChange );
currentEditor.editing.view.on( 'render', this._config.onViewRender );
currentEditor.on( 'change:isReadOnly', this._config.onReadOnlyChange );
}

stopListening( currentEditor ) {
currentEditor.model.document.off( 'change', this._config.onModelChange );
currentEditor.editing.view.off( 'render', this._config.onViewRender );
currentEditor.off( 'change:isReadOnly', this._config.onReadOnlyChange );
}
}

export function getCurrentEditor( globalState ) {
return globalState.editors.get( globalState.currentEditorName );
}
17 changes: 17 additions & 0 deletions src/editorquickactions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

.ck-inspector .ck-inspector-editor-quick-actions {
display: flex;
align-content: center;
justify-content: center;
align-items: center;
flex-direction: row;
flex-wrap: nowrap;

& > .ck-inspector-button {
margin-left: .3em;
}
}
Loading