<commit_before>
angular.module('ui.tinymce.typehead', ['siyfion.sfTypeahead', 'ui.tinymce.typeahead.service', 'ui.tinymce.typehead.factory'])
  .value('uiTinymceTypeheadConfig', {})
  .directive('uiTinymceLinkerMenu', ['$timeout', 'typeaheadService', 'typeaheadFactory', function(timeout, service, factory) {

    return {
      template: '<div ng-show="showMenu">' +                  
                  '<ul class="dropdown-menu" style="display:block;position:absolute;z-index: 1070;top:{{top}}px;left:{{left}}px;width:300px">' +
                    '<li class="dropdown-header" ng-if="ariane && ariane.length > 0"><button class="btn btn-default btn-xs" ng-repeat="menu in ariane" href="#" ng-click="clickMenu(menu)">{{menu.label}}</button></li>' +
                    '<li ng-repeat="menu in menus"><a href="#" ng-click="clickMenu(menu)">' +
                      '<span ng-if="menu.icon" class="glyphicon {{menu.icon}}"></span> {{menu.label}}</a>' +                      
                    '</li>' +                  
                  '</ul>' +                                  
                  '<div ng-if="resultsDataset" style="display:block;position:absolute;z-index: 1070;top:{{top}}px;left:{{left}}px;width:350px" class="well btn-group-vertical">' + 
                    '<div class="dropdown-header text-center"><span class="label label-primary" ng-repeat="menu in ariane">{{menu.label}}</span></div>' +
                    '<div class="input-group">' +
                      '<input type="text" placeholder="Search..." class="form-control" sf-typeahead options="exampleOptions" datasets="resultsDataset" ng-model="selectedLink.result" style="width:270px">' +
                      '<span class="input-group-btn">' +
                        '<button type="button" class="btn btn-success" ng-click="select()"><span class="glyphicon glyphicon-plus"></span></button>' +
                        // '<button type="button" class="btn btn-success" ng-click="selectAdvanced()"><span class="glyphicon glyphicon-plus"></span>(options)</button>' + TODO
                      '</span>' +  
                      
                    '</div>' +
                  '</div>'+
                '<div>',  
      scope: {
        menus: '='
      },
      link: function (scope, elm, attrs) {   

        var isDefined = angular.isDefined;     

        if (!isDefined(attrs.menus)) {
          return;        
        }

        scope.selectedLink = {result: ''};

        // Typeahead options object
        scope.exampleOptions = {
          highlight: true
        };

        scope.originalMenu = angular.copy(scope.menus);  
        scope.ariane = [];      

        scope.clickMenu = function(menu) {          

          if (scope.ariane.indexOf(menu) < 0) {
            scope.ariane.push(menu);
          }  
          
          if (menu.children) {
              scope.showOptions = false;
              scope.showAutoComplete = false;
              scope.showMenu = true;
              scope.menus = menu.children;
              scope.activeMenuItem = undefined;
              scope.showAutoComplete = false;                      
          }
          else {            
            scope.activeMenuItem = menu;
            scope.label = menu.label;
            scope.showOptions = false;
            scope.showMenu = false;
            scope.showAutoComplete = true;
            scope.fetch();
          }          
        };

        scope.fetch = function() {

          if (scope.activeMenuItem.type === 'link') { 
            service.FetchLinks(scope.activeMenuItem, 'test').then(function(data) {              
              scope.resultsDataset = factory.GetResultDatasets(data);              
              scope.showMenu = true;            
            });

          }
          else if (scope.activeMenuItem.type === 'image') {

            service.FetchImageLinks(scope.activeMenuItem, 'test').then(function(data) {
              scope.resultsDataset = factory.GetResultDatasets(data);              
              scope.showMenu = true;              
            });

          }

        };

        scope.select = function(advanced) {                  
          var ed = tinymce.activeEditor; 
          var dom = ed.dom; 
          var html = ed.selection.getContent();

          var url = scope.selectedLink.result.url;
          var label = scope.selectedLink.result.label;          
          var noSelectionLinkAttrs = { target: '_blank', title: label, href: url };
           
          switch(scope.selectedLink.result.type) {
            // LINKS 
            case 'link':
              
              if (html) {
                tinymce.execCommand('mceInsertLink', false, url);
              }  
              else { 
                ed.insertContent(dom.createHTML('a', noSelectionLinkAttrs, dom.encode(noSelectionLinkAttrs.title)));
              }  

            break;
            // IMAGE 
            case 'image':              
              
              // http://stackoverflow.com/questions/5192134/how-to-insert-an-image-at-cursor-position-in-tinymce
              
              var range = ed.selection.getRng();                  // get range
              var newNode = ed.getDoc().createElement ( "img" );  // create img node
              newNode.src=url;                                    // add src attribute
              range.insertNode(newNode);

            break;


          }

          timeout(function() {
            ed.fire('SetContent');
          }, 3000);
              
          scope.showMenu = false;   
          scope.ariane = [];   
          scope.selectedLink = {result: ''};
          scope.menus = scope.originalMenu;  

        };

        scope.selectAdvanced = function() { 
          var url = scope.selectedLink.result.url;
          var label = scope.selectedLink.result.label;

          switch(scope.selectedLink.result.type) {
            // LINKS 
            case 'link':         
              var links = [{value:'_blank', link: url, title: label}];
                scope.showMenu = false;
                var tutu = tinymce.activeEditor.plugins.link.showDialog(links);                
            break;
            // IMAGE : TODO
            case 'image':         
              var noSelectionLinkAttrs = { target: '_blank', title: label, href: url };
              
              // http://stackoverflow.com/questions/5192134/how-to-insert-an-image-at-cursor-position-in-tinymce
              
              var range = ed.selection.getRng();                  // get range
              var newNode = ed.getDoc().createElement ( "img" );  // create img node
              newNode.src=url;                                    // add src attribute
              range.insertNode(newNode);
            break;
          }

          scope.showMenu = false;   
          scope.ariane = [];   
          scope.selectedLink = {result: ''};
          scope.menus = scope.originalMenu;

        };

        scope.initListeners = function() {
          // popup position
          scope.left = 0;
          scope.top= 0;

          // keys
          var ctrlDown = false;
          var ctrlKey = 17; // windows
          var cmdKey = 91; // mac
          var spaceKey = 32; // space
          // Select each item the user clicks on

          tinymce.on('AddEditor', function(e) {

            e.editor.on('click', function(e) {
              timeout(function() {
                scope.showMenu = false; 
                scope.ariane = [];
              });
            });

            e.editor.on('keydown', function(e) {                           

              // TODO: check wether still works on windows  
              if (e.keyCode === ctrlKey || e.ctrlKey || e.metaKey) {<commit_msg>verify tinymce plugins are loaded<commit_after>
angular.module('ui.tinymce.typehead', ['siyfion.sfTypeahead', 'ui.tinymce.typeahead.service', 'ui.tinymce.typehead.factory'])
  .value('uiTinymceTypeheadConfig', {})
  .directive('uiTinymceLinkerMenu', ['$timeout', 'typeaheadService', 'typeaheadFactory', function(timeout, service, factory) {

    return {
      template: '<div ng-show="showMenu">' +                  
                  '<ul class="dropdown-menu" style="display:block;position:absolute;z-index: 1070;top:{{top}}px;left:{{left}}px;width:300px">' +
                    '<li class="dropdown-header" ng-if="ariane && ariane.length > 0"><button class="btn btn-default btn-xs" ng-repeat="menu in ariane" href="#" ng-click="clickMenu(menu)">{{menu.label}}</button></li>' +
                    '<li ng-repeat="menu in menus"><a href="#" ng-click="clickMenu(menu)">' +
                      '<span ng-if="menu.icon" class="glyphicon {{menu.icon}}"></span> {{menu.label}}</a>' +                      
                    '</li>' +                  
                  '</ul>' +                                  
                  '<div ng-if="resultsDataset" style="display:block;position:absolute;z-index: 1070;top:{{top}}px;left:{{left}}px;width:350px" class="well btn-group-vertical">' + 
                    '<div class="dropdown-header text-center"><span class="label label-primary" ng-repeat="menu in ariane">{{menu.label}}</span></div>' +
                    '<div class="input-group">' +
                      '<input type="text" placeholder="Search..." class="form-control" sf-typeahead options="exampleOptions" datasets="resultsDataset" ng-model="selectedLink.result" style="width:270px">' +
                      '<span class="input-group-btn">' +
                        '<button type="button" class="btn btn-success" ng-click="select()"><span class="glyphicon glyphicon-plus"></span></button>' +
                        // '<button type="button" class="btn btn-success" ng-click="selectAdvanced()"><span class="glyphicon glyphicon-plus"></span>(options)</button>' + TODO
                      '</span>' +  
                      
                    '</div>' +
                  '</div>'+
                '<div>',  
      scope: {
        menus: '='
      },
      link: function (scope, elm, attrs) {   

        var isDefined = angular.isDefined;            

        if (!isDefined(attrs.menus)) {
          return;        
        }        

        scope.init = function() {
          scope.selectedLink = {result: ''};

          // Typeahead options object
          scope.exampleOptions = {
            highlight: true
          };

          scope.originalMenu = angular.copy(scope.menus);  
          scope.ariane = [];
        };        

        scope.clickMenu = function(menu) {          

          if (scope.ariane.indexOf(menu) < 0) {
            scope.ariane.push(menu);
          }  
          
          if (menu.children) {
              scope.showOptions = false;
              scope.showAutoComplete = false;
              scope.showMenu = true;
              scope.menus = menu.children;
              scope.activeMenuItem = undefined;
              scope.showAutoComplete = false;                      
          }
          else {            
            scope.activeMenuItem = menu;
            scope.label = menu.label;
            scope.showOptions = false;
            scope.showMenu = false;
            scope.showAutoComplete = true;
            scope.fetch();
          }          
        };

        scope.fetch = function() {

          if (scope.activeMenuItem.type === 'link') { 
            service.FetchLinks(scope.activeMenuItem, 'test').then(function(data) {              
              scope.resultsDataset = factory.GetResultDatasets(data);              
              scope.showMenu = true;            
            });

          }
          else if (scope.activeMenuItem.type === 'image') {

            service.FetchImageLinks(scope.activeMenuItem, 'test').then(function(data) {
              scope.resultsDataset = factory.GetResultDatasets(data);              
              scope.showMenu = true;              
            });

          }

        };

        scope.select = function(advanced) {                  
          var ed = tinymce.activeEditor; 
          var dom = ed.dom; 
          var html = ed.selection.getContent();

          var url = scope.selectedLink.result.url;
          var label = scope.selectedLink.result.label;          
          var noSelectionLinkAttrs = { target: '_blank', title: label, href: url };
           
          switch(scope.selectedLink.result.type) {
            // LINKS 
            case 'link':
              
              if (html) {
                tinymce.execCommand('mceInsertLink', false, url);
              }  
              else { 
                ed.insertContent(dom.createHTML('a', noSelectionLinkAttrs, dom.encode(noSelectionLinkAttrs.title)));
              }  

            break;
            // IMAGE 
            case 'image':              
              
              // http://stackoverflow.com/questions/5192134/how-to-insert-an-image-at-cursor-position-in-tinymce
              
              var range = ed.selection.getRng();                  // get range
              var newNode = ed.getDoc().createElement ( "img" );  // create img node
              newNode.src=url;                                    // add src attribute
              range.insertNode(newNode);

            break;


          }

          timeout(function() {
            ed.fire('SetContent');
          }, 3000);
              
          scope.showMenu = false;   
          scope.ariane = [];   
          scope.selectedLink = {result: ''};
          scope.menus = scope.originalMenu;  

        };

        scope.selectAdvanced = function() { 
          var url = scope.selectedLink.result.url;
          var label = scope.selectedLink.result.label;

          switch(scope.selectedLink.result.type) {
            // LINKS 
            case 'link':         
              var links = [{value:'_blank', link: url, title: label}];
                scope.showMenu = false;
                var tutu = tinymce.activeEditor.plugins.link.showDialog(links);                
            break;
            // IMAGE : TODO
            case 'image':         
              var noSelectionLinkAttrs = { target: '_blank', title: label, href: url };
              
              // http://stackoverflow.com/questions/5192134/how-to-insert-an-image-at-cursor-position-in-tinymce
              
              var range = ed.selection.getRng();                  // get range
              var newNode = ed.getDoc().createElement ( "img" );  // create img node
              newNode.src=url;                                    // add src attribute
              range.insertNode(newNode);
            break;
          }

          scope.showMenu = false;   
          scope.ariane = [];   
          scope.selectedLink = {result: ''};
          scope.menus = scope.originalMenu;

        };

        scope.initListeners = function() {
          // popup position
          scope.left = 0;
          scope.top= 0;

          // keys
          var ctrlDown = false;
          var ctrlKey = 17; // windows
          var cmdKey = 91; // mac
          var spaceKey = 32; // space          

          tinymce.on('AddEditor', function(e) {

            scope.linkPlugin = !!tinymce.AddOnManager.PluginManager.get('link');
            scope.pluginImage = !!tinymce.AddOnManager.PluginManager.get('image');

            if (!scope.linkPlugin && !scope.pluginImage)
              return;

            scope.init();

            e.editor.on('click', function(e) {
              timeout(function() {
                scope.showMenu = false; 
                scope.ariane = [];
              });
            });

            e.editor.on('keydown', function(e) {                           

              // TODO: check wether still works on windows  
              if (e.keyCode === ctrlKey || e.ctrlKey || e.metaKey) {
{'fraction_non_alphanumeric': 0.1305305557303795, 'fraction_numerical': 0.005664296053873749, 'mean_word_length': 1.4024795887511339, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2817209', 'n_tokens_mistral': 4312, 'n_tokens_neox': 4077, 'n_words': 722}