Skip to content

Commit 96d5130

Browse files
author
Piotr Jasiun
committed
Merge branch 't/12150' into major
2 parents 8400e4e + 757eef3 commit 96d5130

File tree

3 files changed

+260
-71
lines changed

3 files changed

+260
-71
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Other Changes:
2929

3030
* [#10903](http://dev.ckeditor.com/ticket/10903): Performance improvements for [`addClass`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-addClass), [`removeClass`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeClass) and [`hasClass`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-hasClass) methods.
3131
* [#11856](http://dev.ckeditor.com/ticket/11856): jQuery adapter throw an meaningful error if CKEditor or jQuery is not loaded.
32+
* [#12150](http://dev.ckeditor.com/ticket/12150): Expose [`getNestedEditable`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-static-method-getNestedEditable) and `is*` [widget helper](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) functions.
3233

3334
## CKEditor 4.4.7
3435

plugins/widget/plugin.js

Lines changed: 133 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
var walker = new CKEDITOR.dom.walker( range ),
271271
wrapper;
272272

273-
walker.evaluator = isDomWidgetWrapper;
273+
walker.evaluator = Widget.isDomWidgetWrapper;
274274

275275
while ( ( wrapper = walker.next() ) )
276276
updater.select( this.getByElement( wrapper ) );
@@ -417,7 +417,7 @@
417417
*/
418418
finalizeCreation: function( container ) {
419419
var wrapper = container.getFirst();
420-
if ( wrapper && isDomWidgetWrapper( wrapper ) ) {
420+
if ( wrapper && Widget.isDomWidgetWrapper( wrapper ) ) {
421421
this.editor.insertElement( wrapper );
422422

423423
var widget = this.getByElement( wrapper );
@@ -533,7 +533,7 @@
533533
instance;
534534

535535
for ( var i = newWidgets.count(); i--; ) {
536-
instance = this.initOn( newWidgets.getItem( i ).getFirst( isDomWidgetElement ) );
536+
instance = this.initOn( newWidgets.getItem( i ).getFirst( Widget.isDomWidgetElement ) );
537537
if ( instance )
538538
newInstances.push( instance );
539539
}
@@ -655,7 +655,6 @@
655655
},
656656

657657
// Expose for tests.
658-
_tests_getNestedEditable: getNestedEditable,
659658
_tests_createEditableFilter: createEditableFilter
660659
};
661660

@@ -1401,6 +1400,113 @@
14011400

14021401
CKEDITOR.event.implementOn( Widget.prototype );
14031402

1403+
/**
1404+
* Gets the {@link #isDomNestedEditable nested editable}
1405+
* (returned as a {@link CKEDITOR.dom.element}, not {@link CKEDITOR.plugins.widget.nestedEditable})
1406+
* closest to the `node` or the `node` if it is a nested editable itself.
1407+
*
1408+
* @since 4.5.0
1409+
* @static
1410+
* @param {CKEDITOR.dom.element} guard Stop ancestor search on this node (usually editor's editable).
1411+
* @param {CKEDITOR.dom.node} node Start search from this node.
1412+
* @returns {CKEDITOR.dom.element/null} Element or `null` if not found.
1413+
*/
1414+
Widget.getNestedEditable = function( guard, node ) {
1415+
if ( !node || node.equals( guard ) )
1416+
return null;
1417+
1418+
if ( Widget.isDomNestedEditable( node ) )
1419+
return node;
1420+
1421+
return Widget.getNestedEditable( guard, node.getParent() );
1422+
};
1423+
1424+
/**
1425+
* Checks whether the `node` is a widget's drag handle element.
1426+
*
1427+
* @since 4.5.0
1428+
* @static
1429+
* @param {CKEDITOR.dom.node} node
1430+
* @returns {Boolean}
1431+
*/
1432+
Widget.isDomDragHandler = function( node ) {
1433+
return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-drag-handler' );
1434+
};
1435+
1436+
/**
1437+
* Checks whether the `node` is a container of the widget's drag handle element.
1438+
*
1439+
* @since 4.5.0
1440+
* @static
1441+
* @param {CKEDITOR.dom.node} node
1442+
* @returns {Boolean}
1443+
*/
1444+
Widget.isDomDragHandlerContainer = function( node ) {
1445+
return node.type == CKEDITOR.NODE_ELEMENT && node.hasClass( 'cke_widget_drag_handler_container' );
1446+
};
1447+
1448+
/**
1449+
* Checks whether the `node` is a {@link CKEDITOR.plugins.widget#editables nested editable}.
1450+
* Note that this function checks only whether it is the right element, not whether
1451+
* the passed `node` is an instance of {@link CKEDITOR.plugins.widget.nestedEditable}.
1452+
*
1453+
* @since 4.5.0
1454+
* @static
1455+
* @param {CKEDITOR.dom.node} node
1456+
* @returns {Boolean}
1457+
*/
1458+
Widget.isDomNestedEditable = function( node ) {
1459+
return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-editable' );
1460+
};
1461+
1462+
/**
1463+
* Checks whether the `node` is a {@link CKEDITOR.plugins.widget#element widget element}.
1464+
*
1465+
* @since 4.5.0
1466+
* @static
1467+
* @param {CKEDITOR.dom.node} node
1468+
* @returns {Boolean}
1469+
*/
1470+
Widget.isDomWidgetElement = function( node ) {
1471+
return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-widget' );
1472+
};
1473+
1474+
/**
1475+
* Checks whether the `node` is a {@link CKEDITOR.plugins.widget#wrapper widget wrapper}.
1476+
*
1477+
* @since 4.5.0
1478+
* @static
1479+
* @param {CKEDITOR.dom.element} node
1480+
* @returns {Boolean}
1481+
*/
1482+
Widget.isDomWidgetWrapper = function( node ) {
1483+
return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-wrapper' );
1484+
};
1485+
1486+
/**
1487+
* Checks whether the `node` is a {@link CKEDITOR.plugins.widget#element widget element}.
1488+
*
1489+
* @since 4.5.0
1490+
* @static
1491+
* @param {CKEDITOR.htmlParser.node} node
1492+
* @returns {Boolean}
1493+
*/
1494+
Widget.isParserWidgetElement = function( node ) {
1495+
return node.type == CKEDITOR.NODE_ELEMENT && !!node.attributes[ 'data-widget' ];
1496+
};
1497+
1498+
/**
1499+
* Checks whether the `node` is a {@link CKEDITOR.plugins.widget#wrapper widget wrapper}.
1500+
*
1501+
* @since 4.5.0
1502+
* @static
1503+
* @param {CKEDITOR.htmlParser.element} node
1504+
* @returns {Boolean}
1505+
*/
1506+
Widget.isParserWidgetWrapper = function( node ) {
1507+
return node.type == CKEDITOR.NODE_ELEMENT && !!node.attributes[ 'data-cke-widget-wrapper' ];
1508+
};
1509+
14041510
/**
14051511
* An event fired when a widget is ready (fully initialized). This event is fired after:
14061512
*
@@ -1824,7 +1930,7 @@
18241930
// Add cke_widget_new class because otherwise
18251931
// widget will not be created on such wrapper.
18261932
wrapper.addClass( 'cke_widget_new' );
1827-
newInstances.push( this.initOn( wrapper.getFirst( isDomWidgetElement ) ) );
1933+
newInstances.push( this.initOn( wrapper.getFirst( Widget.isDomWidgetElement ) ) );
18281934
}
18291935
}
18301936
}
@@ -1861,7 +1967,7 @@
18611967

18621968
for ( ; i < l; ++i ) {
18631969
wrapper = wrappers.getItem( i );
1864-
element = wrapper.getFirst( isDomWidgetElement );
1970+
element = wrapper.getFirst( Widget.isDomWidgetElement );
18651971
// If wrapper contains widget element - unwrap it and wrap again.
18661972
if ( element.type == CKEDITOR.NODE_ELEMENT && element.data( 'widget' ) ) {
18671973
element.replace( wrapper );
@@ -1921,7 +2027,7 @@
19212027
// Wrapper found - find widget element, add it to be
19222028
// cleaned up (unwrapped) and wrapped and stop iterating in this branch.
19232029
if ( 'data-cke-widget-wrapper' in element.attributes ) {
1924-
element = element.getFirst( isParserWidgetElement );
2030+
element = element.getFirst( Widget.isParserWidgetElement );
19252031

19262032
if ( element )
19272033
toBeWrapped.push( [ element ] );
@@ -1991,21 +2097,6 @@
19912097
return false;
19922098
}
19932099

1994-
// Gets nested editable if node is its descendant or the editable itself.
1995-
//
1996-
// @param {CKEDITOR.dom.element} guard Stop ancestor search on this node (usually editor's editable).
1997-
// @param {CKEDITOR.dom.node} node Start search from this node.
1998-
// @returns {CKEDITOR.dom.element} Element or null.
1999-
function getNestedEditable( guard, node ) {
2000-
if ( !node || node.equals( guard ) )
2001-
return null;
2002-
2003-
if ( isDomNestedEditable( node ) )
2004-
return node;
2005-
2006-
return getNestedEditable( guard, node.getParent() );
2007-
}
2008-
20092100
function getWrapperAttributes( inlineWidget ) {
20102101
return {
20112102
// tabindex="-1" means that it can receive focus by code.
@@ -2058,51 +2149,23 @@
20582149
parent.add( element, index );
20592150
}
20602151

2061-
// @param {CKEDITOR.htmlParser.element}
2062-
function isParserWidgetElement( element ) {
2063-
return element.type == CKEDITOR.NODE_ELEMENT && !!element.attributes[ 'data-widget' ];
2064-
}
2065-
2066-
// @param {CKEDITOR.dom.element}
2067-
function isDomWidgetElement( element ) {
2068-
return element.type == CKEDITOR.NODE_ELEMENT && element.hasAttribute( 'data-widget' );
2069-
}
2070-
2071-
// Whether for this definition and element widget should be created in inline or block mode.
2152+
// Checks whether for the given widget definition and element widget should be created in inline or block mode.
2153+
//
2154+
// See also: {@link CKEDITOR.plugins.widget.definition#inline} and {@link CKEDITOR.plugins.widget#element}.
2155+
//
2156+
// @param {CKEDITOR.plugins.widget.definition} widgetDef The widget definition.
2157+
// @param {String} elementName The name of the widget element.
2158+
// @returns {Boolean}
20722159
function isWidgetInline( widgetDef, elementName ) {
20732160
return typeof widgetDef.inline == 'boolean' ? widgetDef.inline : !!CKEDITOR.dtd.$inline[ elementName ];
20742161
}
20752162

2076-
// @param {CKEDITOR.htmlParser.element}
2077-
function isParserWidgetWrapper( element ) {
2078-
return element.type == CKEDITOR.NODE_ELEMENT && element.attributes[ 'data-cke-widget-wrapper' ];
2079-
}
2080-
2081-
// @param {CKEDITOR.dom.element}
2082-
function isDomWidgetWrapper( element ) {
2083-
return element.type == CKEDITOR.NODE_ELEMENT && element.hasAttribute( 'data-cke-widget-wrapper' );
2084-
}
2085-
2086-
// @param {CKEDITOR.dom.element}
2087-
function isDomNestedEditable( node ) {
2088-
return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-editable' );
2089-
}
2090-
20912163
// @param {CKEDITOR.dom.element}
2164+
// @returns {Boolean}
20922165
function isDomTemp( element ) {
20932166
return element.hasAttribute( 'data-cke-temp' );
20942167
}
20952168

2096-
// @param {CKEDITOR.dom.element}
2097-
function isDomDragHandler( element ) {
2098-
return element.type == CKEDITOR.NODE_ELEMENT && element.hasAttribute( 'data-cke-widget-drag-handler' );
2099-
}
2100-
2101-
// @param {CKEDITOR.dom.element}
2102-
function isDomDragHandlerContainer( element ) {
2103-
return element.type == CKEDITOR.NODE_ELEMENT && element.hasClass( 'cke_widget_drag_handler_container' );
2104-
}
2105-
21062169
function onEditableKey( widget, keyCode ) {
21072170
var focusedEditable = widget.focusedEditable,
21082171
range;
@@ -2202,7 +2265,7 @@
22022265
editor.on( 'dragstart', function( evt ) {
22032266
var target = evt.data.target;
22042267

2205-
if ( isDomDragHandler( target ) ) {
2268+
if ( Widget.isDomDragHandler( target ) ) {
22062269
var widget = widgetsRepo.getByElement( target );
22072270

22082271
evt.data.dataTransfer.setData( 'cke/widget-id', widget.id );
@@ -2254,11 +2317,11 @@
22542317
return;
22552318

22562319
// Allow drop line inside, but never before or after nested editable (#12006).
2257-
if ( isDomNestedEditable( el ) )
2320+
if ( Widget.isDomNestedEditable( el ) )
22582321
return;
22592322

22602323
// If element is nested editable, make sure widget can be dropped there (#12006).
2261-
var nestedEditable = getNestedEditable( editable, el );
2324+
var nestedEditable = Widget.getNestedEditable( editable, el );
22622325
if ( nestedEditable ) {
22632326
var draggedWidget = widgetsRepo._.draggedWidget;
22642327

@@ -2327,7 +2390,7 @@
23272390
return;
23282391
}
23292392

2330-
if ( !getNestedEditable( widget.wrapper, target ) ) {
2393+
if ( !Widget.getNestedEditable( widget.wrapper, target ) ) {
23312394
evt.data.preventDefault();
23322395
if ( !CKEDITOR.env.ie )
23332396
widget.focus();
@@ -2369,7 +2432,7 @@
23692432
var widget = widgetsRepo.getByElement( evt.data.element );
23702433

23712434
// Not in widget or in nested editable.
2372-
if ( !widget || getNestedEditable( widget.wrapper, evt.data.element ) )
2435+
if ( !widget || Widget.getNestedEditable( widget.wrapper, evt.data.element ) )
23732436
return;
23742437

23752438
return widget.fire( 'doubleclick', { element: evt.data.element } );
@@ -2430,7 +2493,7 @@
24302493
widgetsRepo.on( 'checkSelection', widgetsRepo.checkSelection, widgetsRepo );
24312494

24322495
editor.on( 'selectionChange', function( evt ) {
2433-
var nestedEditable = getNestedEditable( editor.editable(), evt.data.selection.getStartElement() ),
2496+
var nestedEditable = Widget.getNestedEditable( editor.editable(), evt.data.selection.getStartElement() ),
24342497
newWidget = nestedEditable && widgetsRepo.getByElement( nestedEditable ),
24352498
oldWidget = widgetsRepo.widgetHoldingFocusedEditable;
24362499

@@ -2506,7 +2569,7 @@
25062569
if ( 'data-cke-widget-id' in attrs ) {
25072570
widget = widgetsRepo.instances[ attrs[ 'data-cke-widget-id' ] ];
25082571
if ( widget ) {
2509-
widgetElement = element.getFirst( isParserWidgetElement );
2572+
widgetElement = element.getFirst( Widget.isParserWidgetElement );
25102573
toBeDowncasted.push( {
25112574
wrapper: element,
25122575
element: widgetElement,
@@ -2592,7 +2655,7 @@
25922655

25932656
// Used to determine whether only widget was pasted.
25942657
processedWidgetOnly = evt.data.dataValue.children.length == 1 &&
2595-
isParserWidgetWrapper( evt.data.dataValue.children[ 0 ] );
2658+
Widget.isParserWidgetWrapper( evt.data.dataValue.children[ 0 ] );
25962659
}, null, null, 8 );
25972660

25982661
editor.on( 'dataReady', function() {
@@ -2904,7 +2967,7 @@
29042967

29052968
var editor = widget.editor,
29062969
// Use getLast to find wrapper's direct descendant (#12022).
2907-
container = widget.wrapper.getLast( isDomDragHandlerContainer ),
2970+
container = widget.wrapper.getLast( Widget.isDomDragHandlerContainer ),
29082971
img;
29092972

29102973
// Reuse drag handler if already exists (#11281).
@@ -3117,7 +3180,7 @@
31173180
var target = evt.data.getTarget();
31183181

31193182
// Allow text dragging inside nested editables or dragging inline widget's drag handler.
3120-
if ( !getNestedEditable( widget, target ) && !( widget.inline && isDomDragHandler( target ) ) )
3183+
if ( !Widget.getNestedEditable( widget, target ) && !( widget.inline && Widget.isDomDragHandler( target ) ) )
31213184
evt.data.preventDefault();
31223185
} );
31233186
}
@@ -3272,10 +3335,10 @@
32723335
* @returns {Boolean}
32733336
*/
32743337
checkElement: function( element ) {
3275-
if ( !isDomWidgetWrapper( element ) )
3338+
if ( !Widget.isDomWidgetWrapper( element ) )
32763339
return false;
32773340

3278-
var widgetElement = element.getFirst( isDomWidgetElement );
3341+
var widgetElement = element.getFirst( Widget.isDomWidgetElement );
32793342
return widgetElement && widgetElement.data( 'widget' ) == this.widget;
32803343
},
32813344

0 commit comments

Comments
 (0)