Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Basic linking feature #19

Merged
merged 55 commits into from
Sep 9, 2016
Merged
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
58d139d
Introduced linking engine.
oskarwrobel Aug 12, 2016
ea4ead7
WIP: Introduced link command and link feature.
oskarwrobel Aug 17, 2016
353a2ff
Introduced basic manual test.
oskarwrobel Aug 17, 2016
7cdd8ab
Added binding for active feature. Improved docs.
oskarwrobel Aug 17, 2016
0f93f14
Improved link command.
oskarwrobel Aug 18, 2016
49d61b6
Minor test changes.
oskarwrobel Aug 18, 2016
fae57da
Created mockup of the LinkBalloonPanel.
oleq Aug 19, 2016
cdd90ab
Created basic themes for LinkBalloonPanel.
oleq Aug 19, 2016
d9373c0
Extended Link manual test to include the UI.
oleq Aug 19, 2016
eb414b4
Enabled LinkBalloonPanel in Link feature. Code refactoring.
oleq Aug 19, 2016
6f14c14
Merge remote-tracking branch 'origin/t/1' into t/2
oleq Aug 19, 2016
926f4dc
Use domConverter to obtain native DOM range.
oleq Aug 19, 2016
1b2db40
Added panel elements like button, URL input and label along with the
oleq Aug 19, 2016
fd070c7
Created balloonPanel#url attribute. Basic focus handling when editing…
oleq Aug 19, 2016
eda9c2b
Added Cancel button to LinkBalloonPanel component.
oleq Aug 22, 2016
20cbffc
Massive code refactoring, decoupling and polishing.
oleq Aug 22, 2016
82b170b
Minor refactoring.
oleq Aug 22, 2016
43c1fe6
Added tmp extended version of ck-z helper to linkballoonpanel stylesh…
oleq Aug 22, 2016
eb9223f
Decoupled styles for various components.
oleq Aug 22, 2016
98862a5
Merge branch 't/1' into t/2
oskarwrobel Aug 22, 2016
6821253
Improved data flow between the feature and the UI.
oleq Aug 22, 2016
fc5d6c5
Minor refactoring and docs in Link Feature.
oleq Aug 22, 2016
cd97be6
Added docs for _createBalloonPanel method in Link Feature.
oleq Aug 22, 2016
2cc453c
Very base ui and command integration.
oskarwrobel Aug 23, 2016
b52f48d
Refactored the way of creating panel.
oskarwrobel Aug 23, 2016
f8f9051
Prevent showing panel when editor is not focused.
oskarwrobel Aug 23, 2016
cd2a43c
Moved panel creation to Link Feature init(). Fixed some focus issues.
oleq Aug 23, 2016
762ae4d
Merge branch 't/1' into t/2
oskarwrobel Aug 23, 2016
f9fccc2
Merge branch 'master' into t/2
oskarwrobel Aug 24, 2016
a93540a
Moved Balloon Panel component to ckeditor5-ui-default and ckeditor5-t…
oskarwrobel Aug 29, 2016
932197b
Introduced toolbar unlink button.
oskarwrobel Aug 29, 2016
fc66303
Show panel on Ctrl+l keystroke.
oskarwrobel Aug 29, 2016
ad1d48f
Added missing docs and test for LinkBalloonPanel component.
oskarwrobel Aug 31, 2016
74770f1
Added missing bender tag.
oskarwrobel Aug 31, 2016
c240af5
Added test + minor refactor of Link feature.
oskarwrobel Aug 31, 2016
fb131cd
Moved bender tag at the top of file.
oskarwrobel Aug 31, 2016
7780ed3
Changed the way of getting editable element.
oskarwrobel Sep 4, 2016
25f3806
Removed Balloon Panel test case from link manual test.
oskarwrobel Sep 4, 2016
1b0fb4e
Added use cases to manual test.
oskarwrobel Sep 4, 2016
d3bb9b5
Removed unused editor init.
oskarwrobel Sep 5, 2016
dabe64c
Minor docs refactoring.
oskarwrobel Sep 5, 2016
2cf3f4d
Introduced LinkElement class.
oskarwrobel Sep 5, 2016
6b78bd9
Refactored the way of test which use editable element.
oskarwrobel Sep 5, 2016
a983c1d
Fixed typo in tests.
oskarwrobel Sep 5, 2016
a7ca040
Added unlink button to link balloon panel.
oskarwrobel Sep 5, 2016
f5c07b3
Refactoring after changes in `ckeditor5-ui-default`.
oskarwrobel Sep 8, 2016
10a09de
Changed initialization of LabeledInput component.
oskarwrobel Sep 8, 2016
52fe998
Added keystroke to button title.
oskarwrobel Sep 8, 2016
4840986
Changed CSS class name of LinkForm component region.
oskarwrobel Sep 8, 2016
b940d80
Refactored code style and docs.
oskarwrobel Sep 8, 2016
4b2e4d2
Refactored docs.
oskarwrobel Sep 8, 2016
e49efba
Minor code refactoring and documentation fixes.
oleq Sep 9, 2016
6749e9a
Minor code refactoring and documentation fixes.
oleq Sep 9, 2016
8fdf0f3
Used the new LabeledInput API in the LinkBalloonPanel.
oleq Sep 9, 2016
1091d43
Enhanced visually the link balloon panel with more space.
oleq Sep 9, 2016
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
Prev Previous commit
Next Next commit
Added missing docs and test for LinkBalloonPanel component.
oskarwrobel committed Aug 31, 2016
commit ad1d48f082548c6e7b41a3ba8c49cc1e0b068aac
63 changes: 53 additions & 10 deletions src/ui/linkballoonpanel.js
Original file line number Diff line number Diff line change
@@ -17,12 +17,22 @@ import BoxView from '../../ui/box/boxview.js';
/**
* The link balloon panel controller class.
*
* const model = new Model( {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An extra tab.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is hard to notice it in webstorm :)
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An extra space in fact... indeed it's poorly visible in Webstorm. Use Sublime :P

* maxWidth: 300,
* url: 'http://ckeditor.com'
* } );
*
* // An instance of LinkBalloonPanel.
* new LinkBalloonPanel( model, new LinkBalloonPanelView() );
*
* See {@link link.ui.LinkBalloonPanelView}.
*
* @memberOf link.ui
Copy link
Member

@oleq oleq Sep 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether link instead of link.ui would be enough. WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it's defined inside link/ui/. Then the namespace should reflect this, because this is how you'll import those classes.

* @extends ui.Controller
* @extends ui.balloonPanel.BalloonPanel
*/
export default class LinkBalloonPanel extends BalloonPanel {
/**
* Creates an instance of {@link ui.dropdown.Dropdown} class.
* Creates an instance of {@link link.ui.LinkBalloonPanel} class.
*
* @param {ui.balloonPanel.BalloonPanelModel} model Model of this balloon panel.
* @param {ui.View} view View of this balloon panel.
@@ -33,23 +43,37 @@ export default class LinkBalloonPanel extends BalloonPanel {
this.add( 'content', this._createForm() );
}

/**
* Initialize {@link ui.form.Form Form} component with input and buttons.
*
* @private
* @returns {ui.form.Form} Form component.
*/
_createForm() {
const formModel = new Model();

formModel.delegate( 'execute' ).to( this.model );

/**
* TODO
* Instance of {@link ui.form.Form Form} component.
*
* @member {} todo
* @member {ui.form.Form} link.ui.LinkBalloonPanel#form
*/
this.form = new Form( formModel, new FormView( this.locale ) );

// Add Input and buttons as a form content.
this.form.add( 'content', this._createLabeledInput() );
this.form.add( 'content', this._createButtons() );

return this.form;
}

/**
* Initialize {@link ui.input.LabeledInput LabeledInput} for providing `href` value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Initialize/Initializes (+ couple of eccurences below)

*
* @private
* @returns {ui.input.LabeledInput} Labeled input component.
*/
_createLabeledInput() {
const t = this.view.t;
const model = new Model( {
@@ -59,40 +83,53 @@ export default class LinkBalloonPanel extends BalloonPanel {
model.bind( 'value' ).to( this.model, 'url' );

/**
* TODO
* Input component for providing `href` value.
*
* @member {} todo
* @member {ui.input.LabeledInput} link.ui.LinkBalloonPanel#urlInput
*/
this.urlInput = new LabeledInput( model, new LabeledInputView( this.locale ) );

return this.urlInput;
}

/**
* Create {@link ui.box.Box Box} instance with `Cancel` and `Save` buttons.
*
* @private
* @returns {ui.box.Box} Box component.
*/
_createButtons() {
const box = new Box( new Model( {
alignRight: true
} ), new BoxView( this.locale ) );

/**
* TODO
* Button component for submitting form.
*
* @member {} todo
* @member {ui.button.Button} link.ui.LinkBalloonPanel#saveButton
*/
this.saveButton = this._createSaveButton();

/**
* TODO
* Button component for canceling form.
*
* @member {} todo
* @member {ui.button.Button} link.ui.LinkBalloonPanel#cancelButton
*/
this.cancelButton = this._createCancelButton();

// Add `Cancel` and `Save` buttons as a box content.
box.add( 'content', this.cancelButton );
box.add( 'content', this.saveButton );

return box;
}

/**
* Initialize {@link ui.button.Button Button} for submitting form.
*
* @private
* @returns {ui.button.Button} Save button component.
*/
_createSaveButton() {
const t = this.view.t;
const saveModel = new Model( {
@@ -110,6 +147,12 @@ export default class LinkBalloonPanel extends BalloonPanel {
return button;
}

/**
* Initialize {@link ui.button.Button Button} for canceling form.
*
* @private
* @returns {ui.button.Button} Cancel button component.
*/
_createCancelButton() {
const t = this.view.t;
const cancelModel = new Model( {
4 changes: 2 additions & 2 deletions src/ui/linkballoonpanelview.js
Original file line number Diff line number Diff line change
@@ -9,10 +9,10 @@ import BalloonPanelView from '../../ui/balloonpanel/balloonpanelview.js';
/**
* The link balloon panel view class.
*
* See {@link ui.balloonPanel.BalloonPanelView}.
* See {@link link.ui.LinkBalloonPanel}.
*
* @memberOf link.ui
* @extends ui.View
* @extends ui.balloonPanel.BalloonPanelView
*/
export default class LinkBalloonPanelView extends BalloonPanelView {
/**
114 changes: 114 additions & 0 deletions tests/ui/linkballoonpanel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

/* bender-tags: ui, link */

import LinkBalloonPanel from '/ckeditor5/link/ui/linkballoonpanel.js';
import LinkBalloonPanelView from '/ckeditor5/link/ui/linkballoonpanelview.js';
import BalloonPanel from '/ckeditor5/ui/balloonpanel/balloonpanel.js';
import Model from '/ckeditor5/ui/model.js';

import Form from '/ckeditor5/ui/form/form.js';
import LabeledInput from '/ckeditor5/ui/labeledinput/labeledinput.js';
import Button from '/ckeditor5/ui/button/button.js';

import LocaleMock from '/tests/utils/_utils/locale-mock.js';

describe( 'LinkBalloonPanel', () => {
let model, linkBalloonPanel, view;

beforeEach( () => {
model = new Model( {
maxWidth: 200,
url: 'http://ckeditor.com'
} );

view = new LinkBalloonPanelView( new LocaleMock() );
linkBalloonPanel = new LinkBalloonPanel( model, view );
} );

describe( 'constructor', () => {
it( 'should extends BalloonPanel class', () => {
expect( linkBalloonPanel ).to.be.instanceOf( BalloonPanel );
} );

describe( 'child components', () => {
describe( 'form', () => {
it( 'should creates Form instance', () => {
expect( linkBalloonPanel.form ).to.instanceof( Form );
} );

it( 'should appends to "content" collection', () => {
expect( linkBalloonPanel.collections.get( 'content' ).get( 0 ) ).to.deep.equal( linkBalloonPanel.form );
} );

it( 'should delegates form.model#execute to the model', () => {
const executeSpy = sinon.spy();

model.on( 'execute', executeSpy );

linkBalloonPanel.form.model.fire( 'execute' );

expect( executeSpy.calledOnce ).to.true;
} );
} );

describe( 'urlInput', () => {
it( 'should creates LabeledInput instance', () => {
expect( linkBalloonPanel.urlInput ).to.instanceof( LabeledInput );
} );

it( 'should appends to Form "content" collection', () => {
expect( linkBalloonPanel.form.collections.get( 'content' ).get( 0 ) ).to.deep.equal( linkBalloonPanel.urlInput );
} );

it( 'should binds model#url to urlInput.model#value', () => {
expect( linkBalloonPanel.urlInput.model.value ).to.equal( model.url ).to.equal( 'http://ckeditor.com' );

model.url = 'http://cksource.com';

expect( linkBalloonPanel.urlInput.model.value ).to.equal( 'http://cksource.com' );
} );
} );

describe( 'saveButton', () => {
it( 'should creates Button instance', () => {
expect( linkBalloonPanel.saveButton ).to.instanceof( Button );
} );

it( 'should trigger model#execute event after clicking', ( done ) => {
const executeSpy = sinon.spy();

model.on( 'execute', executeSpy );

linkBalloonPanel.init().then( () => {
linkBalloonPanel.saveButton.view.element.click();

expect( executeSpy.calledOnce ).to.true;
done();
} );
} );

it( 'should be a submit', () => {
expect( linkBalloonPanel.saveButton.model.type ).to.equal( 'submit' );
} );
} );

describe( 'cancelButton', () => {
it( 'should creates Button instance', () => {
expect( linkBalloonPanel.cancelButton ).to.instanceof( Button );
} );

it( 'should hide LinkBalloonPanel on cancelButton.model#execute event', () => {
const hideSpy = sinon.spy( linkBalloonPanel.view, 'hide' );

linkBalloonPanel.cancelButton.model.fire( 'execute' );

expect( hideSpy.calledOnce ).to.true;
} );
} );
} );
} );
} );
27 changes: 27 additions & 0 deletions tests/ui/linkballoonpanelview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

/* bender-tags: ui, link */

import LinkBalloonPanelView from '/ckeditor5/link/ui/linkballoonpanelview.js';
import BalloonPanelView from '/ckeditor5/ui/balloonpanel/balloonpanelview.js';

describe( 'LinkBalloonPanelView', () => {
let view;

beforeEach( () => {
view = new LinkBalloonPanelView();
} );

describe( 'constructor', () => {
it( 'should extends BalloonPanelView class', () => {
expect( view ).to.be.instanceof( BalloonPanelView );
} );

it( 'should extend BalloonPanel element by additional class', () => {
expect( view.element.classList.contains( 'ck-link-balloon-panel' ) ).to.be.true;
} );
} );
} );