<commit_before>import { Behaviours } from "../../behaviours";
import { idiom } from "../../idiom";
import { $ } from '../../libs/jquery/jquery';
import { ui } from "../../ui";
import { http } from "../../http";
import { _ } from '../../libs/underscore/underscore';
import { model } from "../../modelDefinitions";
import { appPrefix } from "../../globals";
import { editorEvents } from "../../editor";

export const linker = {
    name: 'linker',
    run: function(instance){
        return {
            template: '<i ng-click="linker.openLinker()" tooltip="editor.option.link"></i>' +
            '<div ng-include="\'/infra/public/template/linker.html\'"></div>',
            link: function (scope, element, attributes) {
                ui.extendSelector.touchEvents('[contenteditable] a');
                scope.linker = {
                    display: {},
                    apps: [],
                    search: {
                        application: {},
                        text: ''
                    },
                    params: {},
                    resource: {}
                };

                instance.bindContextualMenu(scope, 'a', [
                    {
                        label: 'editor.edit.link',
                        action: function (e) {
                            instance.selection.selectNode(e.target);
                            scope.linker.display.chooseLink = true;
                            scope.linker.openLinker($(e.target).data('app-prefix'), $(e.target).attr('href'), e.target);
                        }

                    },
                    {
                        label: 'editor.remove.link',
                        action: function (e) {
                            var content = document.createTextNode($(e.target).text());
                            e.target.parentNode.insertBefore(content, e.target);
                            $(e.target).remove();
                        }
                    }
                ]);

                scope.linker.openLinker = function (appPrefix, address, element) {
                    var sel = window.getSelection();
                    instance.selection.range = sel.getRangeAt(0);
                    this.rangeCount = 1;
                    scope.linker.display.chooseLink = true;
                    if (appPrefix) {
                        scope.linker.search.application.address = '/' + appPrefix;
                        scope.linker.loadApplicationResources(function () {
                            scope.linker.searchApplication(function () {
                                var resource = _.findWhere(scope.linker.resources, { path: address });
                                scope.linker.applyResource(resource);
                                scope.$apply();
                            });
                        });
                    }
                    else {
                        if (!element && instance.selection.selectedElements.length === 1) {
                            element = instance.selection.selectedElements[0];
                        }
                        if (element) {
                            if (element.nodeType !== 1) {
                                element = element.parentNode;
                            }
                            if (element.nodeName === 'A') {
                                var link = $(element).attr('href');
                                scope.linker.params.blank = $(element).attr('target') === '_blank';
                                scope.linker.params.tooltip = $(element).attr('tooltip') || '';

                                if (link.split('http')[0] === '' && link.split('http').length > 1) {
                                    scope.linker.externalLink = true;
                                    scope.linker.params.link = link;
                                }
                                else {
                                    scope.linker.externalLink = false;
                                    scope.linker.openLinker(link.split('/')[1].split('#')[0], link);
                                }
                            }
                        }
                    }
                };

                scope.linker.loadApplicationResources = function(cb){
                    var split = scope.linker.search.application.address.split('/');
                    var prefix = split[split.length - 1];
                    scope.linker.params.appPrefix = prefix;
                    if(!cb){
                        cb = function(){
                            scope.linker.searchApplication();
                            scope.$apply('linker');
                        };
                    }
                    Behaviours.loadBehaviours(scope.linker.params.appPrefix, function (appBehaviour) {
                        const result = Behaviours.applicationsBehaviours[prefix].loadResources(() => cb(Behaviours.applicationsBehaviours[prefix].resources));
                        if(result && result.then){
                            result.then(() => {
                                cb(Behaviours.applicationsBehaviours[prefix].resources);
                            });
                        }
                        scope.linker.addResource = Behaviours.applicationsBehaviours[prefix].create;
                    });
                };

                scope.linker.searchApplication = function(cb){
                    var split = scope.linker.search.application.address.split('/');
                    var prefix = split[split.length - 1];
                    scope.linker.params.appPrefix = prefix;
                    Behaviours.loadBehaviours(scope.linker.params.appPrefix, function(appBehaviour){
                        scope.linker.resources = _.filter(appBehaviour.resources, function(resource) {
                            return scope.linker.search.text !== '' && (idiom.removeAccents(resource.title.toLowerCase()).indexOf(idiom.removeAccents(scope.linker.search.text).toLowerCase()) !== -1 ||
                                resource._id === scope.linker.search.text);
                        });
                        if(typeof cb === 'function'){
                            cb();
                        }
                    });
                };

                scope.linker.createResource = function(){
                    Behaviours.loadBehaviours(scope.linker.params.appPrefix, function(appBehaviour){
                        appBehaviour.create(scope.linker.resource, function(){
                            scope.linker.search.text = scope.linker.resource.title;
                            
                            scope.linker.searchApplication();
                            scope.$apply();
                        });
                    });
                };

                scope.linker.applyLink = function(link){
                    scope.linker.params.link = link;
                };

                scope.linker.applyResource = function(resource){
                    scope.linker.params.link = resource.path;
                    scope.linker.params.id = resource._id;
                };

                scope.linker.saveLink = function(){
                    if(scope.linker.params.blank){
                        scope.linker.params.target = '_blank';
                    }

                    var linkNode;
                    var selectedNode = instance.selection.range.startContainer;
                    if (selectedNode && selectedNode.nodeType !== 1
                        && selectedNode.parentNode.childNodes.length === 1
                        && instance.selection.range.startOffset === 0
                        && instance.selection.range.endOffset === selectedNode.textContent.length) {
                        selectedNode = selectedNode.parentNode;
                    }
                    if (selectedNode && selectedNode.nodeName === 'A') {
                        linkNode = $(selectedNode);
                    }
                    else {
                        linkNode = $('<a></a>');
                    }

                    if(scope.linker.params.link){
                        let matcher = new RegExp('^www');
                        let linkToCheck = scope.linker.params.link.match(matcher);
                        let protocolToAdd = 'http://';
                        if(linkToCheck === null) {
                            linkNode.attr('href', scope.linker.params.link);
                        } else if(linkToCheck[0] == 'www') {
                            let finalUrl = protocolToAdd.concat(scope.linker.params.link.toString());
                            linkNode.attr('href', finalUrl);
                        }

                        if (scope.linker.params.appPrefix && !scope.linker.externalLink) {
                            linkNode.attr('data-app-prefix', scope.linker.params.appPrefix);
                            if(scope.linker.params.appPrefix !== 'workspace' && !scope.linker.externalLink){
                                linkNode.data('reload', true);
                            }
                        }
                        if(scope.linker.params.id){
                            linkNode.attr('data-id', scope.linker.params.id);
                        }
                        if(scope.linker.params.blank){
                            scope.linker.params.target = '_blank';
                            linkNode.attr('target', scope.linker.params.target);
                        }
                        if(scope.linker.params.tooltip){
                            linkNode.attr('tooltip', scope.linker.params.tooltip);
                        }
                        else if(linkNode.attr('tooltip')){
                            linkNode.removeAttr('tooltip');
                            linkNode.off('mouseover');
                        }
                        editorEvents.onLinkerAdd.next({
                            externalLink: scope.linker.externalLink,<commit_msg>Fix http:// link to https:// in linker<commit_after>import { Behaviours } from "../../behaviours";
import { idiom } from "../../idiom";
import { $ } from '../../libs/jquery/jquery';
import { ui } from "../../ui";
import { http } from "../../http";
import { _ } from '../../libs/underscore/underscore';
import { model } from "../../modelDefinitions";
import { appPrefix } from "../../globals";
import { editorEvents } from "../../editor";

export const linker = {
    name: 'linker',
    run: function(instance){
        return {
            template: '<i ng-click="linker.openLinker()" tooltip="editor.option.link"></i>' +
            '<div ng-include="\'/infra/public/template/linker.html\'"></div>',
            link: function (scope, element, attributes) {
                ui.extendSelector.touchEvents('[contenteditable] a');
                scope.linker = {
                    display: {},
                    apps: [],
                    search: {
                        application: {},
                        text: ''
                    },
                    params: {},
                    resource: {}
                };

                instance.bindContextualMenu(scope, 'a', [
                    {
                        label: 'editor.edit.link',
                        action: function (e) {
                            instance.selection.selectNode(e.target);
                            scope.linker.display.chooseLink = true;
                            scope.linker.openLinker($(e.target).data('app-prefix'), $(e.target).attr('href'), e.target);
                        }

                    },
                    {
                        label: 'editor.remove.link',
                        action: function (e) {
                            var content = document.createTextNode($(e.target).text());
                            e.target.parentNode.insertBefore(content, e.target);
                            $(e.target).remove();
                        }
                    }
                ]);

                scope.linker.openLinker = function (appPrefix, address, element) {
                    var sel = window.getSelection();
                    instance.selection.range = sel.getRangeAt(0);
                    this.rangeCount = 1;
                    scope.linker.display.chooseLink = true;
                    if (appPrefix) {
                        scope.linker.search.application.address = '/' + appPrefix;
                        scope.linker.loadApplicationResources(function () {
                            scope.linker.searchApplication(function () {
                                var resource = _.findWhere(scope.linker.resources, { path: address });
                                scope.linker.applyResource(resource);
                                scope.$apply();
                            });
                        });
                    }
                    else {
                        if (!element && instance.selection.selectedElements.length === 1) {
                            element = instance.selection.selectedElements[0];
                        }
                        if (element) {
                            if (element.nodeType !== 1) {
                                element = element.parentNode;
                            }
                            if (element.nodeName === 'A') {
                                var link = $(element).attr('href');
                                scope.linker.params.blank = $(element).attr('target') === '_blank';
                                scope.linker.params.tooltip = $(element).attr('tooltip') || '';

                                if (link.split('http')[0] === '' && link.split('http').length > 1) {
                                    scope.linker.externalLink = true;
                                    scope.linker.params.link = link;
                                }
                                else {
                                    scope.linker.externalLink = false;
                                    scope.linker.openLinker(link.split('/')[1].split('#')[0], link);
                                }
                            }
                        }
                    }
                };

                scope.linker.loadApplicationResources = function(cb){
                    var split = scope.linker.search.application.address.split('/');
                    var prefix = split[split.length - 1];
                    scope.linker.params.appPrefix = prefix;
                    if(!cb){
                        cb = function(){
                            scope.linker.searchApplication();
                            scope.$apply('linker');
                        };
                    }
                    Behaviours.loadBehaviours(scope.linker.params.appPrefix, function (appBehaviour) {
                        const result = Behaviours.applicationsBehaviours[prefix].loadResources(() => cb(Behaviours.applicationsBehaviours[prefix].resources));
                        if(result && result.then){
                            result.then(() => {
                                cb(Behaviours.applicationsBehaviours[prefix].resources);
                            });
                        }
                        scope.linker.addResource = Behaviours.applicationsBehaviours[prefix].create;
                    });
                };

                scope.linker.searchApplication = function(cb){
                    var split = scope.linker.search.application.address.split('/');
                    var prefix = split[split.length - 1];
                    scope.linker.params.appPrefix = prefix;
                    Behaviours.loadBehaviours(scope.linker.params.appPrefix, function(appBehaviour){
                        scope.linker.resources = _.filter(appBehaviour.resources, function(resource) {
                            return scope.linker.search.text !== '' && (idiom.removeAccents(resource.title.toLowerCase()).indexOf(idiom.removeAccents(scope.linker.search.text).toLowerCase()) !== -1 ||
                                resource._id === scope.linker.search.text);
                        });
                        if(typeof cb === 'function'){
                            cb();
                        }
                    });
                };

                scope.linker.createResource = function(){
                    Behaviours.loadBehaviours(scope.linker.params.appPrefix, function(appBehaviour){
                        appBehaviour.create(scope.linker.resource, function(){
                            scope.linker.search.text = scope.linker.resource.title;
                            
                            scope.linker.searchApplication();
                            scope.$apply();
                        });
                    });
                };

                scope.linker.applyLink = function(link){
                    scope.linker.params.link = link;
                };

                scope.linker.applyResource = function(resource){
                    scope.linker.params.link = resource.path;
                    scope.linker.params.id = resource._id;
                };

                scope.linker.saveLink = function(){
                    if(scope.linker.params.blank){
                        scope.linker.params.target = '_blank';
                    }

                    var linkNode;
                    var selectedNode = instance.selection.range.startContainer;
                    if (selectedNode && selectedNode.nodeType !== 1
                        && selectedNode.parentNode.childNodes.length === 1
                        && instance.selection.range.startOffset === 0
                        && instance.selection.range.endOffset === selectedNode.textContent.length) {
                        selectedNode = selectedNode.parentNode;
                    }
                    if (selectedNode && selectedNode.nodeName === 'A') {
                        linkNode = $(selectedNode);
                    }
                    else {
                        linkNode = $('<a></a>');
                    }

                    if(scope.linker.params.link){
                        let matcher = new RegExp('^www');
                        let linkToCheck = scope.linker.params.link.match(matcher);
                        let protocolToAdd = 'https://';
                        if(linkToCheck === null) {
                            linkNode.attr('href', scope.linker.params.link);
                        } else if(linkToCheck[0] == 'www') {
                            let finalUrl = protocolToAdd.concat(scope.linker.params.link.toString());
                            linkNode.attr('href', finalUrl);
                        }

                        if (scope.linker.params.appPrefix && !scope.linker.externalLink) {
                            linkNode.attr('data-app-prefix', scope.linker.params.appPrefix);
                            if(scope.linker.params.appPrefix !== 'workspace' && !scope.linker.externalLink){
                                linkNode.data('reload', true);
                            }
                        }
                        if(scope.linker.params.id){
                            linkNode.attr('data-id', scope.linker.params.id);
                        }
                        if(scope.linker.params.blank){
                            scope.linker.params.target = '_blank';
                            linkNode.attr('target', scope.linker.params.target);
                        }
                        if(scope.linker.params.tooltip){
                            linkNode.attr('tooltip', scope.linker.params.tooltip);
                        }
                        else if(linkNode.attr('tooltip')){
                            linkNode.removeAttr('tooltip');
                            linkNode.off('mouseover');
                        }
                        editorEvents.onLinkerAdd.next({
                            externalLink: scope.linker.externalLink,
{'fraction_non_alphanumeric': 0.11564828614008942, 'fraction_numerical': 0.0015896671634376552, 'mean_word_length': 1.0274952160338402, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5263616', 'n_tokens_mistral': 4662, 'n_tokens_neox': 4360, 'n_words': 623}