Site icon Blog ARC Optimizer

Résoudre les problèmes de copier-coller de liste Microsoft Word dans AEM RTE

Résoudre les problèmes de copier-coller de liste Microsoft Word dans AEM RTE


Notre client a soulevé un problème indiquant que la conversion de la liste ne se produisait pas correctement lors du copier-coller du texte de l’application de bureau MS Word vers RTE. Lors de mon exploration, j’ai découvert que le composant RTE dans AEM comporte principalement deux modes de collage (mothtml et texte en clair). Le mode texte brut supprime toutes les balises comme le nom du mode le suggère. Alors que « wordhtml » conserve les balises et fonctionne bien pour la plupart des balises. Mais lorsque les auteurs copient une liste (ordonnée/non ordonnée) à partir d’un document Microsoft Word (application de bureau) et essaient de la coller directement dans RTE, cela ne la colle pas bien.

Lors de l’implémentation d’OOTB, j’ai trouvé un commentaire dans EditToolsPlugin js indiquant ol et ul les balises ne sont pas prises en charge pour le moment (version actuelle d’AEM 6.5.23 et cloud) et par conséquent, en guise de solution de secours, elles créent des balises

individuelles avec un point (.) et 6 balises span au lieu de ul ou ol. Ainsi, la liste n’est pas actuellement convertie en

    ,
    et cela est clairement mentionné dans EditToolsPlugin js.

    EditToolsPlugin

    Cela conduit à des incohérences ainsi qu’à de la frustration si les auteurs tentent de le corriger de manière novice. Nous pouvons voir les étendues supplémentaires avec des points au lieu des balises ul/li lors du copier-coller vers rte depuis MsWord dans l’image ci-dessous.

    copier-coller vers RTE

    Examinons donc une solution qui atténue le problème discuté.

    Solution

    Dans le cadre de la solution, nous personnaliserons le code JavaScript du plugin OOTB où nous intercepterons l’opération de collage pour nettoyer le formatage MsWord et le changer en balises html

    /
    tout en préservant les autres balises comme ,,, etc., le cas échéant. L’opération de collage peut également être effectuée soit directement dans la zone de champ de texte RTE, soit via l’icône du plugin de collage. La gestion des deux scénarios est donc décrite ci-dessous.

    Étape 1 : Création de Clientlibs

    Créez un clientlibs pour limiter la portée de ce plugin personnalisé à RTE uniquement et ajoutez-le à la catégorie des propriétés client supplémentaires de la boîte de dialogue RTE, comme indiqué ci-dessous.

    bibliothèques client supplémentaires

    Étape 2 : Solution personnalisée

    Il est maintenant temps de remplacer (copier et coller) l’OOTB modifier le plug-in depuis /libs/clientlibs/granite/richtext/core/js/plugins/EditToolsPlugin.js à notre fichier clientlibs js (edit-tools-plugin-workaround-for-paste.js) créé à l’étape 1.

    Cherchons le APRÈS-PÂTE méthode et mettez la ligne ci-dessous comme affichée dans l’image.

    clipNode.innerHTML = convertWordListsToUL(clipNode.innerHTML);

    APRÈS-PÂTE

    Gardons toutes les lignes de convertWordListsToUL fonction de ce blog dans le dernier de edit-tools-plugin-workaround-for-paste.js qui transforme la liste de MS Word en balises

    /
    .

    ConvertWordListToUL

    function convertWordListsToUL(inputHtml) {
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = inputHtml;
    function cleanNode(node) {
    const comments = [];
    const walker = document.createTreeWalker(node, NodeFilter.SHOW_COMMENT, null);
    let comment;
    while (comment = walker.nextNode()) {
    comments.push(comment);
    }
    comments.forEach(comment => comment.parentNode.removeChild(comment));
    // Remove o:p tags
    const oTags = node.querySelectorAll('o\\:p');
    oTags.forEach(tag => tag.parentNode.removeChild(tag));
    return node;
    }
    function getListLevel(style) {
    if (!style) return 1;
    const levelMatch = style.match(/level(\d+)/i);
    return levelMatch ? parseInt(levelMatch[1], 10) : 1;
    }
    function getListType(bulletText) {
    if (!bulletText) return 'ul';
    const orderedPatterns = [
    /^\d+\.$/,        // 1., 2., 3.
    /^[a-z]\.$/i,     // a., b., c.
    /^[ivx]+\.$/i,    // i., ii., iii.
    /^\(\d+\)$/,      // (1), (2)
    /^\[\d+\]$/,      // [1], [2]
    /^[a-z]\)$/i,     // a), b)
    /^[ivx]+\)$/i,    // i), ii)
    /^\d+\)$/         // 1), 2)
    ];
    for (const pattern of orderedPatterns) {
    if (pattern.test(bulletText)) {
    return 'ol';
    }
    }
    return 'ul';
    }
    const root = document.createElement('div');
    const stack = [{ level: 0, element: root }];
    Array.from(tempDiv.children).forEach(node => {
    if (node.className.includes('MsoListParagraph')) {
    const style = node.getAttribute('style') || '';
    const currentLevel = getListLevel(style);
    const cleanedNode = cleanNode(node.cloneNode(true));
    let bulletText="";
    if (cleanedNode.firstElementChild) {
    bulletText = cleanedNode.firstElementChild.textContent.trim();
    cleanedNode.removeChild(cleanedNode.firstElementChild);
    }
    const listType = getListType(bulletText);
    // Pop stack until we find a parent level lower than current
    while (stack.length > 1 && stack[stack.length - 1].level >= currentLevel) {
    stack.pop();
    }
    const parent = stack[stack.length - 1].element;
    let listContainer = null;
    // Check if parent already has a list of the same type
    if (parent.lastElementChild &&
    parent.lastElementChild.tagName === listType.toUpperCase() &&
    // Only reuse list if we're at same level as last item
    (stack[stack.length - 1].level < currentLevel ||
    stack[stack.length - 1].level === currentLevel)) {
    listContainer = parent.lastElementChild;
    }
    // Check for adjacent list of different type
    else if (parent.lastElementChild &&
    (parent.lastElementChild.tagName === 'OL' ||
    parent.lastElementChild.tagName === 'UL') &&
    parent.lastElementChild.tagName !== listType.toUpperCase()) {
    listContainer = document.createElement(listType);
    parent.appendChild(listContainer);
    }
    else {
    listContainer = document.createElement(listType);
    parent.appendChild(listContainer);
    }
    const li = document.createElement('li');
    li.innerHTML = cleanedNode.innerHTML;
    listContainer.appendChild(li);
    stack.push({ level: currentLevel, element: li });
    } else {
    // Reset stack to root level for non-list items
    while (stack.length > 1) stack.pop();
    const cleanedNode = cleanNode(node.cloneNode(true));
    if (cleanedNode.textContent.trim() !== '') {
    root.appendChild(cleanedNode);
    }
    }
    });
    return root.innerHTML;
    }

    Enregistrer tout les changements pour le refléter correctement.

    Note: Veuillez trouver ci-joint outilsplugin.js et edit-tools-plugin-workaround-for-paste.js js pour référence, mais copiez-collez à partir du chemin spécifié dans votre instance AEM.

    Étape 3 : Configurez « wordhtml » comme mode de collage par défaut

    ModeColle par défaut

    Étape 4 : Facultativement, nous pouvons activer le plugin dans la barre d’outils elle-même, en configurant « coller en tant que wordhtml » plugin explicitement également si nécessaire.

    Accédez au nœud en ligne du composant de texte et activez le plugin de collage en ajoutant modifier#coller-wordhtml

    CollerPlugin

    Pour transformer automatiquement les balises de liste en ol/li, ajoutez le code ci-dessous au même fichier dans showPasteDialog fonctionner comme indiqué ci-dessous

    const iframe = document.querySelector('iframe[name^="rte-paste-html"]');
    if (iframe && iframe.contentWindow) {
       const iframeDocument = iframe.contentWindow.document;
       // Listen for the 'paste' event in the iframe's document
       iframeDocument.addEventListener('paste', function() {
       setTimeout(() => {
          const bodyContent = iframeDocument.querySelector('body');
          iframeDocument.body.innerHTML = convertWordListsToUL(bodyContent.innerHTML);
          }, 100);
       });
    }

    collerDialogue

    Résultats

    Félicitations! Il est temps de vérifier nos efforts en copiant-collant du texte de MS Word App vers RTE.

    Ici, nous pouvons clairement voir sur l’image ci-dessous qu’elle est convertie en

      /
    1. avec les balises d’ancrage requises en gras, italique, sous, le cas échéant.

      Liste de motsVers UL

      Conclusion

      Il s’agit d’une solution rapide qui offre de la flexibilité aux auteurs. Cependant, si nous optons pour cette approche, n’oubliez pas de garder un œil sur les notes de version lors de la mise à niveau du service pack ou de la mise à niveau automatique dans le cas du cloud AEM et supprimez ce fichier une fois corrigé par Adobe.

      J’espère que vous serez en mesure de résoudre de tels problèmes après avoir parcouru ce blog, n’hésitez pas à le personnaliser et à l’utiliser si nécessaire. Merci!

VOUS TROUVEZ CECI UTILE ? PARTAGEZ-LE






Source link
Quitter la version mobile