IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Editeur de code intégré avec coloration syntaxique


Sujet :

JavaScript

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 78
    Points : 48
    Points
    48
    Par défaut Editeur de code intégré avec coloration syntaxique
    Bonjour à tous,

    Pour une projet j'ai besoin de développer un éditeur de code (dans l'exemple suivant du code SQL) avec une coloration syntaxique.

    En cherchant un peut sur le net j'ai trouver une librairie qui fait plutôt bien le boulot pour la coloration : highlight.js

    Voici le code qui permet la coloration (j'utilise le framework prototype.js. Pour info $('aa') est équivalent à document.getElementById('aa') et la méthode update(...) équivaut à un .innerHTML= ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <pre class="code" id="aa" contenteditable="true" onKeyUp="test();">
    select filed1, field2
    from table
    where blablabla
    group by filed2
    </pre>
     
    <script>
    $('aa').update(hljs.highlight('sql', $('aa').innerHTML).value);
    <script>
    Jusque la pas de souci le code se colore correctement c'est même bien sympathique.

    comme vous avez pu le voir, dans ma balise <pre> j'ai un attribut contenteditable="true" qui est le seul moyen de mettre en forme un texte éditable d'après ce que j'ai pu voir.

    Mon problème est donc le suivant : Lorsque je rajoute une lettre dans mon code, je récupère la position du curseur, je fait un striptags pour supprimer la mise en forme, je rapplique la coloration mais je n'arrive pas a repositionner le curseur au bon endroit. j'ai cherché pendant des heures sans résultat.

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //Fonction que j'ai trouvé sur un forum mais j'ai bien peur de ne pas bien la comprendre :
    function getCharacterOffsetWithin(range, node) {
        var treeWalker = document.createTreeWalker(
            node,
            NodeFilter.SHOW_TEXT,
            function(node) {
                var nodeRange = document.createRange();
                nodeRange.selectNode(node);
                return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ?
                    NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
            },
            false
        );
     
        var charCount = 0;
        while (treeWalker.nextNode()) {
            charCount += treeWalker.currentNode.length;
        }
        if (range.startContainer.nodeType == 3) {
            charCount += range.startOffset;
        }
        return charCount;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //Fonction appelée onKeyUp sur le <pre>
    function test(){
    	position = getCharacterOffsetWithin(window.getSelection().getRangeAt(0), $('aa')); //Récupération de la position du curseur
    	$('aa').update(hljs.highlight('sql', $('aa').innerHTML.stripTagsSecific('span')).value); // Mise à jour du champ pour relancer la coloration
    	//Pour le moment, le curseur se repositionne au début de mon champ éditable. impossible de me replacer au bon endroit
    }

    Voila j'espère avoir été clair et que quelqu'un pourra venir à mon aide.

  2. #2
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Ce n'est pas simple et je n'ai pas la solution
    Mais il existe sûrement des librairies d'éditeurs de code Javascript qui intègrent highlight.js ou un autre coloreur syntaxique (mon préféré est http://craig.is/making/rainbows)
    One Web to rule them all

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 78
    Points : 48
    Points
    48
    Par défaut
    Justement j'ai pas mal cherché, j'ai trouvé un bon paquet de librairie de coloration syntaxique mais rien pour créer une sorte d'éditeur :s

    En plus comme je l'ai expliqué dans mon premier message j'ai vraiment l'impression de toucher la solution du doigt il faut juste que j'arrive à replacer le curseur au bon endroit mais j'ai testé plein de truc sans succès :s.

    Si quelqu'un avait une solution à me proposé ça serait vraiment génial ... ou si une librairie existe je suis preneur aussi.

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    on avait plus ou moins abordé le sujet sur http://www.developpez.net/forums/d10...nput-tabindex/

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 78
    Points : 48
    Points
    48
    Par défaut
    Bonjour NoSmoking,

    Si j'ai bien compris le lien que tu m'as mis, ce post parle de position de curseur dans un champs input ou textarea.

    Mon problème est tout autre : j'ai un élément <pre> avec un attribut contenteditable="true". La position du curseur ne fonctionne pas du tout de la même manière

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Oui effectivement, tu peux partir sur cette base, sachant que le problème sera plus complexe lié à la présence de noeuds.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <!DOCTYPE html>
    <html lang="fr">
    <head>
    <meta charset="UTF-8">
    <title>[...]</title>
    <meta content="NoSmoking" name="Author">
    </head>
    <body>
    <div id="id_div" contenteditable="true">Du texte à modifier</div>
    <script>
    function setCursorPosition( id, pos){
      var oRange  = document.createRange();
      var oEdit   = document.getElementById( id);
      var oSelect = window.getSelection();
      // l'element doit avoir le focus
      oEdit.focus();
      // cree une selection
      oRange.setStart( oEdit.firstChild, pos -1);
      oRange.setEnd  ( oEdit.firstChild, pos);
      // ajout la selection
      oSelect.addRange(oRange);
      // deplace en fin de selection
      oSelect.collapseToEnd();
    }
    setCursorPosition( 'id_div', 6)
    </script>
    </body>
    </html>

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 78
    Points : 48
    Points
    48
    Par défaut
    je l'ai pas essayé mais je pense que cette solution poserait problème dans mon cas à cause de la coloration syntaxique (ajout de span et donc de noeuds).

    J'ai finit par trouvé une solution ... C'est de la grosse bidouille et ça peut surement être optimisé mais au moins ça fonctionne.

    Vu qu'après moulte recherche sur google j'ai pas trouvé de script pour faire ça du coup je vous met mon code ici.
    Attention j'utilise le framwork prototype donc ce code sera peut être à modifier légèrement si vous utilisez un autre framwork ou que vous n'en utilisez pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    <html>
    <head>
    <link href="highlight.js/styles/idea.css" rel="stylesheet" type="text/css" />
     
    <script type="text/javascript" src="highlight.js/highlight.pack.js"></script>
    <script type="text/javascript" src="prototype.js"></script>
    <script>
     
     
    //Fonction que j'ai trouvé sur un forum mais j'ai bien peur de ne pas bien la comprendre :
    function getCharacterOffsetWithin(range, node) {
        var treeWalker = document.createTreeWalker(
            node,
            NodeFilter.SHOW_TEXT,
            function(node) {
                var nodeRange = document.createRange();
                nodeRange.selectNode(node);
                return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ?
                    NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
            },
            false
        );
     
        var charCount = 0;
        while (treeWalker.nextNode()) {
            charCount += treeWalker.currentNode.length;
        }
        if (range.startContainer.nodeType == 3) {
            charCount += range.startOffset;
        }
        return charCount;
    }
     
    //Fonction appelée onKeyUp sur le <pre>
    function test(){
    	position = getCharacterOffsetWithin(window.getSelection().getRangeAt(0), $('aa'));
    	$('aa').update(hljs.highlight('sql', $('aa').innerHTML.stripTags()).value); 
    	setPosition(window.getSelection().getRangeAt(0), $('aa'), position);
    }
     
    //Fonction getCharacterOffsetWithin que j'ai bidouiller pour faire ce que je voulait ;) mais je comprend tjr par comment elle fonctionne.
    function setPosition(range, node, position) {
        var treeWalker = document.createTreeWalker(
            node,
            NodeFilter.SHOW_TEXT,
            function(node) {
                var nodeRange = document.createRange();
                nodeRange.selectNode(node);
                return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ?
                //    NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
    				1 : 1;
            },
            false
        );
     
        var charCount = 0;
        while (treeWalker.nextNode()) {
            charCount += treeWalker.currentNode.length;
    		if(charCount > position){
    			stratChar = (charCount - treeWalker.currentNode.length);
    			position = position - stratChar;
    			var range = document.createRange();
    			range.setStart(treeWalker.currentNode, position);
    			range.setEnd(treeWalker.currentNode, position);
    			var sel = window.getSelection();
    			sel.removeAllRanges();
    			sel.addRange(range);
     
    			return;	
    		}
        }
        if (range.startContainer.nodeType == 3) {
            charCount += range.startOffset;
        }
        return charCount;
    }
     
    </script>
    </head>
    <body>
    <pre class="code" id="aa" contenteditable="true" onKeyUp="test();">
    select filed1, field2
    from table
    where blablabla = "eee"
    group by filed2
    </pre>
     
    <script>
    $('aa').update(hljs.highlight('sql', $('aa').innerHTML).value);
    </script>
     
    </body></html>

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Affichage de code Java avec coloration syntaxique
    Par sheep_one dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 09/06/2014, 17h16
  2. Réponses: 21
    Dernier message: 27/04/2013, 17h27
  3. Exportation du Code Source Avec Coloration Syntaxique en HTML
    Par hackoofr dans le forum Vos Contributions VBScript
    Réponses: 1
    Dernier message: 22/02/2013, 05h58
  4. Réponses: 2
    Dernier message: 09/02/2010, 16h08
  5. Editeur avec coloration syntaxique
    Par LeGilou dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 01/11/2008, 10h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo