|
270 | 270 | var walker = new CKEDITOR.dom.walker( range ),
|
271 | 271 | wrapper;
|
272 | 272 |
|
273 |
| - walker.evaluator = isDomWidgetWrapper; |
| 273 | + walker.evaluator = Widget.isDomWidgetWrapper; |
274 | 274 |
|
275 | 275 | while ( ( wrapper = walker.next() ) )
|
276 | 276 | updater.select( this.getByElement( wrapper ) );
|
|
417 | 417 | */
|
418 | 418 | finalizeCreation: function( container ) {
|
419 | 419 | var wrapper = container.getFirst();
|
420 |
| - if ( wrapper && isDomWidgetWrapper( wrapper ) ) { |
| 420 | + if ( wrapper && Widget.isDomWidgetWrapper( wrapper ) ) { |
421 | 421 | this.editor.insertElement( wrapper );
|
422 | 422 |
|
423 | 423 | var widget = this.getByElement( wrapper );
|
|
533 | 533 | instance;
|
534 | 534 |
|
535 | 535 | 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 ) ); |
537 | 537 | if ( instance )
|
538 | 538 | newInstances.push( instance );
|
539 | 539 | }
|
|
655 | 655 | },
|
656 | 656 |
|
657 | 657 | // Expose for tests.
|
658 |
| - _tests_getNestedEditable: getNestedEditable, |
659 | 658 | _tests_createEditableFilter: createEditableFilter
|
660 | 659 | };
|
661 | 660 |
|
|
1401 | 1400 |
|
1402 | 1401 | CKEDITOR.event.implementOn( Widget.prototype );
|
1403 | 1402 |
|
| 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 | + |
1404 | 1510 | /**
|
1405 | 1511 | * An event fired when a widget is ready (fully initialized). This event is fired after:
|
1406 | 1512 | *
|
|
1824 | 1930 | // Add cke_widget_new class because otherwise
|
1825 | 1931 | // widget will not be created on such wrapper.
|
1826 | 1932 | wrapper.addClass( 'cke_widget_new' );
|
1827 |
| - newInstances.push( this.initOn( wrapper.getFirst( isDomWidgetElement ) ) ); |
| 1933 | + newInstances.push( this.initOn( wrapper.getFirst( Widget.isDomWidgetElement ) ) ); |
1828 | 1934 | }
|
1829 | 1935 | }
|
1830 | 1936 | }
|
|
1861 | 1967 |
|
1862 | 1968 | for ( ; i < l; ++i ) {
|
1863 | 1969 | wrapper = wrappers.getItem( i );
|
1864 |
| - element = wrapper.getFirst( isDomWidgetElement ); |
| 1970 | + element = wrapper.getFirst( Widget.isDomWidgetElement ); |
1865 | 1971 | // If wrapper contains widget element - unwrap it and wrap again.
|
1866 | 1972 | if ( element.type == CKEDITOR.NODE_ELEMENT && element.data( 'widget' ) ) {
|
1867 | 1973 | element.replace( wrapper );
|
|
1921 | 2027 | // Wrapper found - find widget element, add it to be
|
1922 | 2028 | // cleaned up (unwrapped) and wrapped and stop iterating in this branch.
|
1923 | 2029 | if ( 'data-cke-widget-wrapper' in element.attributes ) {
|
1924 |
| - element = element.getFirst( isParserWidgetElement ); |
| 2030 | + element = element.getFirst( Widget.isParserWidgetElement ); |
1925 | 2031 |
|
1926 | 2032 | if ( element )
|
1927 | 2033 | toBeWrapped.push( [ element ] );
|
|
1991 | 2097 | return false;
|
1992 | 2098 | }
|
1993 | 2099 |
|
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 |
| - |
2009 | 2100 | function getWrapperAttributes( inlineWidget ) {
|
2010 | 2101 | return {
|
2011 | 2102 | // tabindex="-1" means that it can receive focus by code.
|
|
2058 | 2149 | parent.add( element, index );
|
2059 | 2150 | }
|
2060 | 2151 |
|
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} |
2072 | 2159 | function isWidgetInline( widgetDef, elementName ) {
|
2073 | 2160 | return typeof widgetDef.inline == 'boolean' ? widgetDef.inline : !!CKEDITOR.dtd.$inline[ elementName ];
|
2074 | 2161 | }
|
2075 | 2162 |
|
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 |
| - |
2091 | 2163 | // @param {CKEDITOR.dom.element}
|
| 2164 | + // @returns {Boolean} |
2092 | 2165 | function isDomTemp( element ) {
|
2093 | 2166 | return element.hasAttribute( 'data-cke-temp' );
|
2094 | 2167 | }
|
2095 | 2168 |
|
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 |
| - |
2106 | 2169 | function onEditableKey( widget, keyCode ) {
|
2107 | 2170 | var focusedEditable = widget.focusedEditable,
|
2108 | 2171 | range;
|
|
2202 | 2265 | editor.on( 'dragstart', function( evt ) {
|
2203 | 2266 | var target = evt.data.target;
|
2204 | 2267 |
|
2205 |
| - if ( isDomDragHandler( target ) ) { |
| 2268 | + if ( Widget.isDomDragHandler( target ) ) { |
2206 | 2269 | var widget = widgetsRepo.getByElement( target );
|
2207 | 2270 |
|
2208 | 2271 | evt.data.dataTransfer.setData( 'cke/widget-id', widget.id );
|
|
2254 | 2317 | return;
|
2255 | 2318 |
|
2256 | 2319 | // Allow drop line inside, but never before or after nested editable (#12006).
|
2257 |
| - if ( isDomNestedEditable( el ) ) |
| 2320 | + if ( Widget.isDomNestedEditable( el ) ) |
2258 | 2321 | return;
|
2259 | 2322 |
|
2260 | 2323 | // 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 ); |
2262 | 2325 | if ( nestedEditable ) {
|
2263 | 2326 | var draggedWidget = widgetsRepo._.draggedWidget;
|
2264 | 2327 |
|
|
2327 | 2390 | return;
|
2328 | 2391 | }
|
2329 | 2392 |
|
2330 |
| - if ( !getNestedEditable( widget.wrapper, target ) ) { |
| 2393 | + if ( !Widget.getNestedEditable( widget.wrapper, target ) ) { |
2331 | 2394 | evt.data.preventDefault();
|
2332 | 2395 | if ( !CKEDITOR.env.ie )
|
2333 | 2396 | widget.focus();
|
|
2369 | 2432 | var widget = widgetsRepo.getByElement( evt.data.element );
|
2370 | 2433 |
|
2371 | 2434 | // 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 ) ) |
2373 | 2436 | return;
|
2374 | 2437 |
|
2375 | 2438 | return widget.fire( 'doubleclick', { element: evt.data.element } );
|
|
2430 | 2493 | widgetsRepo.on( 'checkSelection', widgetsRepo.checkSelection, widgetsRepo );
|
2431 | 2494 |
|
2432 | 2495 | 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() ), |
2434 | 2497 | newWidget = nestedEditable && widgetsRepo.getByElement( nestedEditable ),
|
2435 | 2498 | oldWidget = widgetsRepo.widgetHoldingFocusedEditable;
|
2436 | 2499 |
|
|
2506 | 2569 | if ( 'data-cke-widget-id' in attrs ) {
|
2507 | 2570 | widget = widgetsRepo.instances[ attrs[ 'data-cke-widget-id' ] ];
|
2508 | 2571 | if ( widget ) {
|
2509 |
| - widgetElement = element.getFirst( isParserWidgetElement ); |
| 2572 | + widgetElement = element.getFirst( Widget.isParserWidgetElement ); |
2510 | 2573 | toBeDowncasted.push( {
|
2511 | 2574 | wrapper: element,
|
2512 | 2575 | element: widgetElement,
|
|
2592 | 2655 |
|
2593 | 2656 | // Used to determine whether only widget was pasted.
|
2594 | 2657 | processedWidgetOnly = evt.data.dataValue.children.length == 1 &&
|
2595 |
| - isParserWidgetWrapper( evt.data.dataValue.children[ 0 ] ); |
| 2658 | + Widget.isParserWidgetWrapper( evt.data.dataValue.children[ 0 ] ); |
2596 | 2659 | }, null, null, 8 );
|
2597 | 2660 |
|
2598 | 2661 | editor.on( 'dataReady', function() {
|
|
2904 | 2967 |
|
2905 | 2968 | var editor = widget.editor,
|
2906 | 2969 | // Use getLast to find wrapper's direct descendant (#12022).
|
2907 |
| - container = widget.wrapper.getLast( isDomDragHandlerContainer ), |
| 2970 | + container = widget.wrapper.getLast( Widget.isDomDragHandlerContainer ), |
2908 | 2971 | img;
|
2909 | 2972 |
|
2910 | 2973 | // Reuse drag handler if already exists (#11281).
|
|
3117 | 3180 | var target = evt.data.getTarget();
|
3118 | 3181 |
|
3119 | 3182 | // 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 ) ) ) |
3121 | 3184 | evt.data.preventDefault();
|
3122 | 3185 | } );
|
3123 | 3186 | }
|
|
3272 | 3335 | * @returns {Boolean}
|
3273 | 3336 | */
|
3274 | 3337 | checkElement: function( element ) {
|
3275 |
| - if ( !isDomWidgetWrapper( element ) ) |
| 3338 | + if ( !Widget.isDomWidgetWrapper( element ) ) |
3276 | 3339 | return false;
|
3277 | 3340 |
|
3278 |
| - var widgetElement = element.getFirst( isDomWidgetElement ); |
| 3341 | + var widgetElement = element.getFirst( Widget.isDomWidgetElement ); |
3279 | 3342 | return widgetElement && widgetElement.data( 'widget' ) == this.widget;
|
3280 | 3343 | },
|
3281 | 3344 |
|
|
0 commit comments