anchor_link-8.x-1.x-dev/js/unlink/plugin.js

js/unlink/plugin.js
/**
 * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */

'use strict';

( function () {
    CKEDITOR.plugins.add( 'unlink', {
        // jscs:disable maximumLineLength
        lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,es-mx,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
        // jscs:enable maximumLineLength
        icons: 'unlink', // %REMOVE_LINE_CORE%
        hidpi: true, // %REMOVE_LINE_CORE%
        onLoad: function () {

            var template = '.%2 a.cke_anchor,' +
                '.%2 a.cke_anchor_empty' +
                ',.cke_editable.%2 a[name]' +
                ',.cke_editable.%2 a[data-cke-saved-name]' +
                '{' +
                    baseStyle +
                    'padding-%1:18px;' +
                    // Show the arrow cursor for the anchor image (FF at least).
                    'cursor:auto;' +
                '}' +
                '.%2 img.cke_anchor' +
                '{' +
                    baseStyle +
                    'width:16px;' +
                    'min-height:15px;' +
                    // The default line-height on IE.
                    'height:1.15em;' +
                    // Opera works better with "middle" (even if not perfect)
                    'vertical-align:text-bottom;' +
                '}';

            // Styles with contents direction awareness.
            function cssWithDir( dir ) {
                return template.replace( /%1/g, dir == 'rtl' ? 'right' : 'left' ).replace( /%2/g, 'cke_contents_' + dir );
            }

            CKEDITOR.addCss( cssWithDir( 'ltr' ) + cssWithDir( 'rtl' ) );
        },

        init: function ( editor ) {
            var allowed = 'a[!href]',
                required = 'a[href]';

            editor.addCommand( 'unlink', new CKEDITOR.unlinkCommand() );

            if ( editor.ui.addButton ) {
                editor.ui.addButton( 'Unlink', {
                    label: editor.lang.unlink.unlink,
                    command: 'unlink',
                    toolbar: 'links,20'
                } );
            }

            // If the "menu" plugin is loaded, register the menu items.
            if ( editor.addMenuItems ) {
                editor.addMenuItems( {
                    unlink: {
                        label: editor.lang.unlink.unlink,
                        command: 'unlink',
                        group: 'link',
                        order: 5
                    }
                } );
            }

            this.compiledProtectionFunction = getCompiledProtectionFunction( editor );
        },

    } );

    // Loads the parameters in a selected link to the link dialog fields.
    var javascriptProtocolRegex = /^javascript:/,
        emailRegex = /^(?:mailto)(?:(?!\?(subject|body)=).)+/i,
        emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/i,
        emailBodyRegex = /body=([^;?:@&=$,\/]*)/i,
        anchorRegex = /^#(.*)$/,
        urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,
        selectableTargets = /^(_(?:self|top|parent|blank))$/,
        encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,
        functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/,
        popupRegex = /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/,
        popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi,
        telRegex = /^tel:(.*)$/;

    var advAttrNames = {
        id: 'advId',
        dir: 'advLangDir',
        accessKey: 'advAccessKey',
        // 'data-cke-saved-name': 'advName',
        name: 'advName',
        lang: 'advLangCode',
        tabindex: 'advTabIndex',
        title: 'advTitle',
        type: 'advContentType',
        'class': 'advCSSClasses',
        charset: 'advCharset',
        style: 'advStyles',
        rel: 'advRel'
    };

    function unescapeSingleQuote( str ) {
        return str.replace( /\\'/g, '\'' );
    }

    function escapeSingleQuote( str ) {
        return str.replace( /'/g, '\\$&' );
    }

    function protectEmailAddressAsEncodedString( address ) {
        var length = address.length,
            encodedChars = [],
            charCode;

        for ( var i = 0; i < length; i++ ) {
            charCode = address.charCodeAt( i );
            encodedChars.push( charCode );
        }

        return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';
    }

    function protectEmailLinkAsFunction( editor, email ) {
        var plugin = editor.plugins.link,
            name = plugin.compiledProtectionFunction.name,
            params = plugin.compiledProtectionFunction.params,
            retval = [ name, '(' ],
            paramName,
            paramValue;

        for ( var i = 0; i < params.length; i++ ) {
            paramName = params[ i ].toLowerCase();
            paramValue = email[ paramName ];

            i > 0 && retval.push( ',' );
            retval.push( '\'', paramValue ? escapeSingleQuote( encodeURIComponent( email[ paramName ] ) ) : '', '\'' );
        }
        retval.push( ')' );
        return retval.join( '' );
    }

    function getCompiledProtectionFunction( editor ) {
        var emailProtection = editor.config.emailProtection || '',
            compiledProtectionFunction;

        // Compile the protection function pattern.
        if ( emailProtection && emailProtection != 'encode' ) {
            compiledProtectionFunction = {};

            emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function ( match, funcName, params ) {
                compiledProtectionFunction.name = funcName;
                compiledProtectionFunction.params = [];
                params.replace( /[^,\s]+/g, function ( param ) {
                    compiledProtectionFunction.params.push( param );
                } );
            } );
        }

        return compiledProtectionFunction;
    }

    /**
     * Set of Link plugin helpers.
     *
     * @class
     * @singleton
     */
    CKEDITOR.plugins.unlink = {
        /**
         * Get the surrounding link element of the current selection.
         *
         *        CKEDITOR.plugins.unlink.getSelectedLink( editor );
         *
         *        // The following selections will all return the link element.
         *
         *        <a href="#">li^nk</a>
         *        <a href="#">[link]</a>
         *        text[<a href="#">link]</a>
         *        <a href="#">li[nk</a>]
         *        [<b><a href="#">li]nk</a></b>]
         *        [<a href="#"><b>li]nk</b></a>
         *
         * @since 3.2.1
         * @param {CKEDITOR.editor} editor
         * @param {Boolean} [returnMultiple=false] Indicates whether the function should return only the first selected link or all of them.
         * @returns {CKEDITOR.dom.element/CKEDITOR.dom.element[]/null} A single link element or an array of link
         * elements relevant to the current selection.
         */
        getSelectedLink: function ( editor, returnMultiple ) {
            var selection = editor.getSelection(),
                selectedElement = selection.getSelectedElement(),
                ranges = selection.getRanges(),
                links = [],
                link,
                range;

            if ( !returnMultiple && selectedElement && selectedElement.is( 'a' ) ) {
                return selectedElement;
            }

            for ( var i = 0; i < ranges.length; i++ ) {
                range = selection.getRanges()[ i ];

                // Skip bogus to cover cases of multiple selection inside tables (#tp2245).
                // Shrink to element to prevent losing anchor (#859).
                range.shrink( CKEDITOR.SHRINK_ELEMENT, true, { skipBogus: true } );
                link = editor.elementPath( range.getCommonAncestor() ).contains( 'a', 1 );

                if ( link && returnMultiple ) {
                    links.push( link );
                } else if ( link ) {
                    return link;
                }
            }

            return returnMultiple ? links : null;
        },

        /**
         * Determines whether an element should have a "Display Text" field in the Link dialog.
         *
         * @since 4.5.11
         * @param {CKEDITOR.dom.element/null} element Selected element, `null` if none selected or if a ranged selection
         * is made.
         * @param {CKEDITOR.editor} editor The editor instance for which the check is performed.
         * @returns {Boolean}
         */
        showDisplayTextForElement: function ( element, editor ) {
            var undesiredElements = {
                    img: 1,
                    table: 1,
                    tbody: 1,
                    thead: 1,
                    tfoot: 1,
                    input: 1,
                    select: 1,
                    textarea: 1
                },
                selection = editor.getSelection();

            // Widget duck typing, we don't want to show display text for widgets.
            if ( editor.widgets && editor.widgets.focused ) {
                return false;
            }

            if ( selection && selection.getRanges().length > 1 ) {
                return false;
            }

            return !element || !element.getName || !element.is( undesiredElements );
        }
    };

    CKEDITOR.unlinkCommand = function () {};
    CKEDITOR.unlinkCommand.prototype = {
        exec: function ( editor ) {
            // IE/Edge removes link from selection while executing "unlink" command when cursor
            // is right before/after link's text. Therefore whole link must be selected and the
            // position of cursor must be restored to its initial state after unlinking. (https://dev.ckeditor.com/ticket/13062)
            if ( CKEDITOR.env.ie ) {
                var range = editor.getSelection().getRanges()[ 0 ],
                    link = ( range.getPreviousEditableNode() && range.getPreviousEditableNode().getAscendant( 'a', true ) ) ||
                        ( range.getNextEditableNode() && range.getNextEditableNode().getAscendant( 'a', true ) ),
                    bookmark;

                if ( range.collapsed && link ) {
                    bookmark = range.createBookmark();
                    range.selectNodeContents( link );
                    range.select();
                }
            }

            var style = new CKEDITOR.style( { element: 'a', type: CKEDITOR.STYLE_INLINE, alwaysRemoveElement: 1 } );
            editor.removeStyle( style );

            if ( bookmark ) {
                range.moveToBookmark( bookmark );
                range.select();
            }
        },

        refresh: function ( editor, path ) {
            // Despite our initial hope, document.queryCommandEnabled() does not work
            // for this in Firefox. So we must detect the state by element paths.

            var element = path.lastElement && path.lastElement.getAscendant( 'a', true );

            if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) && element.getChildCount() ) {
                this.setState( CKEDITOR.TRISTATE_OFF );
            } else {
                this.setState( CKEDITOR.TRISTATE_DISABLED );
            }
        },

        contextSensitive: 1,
        startDisabled: 1,
        requiredContent: 'a[href]',
        editorFocus: 1
    };

} )();

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc