> vOffsetTR) { //ce rowSpan intersecte bien notre TR var vColSpan = parseInt(vPrevTD.getAttribute("colSpan"), 10) || 1; for (var i = 0; vCol && i < vColSpan; i++) { vCol = vCol.previousSibling; while(vCol && vCol.nodeName != "COL") vCol = vCol.previousSibling; } if(!vCol) break scanRowSpan; } vPrevTD = vPrevTD.nextElementSibling; } var vPrevTR = vPrevTR.previousSibling; while(vPrevTR && vPrevTR.nodeName != "TR") vPrevTR = vPrevTR.previousSibling; vOffsetTR++; } break; } while(vCol && !vTd) { //Il y un trou on ajoute des cellules var vNewTD = vDoc.createElement("td"); if(pInTransaction) { this.insertElt(vNewTD, vNode, null); } else { vNode.appendChild(vNewTD); } this.setDefaultRole(vNewTD, this.fClasses.TD); vCol = vCol.previousSibling; while(vCol && vCol.nodeName != "COL") vCol = vCol.previousSibling; } while(!vCol && vTd) { //TODO Il y a trop de TD, que faire ? break; } break; case "DIR" : case "UL" : case "OL" : if(vClass.hasTitle(vNode)) { var vTitle = vNode.firstElementChild; if(! vTitle || vTitle.nodeName != "TITLE") { vTitle = vDoc.createElement("title"); if(pInTransaction) { this.insertElt(vTitle, vNode, vNode.firstChild); } else { vNode.insertBefore(vTitle, vNode.firstChild); } } } var vItemName = vNode.nodeName=="DIR" ? "MEMBER": "LITEM"; var vItem = vNode.lastElementChild; if(!vItem || vItem.nodeName != vItemName) { //On ajoute au moins un item. var vLi = vDoc.createElement(vItemName); if(pInTransaction) { this.insertElt(vLi, vNode, null); } else { vNode.insertBefore(vLi, null); } } break; case "EXTBLOCK" : var vCaption = vNode.firstElementChild; if(vClass.hasCaption(vNode) && (! vCaption || vCaption.nodeName != "CAPTIONBLOCK") ) { vCaption = vDoc.createElement("captionBlock"); if(pInTransaction) { this.insertElt(vCaption, vNode, vNode.firstChild); } else { vNode.insertBefore(vCaption, vNode.firstChild); } } break; } } if(vNode.hasChildNodes()) { vNode = vNode.firstChild; continue; } break; case 5 : case 7 : //Blocks de paragraphes if( ! vNode.hasChildNodes() || vNode.lastChild.nodeName!="BR") { if(pInTransaction) { this.insertElt(vDoc.createElement("BR"), vNode, null); } else { vNode.appendChild(vDoc.createElement("BR")); } } break; } if(vNode == pHtmlRoot) return; while(! vNode.nextSibling) { vNode = vNode.parentNode; if(vNode == pHtmlRoot) return; } vNode = vNode.nextSibling; } ]]> "+vParentClass.isChildAllowed(vHtmlNode, pClass)); if(vParentClass.isChildAllowed(vHtmlNode, pClass) && pClass.isDefined(pXmlNode) && ! vParentClass.isDescForbidden(vHtmlNode, pClass, pXmlNode.getAttribute("role"))) return true; vZone.warnTagsUnknown(); vStackJumpXmlNode[vStackJumpXmlNode.length-1] = true; return false; } /** Valide un tag dont le role est remplacé par celui par défaut si non autorisé. * Si cette balise n'est pas autorisé dutout, */ function validRoleTag(pHtmlNode, pClass){ //xed.debug("validRoleTag parent: "+vHtmlNode.nodeName+" - "+pHtmlNode.nodeName+" --> "+vParentClass.isChildAllowed(vHtmlNode, pClass)); if(!vParentClass.isChildAllowed(vHtmlNode, pClass)) { vStackJumpXmlNode[vStackJumpXmlNode.length-1] = true; vZone.warnTagsUnknown(); return null; } if(pClass.isDefined(pHtmlNode, vHtmlNode) && ! vParentClass.isDescForbidden(vHtmlNode, pClass, pHtmlNode.getAttribute("role"))) return pHtmlNode; vZone.warnTagsUnknown(); var vRole = pClass.getDefaultRole(pHtmlNode, vHtmlNode); if(vRole==null) { vStackJumpXmlNode[vStackJumpXmlNode.length-1] = true; return null; } if(vRole) pHtmlNode.setAttribute("role", vRole); else pHtmlNode.removeAttribute("role"); return pHtmlNode; } function treatMetaForLeafTag(pHtmlNode) { var vXmlMeta = vXmlNode.firstElementChild; if(!vXmlMeta) return; if(vXmlMeta.namespaceURI!="http://www.utc.fr/ics/scenari/v3/core") { //Traitement des meta var vStructNode = vZone.fClasses[pHtmlNode.nodeName].getStructuralNodes(pHtmlNode); if(vStructNode.hasSubEditor) { vZone.loadMeta(pHtmlNode, vXmlMeta); } else { //meta non autorisé ici, erreur. vZone.warnTagsUnknown(); } } else { //balise non autorisée. vZone.warnTagsUnknown(); } } while(vXmlNode) { //xed.debug("vXmlNode::"+vXmlNode); if(vXmlNode.nodeType == 1) { var vHtmlChild = null; var vStopChildren = false; if(vXmlNode.namespaceURI!="http://www.utc.fr/ics/scenari/v3/core") { //xed.debug("vXmlNode:::"+vXmlNode.namespaceURI+"|"+vXmlNode.localName); //Traitement des meta if(vHtmlNode.getUserData("meta")!=null) { //meta déjà renseigné, erreur. this.warnTagsUnknown(); } else { var vStructNode = this.fClasses[vHtmlNode.nodeName].getStructuralNodes(vHtmlNode); if(vStructNode.hasSubEditor) { this.loadMeta(vHtmlNode, vXmlNode); } else { //meta non autorisé ici, erreur. this.warnTagsUnknown(); } } vStopChildren = true; } else { //Balise "sc:" switch(vXmlNode.localName){ // #### Balises paragraphes #### case "para" : case "member" : //case "variableList" : //case "varListEntry" : //case "term" : if(validOptTag(vXmlNode, this.fClasses._xml[vXmlNode.localName])) { vHtmlChild = fctCreateElt.call(vHtmlDoc, vXmlNode.localName); copyAtts(vXmlNode, vHtmlChild); } break; case "simpleList" : vHtmlChild = fctCreateElt.call(vHtmlDoc, "dir"); copyAtts(vXmlNode, vHtmlChild); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.DIR); break; case "itemizedList" : vHtmlChild = fctCreateElt.call(vHtmlDoc, "ul"); copyAtts(vXmlNode, vHtmlChild); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.UL); break; case "orderedList" : vHtmlChild = fctCreateElt.call(vHtmlDoc, "ol"); copyAtts(vXmlNode, vHtmlChild); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.OL); break; case "listItem" : if(validOptTag(vXmlNode, this.fClasses.LITEM)) { var vNodeName = "litem"; /* if(vXmlNode.parentNode != null && vXmlNode.parentNode.nodeType==1) { if(vXmlNode.parentNode.localName=="varListEntry") { vNodeName = "varListItem"; } } else if(vHtmlNode.parentNode != null) { //Cas d'un copie avec un listitem en racine. if(vHtmlNode.parentNode.localName=="VARLISTENTRY") { vNodeName = "varListItem"; } } */ vHtmlChild = fctCreateElt.call(vHtmlDoc, vNodeName); copyAtts(vXmlNode, vHtmlChild); } break; case "title" : if(validOptTag(vXmlNode, this.fClasses.TITLE)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, vXmlNode.localName); copyAtts(vXmlNode, vHtmlChild); } break; case "table" : vHtmlChild = fctCreateElt.call(vHtmlDoc, vXmlNode.localName); copyAtts(vXmlNode, vHtmlChild); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.TABLE); break; case "caption" : if(validOptTag(vXmlNode, this.fClasses.CAPTION)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, vXmlNode.localName); copyAtts(vXmlNode, vHtmlChild); } break; case "column" : vHtmlChild = fctCreateElt.call(vHtmlDoc, "col"); copyAtts(vXmlNode, vHtmlChild); var vW = vXmlNode.getAttribute("width") || 50; vHtmlChild.setAttribute("width", this.computeTDWidthFromScWidth(vW)); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.COL); vStopChildren = true; break; case "row" : vHtmlChild = fctCreateElt.call(vHtmlDoc, "tr"); copyAtts(vXmlNode, vHtmlChild); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.TR); break; case "cell" : vHtmlChild = fctCreateElt.call(vHtmlDoc, "td"); copyAtts(vXmlNode, vHtmlChild); var vVal = vXmlNode.getAttribute("rowSpan"); if(vVal) vHtmlChild.setAttribute("rowSpan", vVal); vVal = vXmlNode.getAttribute("colSpan"); if(vVal) vHtmlChild.setAttribute("colSpan", vVal); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.TD); break; case "extBlock" : vHtmlChild = fctCreateElt.call(vHtmlDoc, vXmlNode.localName); copyAtts(vXmlNode, vHtmlChild); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.EXTBLOCK); if(vHtmlChild) { var vRefUri = vXmlNode.getAttributeNS(SCNS, "refUri"); vHtmlChild.setAttribute("refUri", vRefUri); //this.loadExtBlock(vHtmlChild, vRefUri); traité en asynchrone lorsque l'iframe est chargée (event ScText_init). } break; case "captionBlock" : if(validOptTag(vXmlNode, this.fClasses.CAPTIONBLOCK)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, vXmlNode.localName); copyAtts(vXmlNode, vHtmlChild); } break; case "emptyBlock" : vHtmlChild = fctCreateElt.call(vHtmlDoc, vXmlNode.localName); copyAtts(vXmlNode, vHtmlChild); vHtmlChild = validRoleTag(vHtmlChild, this.fClasses.EMPTYBLOCK); break; // #### Balises inlines #### case "phrase" : if(validOptTag(vXmlNode, this.fClasses.PHRASE)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, "phrase"); copyAtts(vXmlNode, vHtmlChild); if( ! vXmlNode.hasChildNodes()) vHtmlChild.appendChild(vHtmlDoc.createTextNode("")); } break; case "inlineStyle" : if(validOptTag(vXmlNode, this.fClasses.INLINESTYLE)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, "inlineStyle"); copyAtts(vXmlNode, vHtmlChild); if( ! vXmlNode.hasChildNodes()) vHtmlChild.appendChild(vHtmlDoc.createTextNode("")); } break; case "textLeaf" : if(validOptTag(vXmlNode, this.fClasses.TEXTLEAF)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, "textLeaf"); copyAtts(vXmlNode, vHtmlChild); if( ! vXmlNode.hasChildNodes()) vHtmlChild.appendChild(vHtmlDoc.createTextNode("")); } break; case "uLink" : if(validOptTag(vXmlNode, this.fClasses.ULINK)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, "uLink"); copyAtts(vXmlNode, vHtmlChild); if(vXmlNode.hasAttribute("url")) { vHtmlChild.setAttribute("url", vXmlNode.getAttribute("url")); } else { var vRefUri = vXmlNode.getAttributeNS(SCNS, "refUri"); vHtmlChild.setAttribute("refUri", vRefUri); this.loadULink(vHtmlChild, vRefUri); } if( ! vXmlNode.hasChildNodes()) vHtmlChild.appendChild(vHtmlDoc.createTextNode("")); } break; case "inlineImg" : if(validOptTag(vXmlNode, this.fClasses.IMG)) { var vIcon = fctCreateElt.call(vHtmlDoc, "img"); copyAtts(vXmlNode, vIcon); var vRefUri = vXmlNode.getAttributeNS(SCNS, "refUri"); vIcon.setAttribute("refUri", vRefUri); this.loadInlineImg(vIcon, vRefUri); //vIcon.setAttribute("src", vRefUri)); var vCh = vXmlNode.firstChild; var vText = ""; while(vCh) { if(vCh.nodeType == 3 || vXmlNode.nodeType == 4) vText += vCh.nodeValue; vCh = vCh.nextSibling; } if(vText) vIcon.setAttribute("text", vText); vHtmlNode.appendChild(vIcon); treatMetaForLeafTag(vIcon); } vStopChildren = true; break; case "objectLeaf" : if(validOptTag(vXmlNode, this.fClasses.OBJECTLEAF)) { var vObject = fctCreateElt.call(vHtmlDoc, "objectLeaf"); copyAtts(vXmlNode, vObject); var vRefUri = vXmlNode.getAttributeNS(SCNS, "refUri"); vObject.setAttribute("refUri", vRefUri); this.loadObjectLeaf(vObject, vRefUri); vHtmlNode.appendChild(vObject); treatMetaForLeafTag(vObject); } vStopChildren = true; break; case "emptyLeaf" : if(validOptTag(vXmlNode, this.fClasses.EMPTYLEAF)) { var vObject = fctCreateElt.call(vHtmlDoc, "emptyLeaf"); copyAtts(vXmlNode, vObject); vHtmlNode.appendChild(vObject); treatMetaForLeafTag(vObject); } vStopChildren = true; break; case "note" : if(validOptTag(vXmlNode, this.fClasses.NOTE)) { vHtmlChild = fctCreateElt.call(vHtmlDoc, "note"); copyAtts(vXmlNode, vHtmlChild); this.loadNote(vHtmlChild, vXmlNode); vHtmlNode.appendChild(vHtmlChild); vHtmlChild = null; } vStopChildren = true; break; default : try{this.warnTagsUnknown();}catch(e){}; vStopChildren = true; } } if ( ! vStopChildren) { if(vXmlNode.hasChildNodes()){ vXmlNode = vXmlNode.firstChild; vStackJumpXmlNode[vStackJumpXmlNode.length] = false; if(vHtmlChild) { vHtmlNode = vHtmlNode.appendChild(vHtmlChild); vParentClass = this.fClasses[vHtmlNode.nodeName]; } continue; } else { if(vHtmlChild) vHtmlNode.appendChild(vHtmlChild); } } else { if(vHtmlChild) vHtmlNode.appendChild(vHtmlChild); } } else if(vXmlNode.nodeType == 3 || vXmlNode.nodeType == 4) { fctAppendText.call(this, vXmlNode.nodeValue); } nextSibling: while(! vXmlNode.nextSibling){ if(vXmlNode.parentNode==null || vXmlNode.parentNode.isSameNode(pXmlRoot)) { vXmlNode = null; break nextSibling; } else { vXmlNode = vXmlNode.parentNode; vStackJumpXmlNode.pop(); while(vStackJumpXmlNode[vStackJumpXmlNode.length-1] == true && ! vXmlNode.nextSibling) { if(vXmlNode.parentNode==null || vXmlNode.parentNode.isSameNode(pXmlRoot)) { vXmlNode = null; break nextSibling; } vStackJumpXmlNode.pop(); vXmlNode = vXmlNode.parentNode; } if(vStackJumpXmlNode[vStackJumpXmlNode.length-1] == false) { vHtmlNode = vHtmlNode.parentNode; vParentClass = this.fClasses[vHtmlNode.nodeName]; //xed.debug("vXmlNode::"+xed.getXml(vXmlNode)+ "\nvHtmlNode::" + xed.getXml(vHtmlNode)); } } } if(vXmlNode) { vXmlNode = vXmlNode.nextSibling; vStackJumpXmlNode[vStackJumpXmlNode.length-1] = false; } } }catch(e){ xed.debug("xml2html()::"+(vXmlNode?vXmlNode.nodeName:"[xmlNode:ull]")+" "+(vHtmlChild?vHtmlChild.nodeName:"[htmlChild:null]")+" "+e); } finally { if(pHtmlContext && pHtmlRoot) delete pHtmlRoot.fHtmlContext; } ]]> 1) ? parseInt(vColSpan, 10) : 1; } else vRow.removeChild(vCell); vCell = vNextCell; } vFirstRow = vRow; } } else if(vFirstRow){ //erreur dtd, on suppr this.fXmlTable.removeChild(vRow); } else if(vRow.localName=="caption") { vCaption = vRow; } vRow = vRowNext; } //Création des column var vHtmlCol = this.fHtmlTable.firstChild; while(vHtmlCol && vHtmlCol.nodeName != "COL") vHtmlCol = vHtmlCol.nextSibling; for(var i = 0; i < vMaxCountCell; i++) { var vXmlCol = vXmlDoc.createElementNS(SCNS, "sc:column"); if(vHtmlCol) { copyAtts(vHtmlCol, vXmlCol); var vW = Math.max(10, vHtmlCol.offsetWidth); if( ! vHtmlCol.hasAttribute("width")) { //On était en mode auto, on se prend une marge de 5% ou 5px min vW = vW + (Math.min(5, vW*.05)); } vXmlCol.setAttribute("width", pZoneEditor.computeScWitdhFromTDWidth(vW)); vHtmlCol = vHtmlCol.nextSibling; while(vHtmlCol && vHtmlCol.nodeName != "COL") vHtmlCol = vHtmlCol.nextSibling; } else { vXmlCol.setAttribute("width", vDefaultXmlW); } this.fXmlTable.insertBefore(vXmlCol, vFirstRow); } //Gestion des captions var vCaptionRule = pZoneEditor.fClasses[this.fHtmlTable.nodeName].hasCaption(this.fHtmlTable); if(vCaptionRule==0) { if(vCaption) this.fXmlTable.removeChild(vCaption); } else if(vCaptionRule==2) { if( ! vCaption) this.fXmlTable.insertBefore(vXmlDoc.createElementNS(SCNS, "sc:caption"), this.fXmlTable.firstChild); } }; function ExtBlockPostTask(pHtmlExtBlock, pXmlExtBlock){ this.fHtmlExtBlock = pHtmlExtBlock; this.fXmlExtBlock = pXmlExtBlock; } ExtBlockPostTask.prototype.execPost = function(pZoneEditor){ var vCaption = this.fXmlExtBlock.firstChild; var vCaptionRule = pZoneEditor.fClasses[this.fHtmlExtBlock.nodeName].hasCaption(this.fHtmlExtBlock); if(vCaptionRule==0) { if(vCaption) this.fXmlExtBlock.removeChild(vCaption); } else if(vCaptionRule==2) { if( ! vCaption) this.fXmlExtBlock.insertBefore(vXmlDoc.createElementNS(SCNS, "sc:captionBlock"), null); } }; function ListsPostTask(pHtmlList, pXmlList){ this.fHtmlList = pHtmlList; this.fXmlList = pXmlList; } ListsPostTask.prototype.execPost = function(pZoneEditor){ var vTitle = this.fXmlList.firstElementChild; if(vTitle && vTitle.localName!="title") vTitle = null; var vTitleRule = pZoneEditor.fClasses[this.fHtmlList.nodeName].hasTitle(this.fHtmlList); if(vTitleRule==0) { if(vTitle) this.fXmlList.removeChild(vTitle); } else if(vTitleRule==2) { if( ! vTitle) this.fXmlList.insertBefore(vXmlDoc.createElementNS(SCNS, "sc:title"), null); } }; //Init if(pRange!=null) { var vStartNode = pRange.startContainer; var vStartOffset = pRange.startOffset; vEndNode = pRange.endContainer; var vEndOffset = pRange.endOffset; if(vEndNode.nodeType == 1 && vEndOffset > 0) { vEndNode = vEndNode.childNodes.item(pRange.endOffset-1); vEndOffset = vEndNode.nodeType==3 ? vEndNode.data.length : 0; } if(pTrim) { while(vStartNode.nodeType == 3 && vStartOffset == vStartNode.data.length) { //On est en fin de noeud text, on passe au noeud suivant. while(!vStartNode.nextSibling){ vStartNode = vStartNode.parentNode; if(vStartNode == this.fHtmlRoot) return; } vStartNode = vStartNode.nextSibling; vStartOffset = 0; if( ! pRange.isPointInRange(vStartNode, vStartOffset)) return; } } if(vStartNode.nodeType == 1) { if(vStartOffset < vStartNode.childNodes.length && vStartNode.childNodes.item(vStartOffset).nodeName != "BR") { vStartNode = vStartNode.childNodes.item(vStartOffset); vStartOffset = 0; } else { //On est après le dernir fils d'une balise, on la saute while(!vStartNode.nextSibling){ vStartNode = vStartNode.parentNode; if(vStartNode == this.fHtmlRoot) return; } vStartNode = vStartNode.nextSibling; vStartOffset = 0; } if( ! pRange.isPointInRange(vStartNode, vStartOffset)) return; } vHtmlNode = vStartNode; var vRelativePos = vStartNode.compareDocumentPosition(vEndNode); /* if(vRelativePos & 2) { xed.debug("start après le end, aucun contenu....."); xed.debug("vStartNode:::"+xed.getXml(vStartNode)); xed.debug("vEndNode:::"+xed.getXml(vEndNode)); return; //start après le end, aucun contenu. } */ if(vStartNode.parentNode != vEndNode.parentNode && ( (vRelativePos & 16) == 0)){ //La fin n'est pas contenue dans le noeud start et les 2 noeuds ne sont pas frères //vHtmlNode va devoir être un parent à vStartNode //xed.debug("vHtmlNode va devoir être un parent à vStartNode....."); vStartOutside = true; function getDeep(pNode){ var vDeep = 0; while(pNode) { vDeep++; pNode = pNode.parentNode; } return vDeep; } var vStartDeep = getDeep(vStartNode); var vEndDeep = getDeep(vEndNode); var vAncestorEndNode = vEndNode; //On se place à la même profondeur for(; vStartDeep > vEndDeep; vStartDeep--) {vHtmlNode = vHtmlNode.parentNode;} for(; vEndDeep > vStartDeep; vEndDeep--) {vAncestorEndNode = vAncestorEndNode.parentNode;} while(vHtmlNode.parentNode != vAncestorEndNode.parentNode){ vHtmlNode = vHtmlNode.parentNode; vAncestorEndNode = vAncestorEndNode.parentNode; } } //Si on est dans une structure interne à un container de block, on remonte au root du container. var vType = this.fClasses[vHtmlNode.nodeName].type; if(vType==5 || vType==6) while( ! this.fClasses[vHtmlNode.nodeName].isParaSibling) { //Balises intermédiaires de containers vHtmlNode = vHtmlNode.parentNode; vStartOutside = true; } //Dans les ancêtres de vEndNode on recherche le noeud incomplet le plus profond vLastIncompleteEndNode = null; if(vEndNode.nodeType == 3 && vEndOffset < vEndNode.data.length) { //Le noeud texte terminal lui-même n'est pas complet. vLastIncompleteEndNode = vEndNode; } else { var vAncestorEndNode = vEndNode; while(vAncestorEndNode != this.fHtmlRoot) { if(vAncestorEndNode.nextSibling != null) { var vNext = vAncestorEndNode.nextSibling; while(vNext){ if( (vNext.nodeType == 1) ? vNext.nodeName != "BR" : vNext.data.length > 0) { break; //noeud non vide } vNext = vNext.nextSibling; } if(vNext) { //On a trouvé un noeud non vide vLastIncompleteEndNode = vAncestorEndNode; break; } } vAncestorEndNode = vAncestorEndNode.parentNode; } } //xed.debug("pRange.startContainer:::"+xed.getXml(pRange.startContainer)+" - "+pRange.startOffset); //xed.debug("vStartNode:::"+xed.getXml(vStartNode)); //xed.debug("pRange.endContainer:::"+xed.getXml(pRange.endContainer)+" - "+pRange.endOffset); //xed.debug("vEndNode:::"+xed.getXml(vEndNode)); //xed.debug("vStartNode.compareDocumentPosition(vEndNode):::"+vStartNode.compareDocumentPosition(vEndNode)); //xed.debug("vStartOutside:::"+vStartOutside); //xed.debug("vHtmlNode:::"+xed.getXml(vHtmlNode)); } else { //Pas de pRange vHtmlNode = this.fHtmlRoot.firstChild; vEndNode = this.fHtmlRoot; } /* Copie les attributs standards role, sc:id et les metas. */ function copyAtts(pHtmlNode, pXmlNode){ //if(pHtmlNode.hasAttribute("lang")) pXmlNode.setAttribute("xml:lang", pHtmlNode.getAttribute("lang")); if(pHtmlNode.hasAttribute("role")) pXmlNode.setAttribute("role", pHtmlNode.getAttribute("role")); //Meta... var vMeta = pHtmlNode.getUserData("meta"); if(vMeta) { //xed.debug("Meta to save : "+xed.getXml(vMeta)); pXmlNode.appendChild(pXmlNode.ownerDocument.importNode(vMeta, true)); } //sc:id if( ! vStartOutside && pHtmlNode.hasAttribute("id")) { if(vLastIncompleteEndNode) { //On teste si ce noeud appartient à la liste des noeuds terminaux incomplets : dans ce cas, pas d'ID. var vNode = vLastIncompleteEndNode; while(vNode) { if(vNode == pHtmlNode) return; //Noeud incomplet on sort vNode = vNode.parentNode; } } pXmlNode.setAttributeNS(SCNS, "sc:id", pHtmlNode.getAttribute("id")); } } function isFilled(pHtmlNode){ var vCh = pHtmlNode.firstChild; while(vCh) { if(vCh.nodeType == 1 || vCh.nodeValue.length > 0) return true; vCh = vCh.nextSibling; } return false; } while(vHtmlNode) { if(vStartOutside) { if(vHtmlNode == vStartNode) { //Ca y est on entre dans la zone vStartOutside = false; } else { //On regarde si ce noeud est dans la hierarchie parent //xed.debug("vStartNode:::"+xed.getXml(vStartNode)); //xed.debug("vHtmlNode:::"+xed.getXml(vHtmlNode)); //xed.debug("vHtmlNode.compareDocumentPosition(vStartNode):::"+vHtmlNode.compareDocumentPosition(vStartNode)); if( (vHtmlNode.compareDocumentPosition(vStartNode) & 16) == 0) { //Noeud hors hiérarchie, on passe au noeud suivant //Cas particulier du term, pour respecter la DTD, on ajoute un term vide if(vHtmlNode.localName == "TERM" && ! vXmlNode.hasChildNodes()) { vXmlNode.appendChild(vXmlDoc.createElementNS(SCNS, "sc:term")); } while(! vHtmlNode.nextSibling){ vHtmlNode = vHtmlNode.parentNode; vXmlNode = vXmlNode.parentNode; } vHtmlNode = vHtmlNode.nextSibling; continue; } } } var vHtmlNextStep = true; if(vHtmlNode.nodeType == 1) { var vXmlChild = null; switch(vHtmlNode.nodeName){ // ####### Balises blocks ######## case "PARA" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:para"); vXmlChild.setAttribute("xml:space", "preserve"); copyAtts(vHtmlNode, vXmlChild); } break; case "DIR" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:simpleList"); copyAtts(vHtmlNode, vXmlChild); vPostTasks.push(new ListsPostTask(vHtmlNode, vXmlChild)); } break; case "MEMBER" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:member"); vXmlChild.setAttribute("xml:space", "preserve"); copyAtts(vHtmlNode, vXmlChild); } break; case "UL" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:itemizedList"); copyAtts(vHtmlNode, vXmlChild); vPostTasks.push(new ListsPostTask(vHtmlNode, vXmlChild)); } break; case "OL" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:orderedList"); copyAtts(vHtmlNode, vXmlChild); vPostTasks.push(new ListsPostTask(vHtmlNode, vXmlChild)); } break; case "LITEM" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:listItem"); copyAtts(vHtmlNode, vXmlChild); } break; case "TITLE" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:title"); vXmlChild.setAttribute("xml:space", "preserve"); copyAtts(vHtmlNode, vXmlChild); } break; /* case "VARIABLELIST" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:variableList"); copyAtts(vHtmlNode, vXmlChild); } break; case "VARLISTENTRY" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:varListEntry"); copyAtts(vHtmlNode, vXmlChild); } break; case "TERM" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:term"); copyAtts(vHtmlNode, vXmlChild); } break; case "VARLISTITEM" : */ case "TABLE" : vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:table"); copyAtts(vHtmlNode, vXmlChild); vPostTasks.push(new TablePostTask(vHtmlNode, vXmlChild)); break; case "COL" : //sera traité par la postTask break; case "CAPTION" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:caption"); vXmlChild.setAttribute("xml:space", "preserve"); copyAtts(vHtmlNode, vXmlChild); } break; case "TR" : vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:row"); copyAtts(vHtmlNode, vXmlChild); break; case "TD" : vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:cell"); copyAtts(vHtmlNode, vXmlChild); var vVal = vHtmlNode.getAttribute("rowSpan"); if(vVal > 1) vXmlChild.setAttribute("rowSpan", vVal); vVal = vHtmlNode.getAttribute("colSpan"); if(vVal > 1) vXmlChild.setAttribute("colSpan", vVal); break; case "EXTBLOCK" : vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:extBlock"); copyAtts(vHtmlNode, vXmlChild); vXmlChild.setAttributeNS(SCNS, "sc:refUri", vHtmlNode.getAttribute("refUri")); vPostTasks.push(new ExtBlockPostTask(vHtmlNode, vXmlChild)); break; case "CAPTIONBLOCK" : if( ! this.isNodeEmpty(vHtmlNode)) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:captionBlock"); vXmlChild.setAttribute("xml:space", "preserve"); copyAtts(vHtmlNode, vXmlChild); } break; case "EMPTYBLOCK" : vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:emptyBlock"); copyAtts(vHtmlNode, vXmlChild); break; // ####### Balises inline ######## case "PHRASE" : vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:phrase"); copyAtts(vHtmlNode, vXmlChild); break; case "INLINESTYLE" : if(isFilled(vHtmlNode) || vHtmlNode.getUserData("meta")!=null) { vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:inlineStyle"); copyAtts(vHtmlNode, vXmlChild); } break; case "TEXTLEAF" : //if(isFilled(vHtmlNode)) { non : exemple : copyright sans contenu vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:textLeaf"); copyAtts(vHtmlNode, vXmlChild); //} break; case "ULINK" : vXmlChild = vXmlDoc.createElementNS(SCNS, "sc:uLink"); copyAtts(vHtmlNode, vXmlChild); if(this.fClasses[vHtmlNode.nodeName].isRefItem(vHtmlNode)) { vXmlChild.setAttributeNS(SCNS, "sc:refUri", vHtmlNode.getAttribute("refUri")); } else { vXmlChild.setAttribute("url", vHtmlNode.getAttribute("url")); } break; case "OBJECTLEAF" : var vNewNode = vXmlDoc.createElementNS(SCNS, "sc:objectLeaf"); copyAtts(vHtmlNode, vNewNode); vNewNode.setAttributeNS(SCNS, "sc:refUri", vHtmlNode.getAttribute("refUri")); vXmlNode.appendChild(vNewNode); break; case "EMPTYLEAF" : var vNewNode = vXmlDoc.createElementNS(SCNS, "sc:emptyLeaf"); copyAtts(vHtmlNode, vNewNode); vXmlNode.appendChild(vNewNode); break; case "IMG" : if(vHtmlNode !== this._TmpDragImg) { var vNewNode = vXmlDoc.createElementNS(SCNS, "sc:inlineImg"); copyAtts(vHtmlNode, vNewNode); vNewNode.setAttributeNS(SCNS, "sc:refUri", vHtmlNode.getAttribute("refUri")); if(vHtmlNode.hasAttribute("text")) { vNewNode.appendChild(vXmlDoc.createTextNode(vHtmlNode.getAttribute("text"))); } vXmlNode.appendChild(vNewNode); } break; case "NOTE" : var vNewNode = vXmlDoc.createElementNS(SCNS, "sc:note"); copyAtts(vHtmlNode, vNewNode); var vIntern = vHtmlNode.getUserData("note"); if(vIntern) { var vCh = vIntern.firstChild; while(vCh) { vNewNode.appendChild(vXmlDoc.importNode(vCh, true)); vCh = vCh.nextSibling; } } vXmlNode.appendChild(vNewNode); break; } if (vXmlChild) { if(vHtmlNode.hasChildNodes()){ vHtmlNode = vHtmlNode.firstChild; vXmlNode = vXmlNode.appendChild(vXmlChild); vHtmlNextStep = false; } else { vXmlNode.appendChild(vXmlChild); } } } else if(vHtmlNode.nodeType == 3) { // Dans le cas d'un noeud texte var vValue = vHtmlNode.nodeValue; if(pRange!=null) { if(vHtmlNode === vEndNode) vValue = (vEndOffset > 0) ? vValue.substring(0, vEndOffset) : ""; if(vHtmlNode === vStartNode) vValue = (vStartOffset < vValue.length) ? vValue.substring(vStartOffset) : ""; } if(vValue) vXmlNode.appendChild(vXmlDoc.createTextNode(vValue.replace(/([\u2004\u2423])/g, "\u00A0"))); } if(vHtmlNextStep) { while(! vHtmlNode.nextSibling){ if(vHtmlNode.isSameNode(vEndNode)) { vHtmlNode = null; break; } else { vHtmlNode = vHtmlNode.parentNode; vXmlNode = vXmlNode.parentNode; } } if(vHtmlNode) { if(vHtmlNode.isSameNode(vEndNode)) { vHtmlNode = null; } else { vHtmlNode = vHtmlNode.nextSibling; } } } }//end while for each(var vPostTask in vPostTasks) vPostTask.execPost(this); }catch(e){xed.debug(this.tagName +"->html2xml:"+e);} ]]> 0) vXmlTable.appendChild(vXmlDoc.createElementNS(SCNS, "sc:caption")); //Columns var vColCount = 0; var vRowsUsed = []; var vOffsetCol = 0; var vHtmlCol = vHtmlTable.firstChild; while(vHtmlCol && vHtmlCol.nodeName != "COL") vHtmlCol = vHtmlCol.nextSibling; for(var vX in pMapCells) { while(vHtmlCol && vX > vOffsetCol) { vOffsetCol++; vHtmlCol = vHtmlCol.nextSibling; while(vHtmlCol && vHtmlCol.nodeName != "COL") vHtmlCol = vHtmlCol.nextSibling; } var vXmlCol = vXmlTable.appendChild(vXmlDoc.createElementNS(SCNS, "sc:column")); copyAtts(vHtmlCol, vXmlCol); var vW = Math.max(10, vHtmlCol.offsetWidth); vXmlCol.setAttribute("width", this.computeScWitdhFromTDWidth(vW)); vColCount++; for(var vY in pMapCells[vX]) vRowsUsed[vY] = true; } //Rows var vOffsetRow = 0; var vHtmlRow = vHtmlTable.firstChild; while(vHtmlRow && vHtmlRow.nodeName != "TR") vHtmlRow = vHtmlRow.nextSibling; var vRange = vHtmlDoc.createRange(); for(var vY in vRowsUsed) { while(vHtmlRow && vY > vOffsetRow) { vOffsetRow++; vHtmlRow = vHtmlRow.nextSibling; while(vHtmlRow && vHtmlRow.nodeName != "TR") vHtmlRow = vHtmlRow.nextSibling; } var vXmlRow = vXmlTable.appendChild(vXmlDoc.createElementNS(SCNS, "sc:row")); copyAtts(vHtmlRow, vXmlRow); for(var vX in pMapCells) { var vHtmlCell = pMapCells[vX][vY]; var vXmlCell = vXmlRow.appendChild(vXmlDoc.createElementNS(SCNS, "sc:cell")); if(vHtmlCell) { copyAtts(vHtmlCell, vXmlCell); vRange.selectNodeContents(vHtmlCell); this.html2xml(vXmlCell, vRange, false); } else { //Cell vide -> TODO role cell par défaut ? } } } vRange.detach(); }catch(e){xed.debug(this.tagName +"->cells2xml:"+e);} ]]> 0) { vTw.currentNode = vStartNode.childNodes[vRange.endOffset-1]; } else { vTw.currentNode = vStartNode; } if(!gotoNext()) return vResultSynch; } } else { vTw.currentNode = vStartNode; if(!gotoNext()) return vResultSynch; } } else if(pFrom==2) { if(!gotoNext())return vResultSynch; } else if(pFrom==3) { var vStartNode = vDoc.body; while(vStartNode.lastChild) vStartNode = vStartNode.lastChild; vTw.currentNode = vStartNode; if(vTw.currentNode.nodeType!=1 && !gotoNext())return vResultSynch; } function notifErrorMeta(pMsg) { try { //On a trouvé une erreur //On effectue les actions demandées var vEditor = xed.getEditor(vZoneEditor.fRichTextInput); if(pNotif&1) { vEditor.setFocus(vZoneEditor.fRichTextInput); vZoneEditor.focusHtmlNode(vTw.currentNode); } if(pNotif&2) { var vButtons = [{ label : "Editer", accessKey : "?key=accessKey.Editer;E", className : "edit", callback : function(pNotif, pDesc){ try { var vStructNode = pDesc.fZoneEditor.fClasses[pDesc.fNode.nodeName].getStructuralNodes(pDesc.fNode); pDesc.fZoneEditor.openSubWindowEditor(vStructNode.urlSubEditor, pDesc.fNode); pNotif.close(); }catch(e){xed.debug(e);} }, fZoneEditor : vZoneEditor, fNode : vTw.currentNode }] xed.setTemporaryNotif(vEditor, pMsg, "xedError", 7, vButtons); } } catch(e){xed.debug(e)}; } function evalResultMeta(pResult, pIsOnLoadError) { if(pResult==1) { //xed.debug("evalResultMeta::"+pResult); notifErrorMeta("Les propriétés de cet élément sont en erreur."); finish(1); } //Sinon, on poursuit la recherche. } function evalResultMetaAsynch(pResult) { //Suppression des dst temporaires de ces meta. //xed.debug("evalResultMetaAsynch::::::::"+pResult); try { evalResultMeta(pResult); vZoneEditor.hiddenDst.removeChild(vRootDst); if(!gotoNext()) return; searchNext(); } catch(e) { xed.debug("evalResultMetaAsynch::"+e); finish(0); } } function searchNext() { try { for(;;) { //xed.debug("vTw.currentNode.nodeName]:::::"+vTw.currentNode.nodeName); var vClassNode = vZoneEditor.fClasses[vTw.currentNode.nodeName]; if(vTw.currentNode.hasAttribute("error")) { var vEditor = xed.getEditor(vZoneEditor.fRichTextInput); if(pNotif&1) { vEditor.setFocus(vZoneEditor.fRichTextInput); vZoneEditor.focusHtmlNode(vTw.currentNode); } if(pNotif&2) { var vButtons = [{ label : "Editer", accessKey : "?key=accessKey.Editer;E", className : "edit", callback : function(pNotif, pDesc){ try { var vStructNode = pDesc.fZoneEditor.fClasses[pDesc.fNode.nodeName].getStructuralNodes(pDesc.fNode); pDesc.fZoneEditor.openSubWindowEditor(vStructNode.urlLinkEditor, pDesc.fNode); pNotif.close(); }catch(e){xed.debug(e);} }, fZoneEditor : vZoneEditor, fNode : vTw.currentNode }] xed.setTemporaryNotif(vEditor, "Ce lien est incorrect.", "xedError", 7, vButtons); } finish(1); return; } var vStructNode = vClassNode && ("getStructuralNodes" in vClassNode) ? vClassNode.getStructuralNodes(vTw.currentNode) : null; if(vStructNode && vStructNode.urlXedMeta) { var vMeta = vTw.currentNode.getUserData("meta"); if(vMeta==null && ! vStructNode.isMetaOptional && ! vZoneEditor.isNodeEmpty(vTw.currentNode)) { //Meta obligatoires mais inexistants, et balise exportable. notifErrorMeta("Les propriétés de cet élément n'ont pas été renseignées."); finish(1); return; } else if(vMeta!=null) { //Meta renseignés, on les valide var vEditor = xed.getEditor(vZoneEditor.fRichTextInput); try { var vOnLoadErrors = false; vRootDst = vZoneEditor.hiddenDst.appendChild(document.createElementNS(XULNS, "box")); vRootDst.fEditor = vEditor; vRootDst.fIsEditor = true; vRootDst.fIsRootEditor = true; vRootDst.collapsed = true; vRootDst.addEventListener("XEDUndefinedNodeInserted", function(pEvent){ //xed.debug("XEDUndefinedNodeInserted..........."); pEvent.preventDefault(); pEvent.stopPropagation(); vOnLoadErrors = true; }, true); var vRootSrc = vMeta ? vMeta.parentNode : null; if(!vRootSrc) { vRootSrc = vEditor.getDocSrc().createDocumentFragment(); if(vMeta) vRootSrc.appendChild(vMeta); } vEditor.refreshContentDst(vRootDst, vMeta, vEditor.resolveModelByUrlId(vStructNode.urlXedMeta), []); if(vOnLoadErrors) { evalResultMeta(1, true); } else { var vResultErr = vEditor.findErrorFromDstRoot(vRootDst, 0, false, 2, true, vZoneEditor, evalResultMetaAsynch); if(vResultErr == null) { //On part en asynch //xed.debug("scText findError Meta asycnh..........DST::"+xed.getXml(vRootDst)); vResultSynch = null; return; } evalResultMeta(vResultErr); } vZoneEditor.hiddenDst.removeChild(vRootDst); } catch(e){ xed.debug("buildScTextMeta failed : "+e); } } } if(!gotoNext()) return; } } catch(e){ xed.debug("scRichText.findErrorInDst.searchNext::"+e); finish(0); } } searchNext(); //xed.debug("result synch scText zone : "+vResultSynch); return vResultSynch; }catch(e){xed.debug("scRichText.findErrorInDst::"+e);} return 0; // si exception ]]> 1) { //On tente une fusion des ranges de cellules de tables. var vListR = []; for(var i = 0; i < vRangeCount; i++) { var vR = vSel.getRangeAt(i).cloneRange(); //On absorbe les balises TR par les ranges de 1ère et dernière TD if(vR.startContainer.nodeName=="TR" && vR.startOffset == 0) vR.setStart(vR.startContainer.parentNode, this.getOffsetInParent(vR.startContainer)); if(vR.endContainer.nodeName=="TR" && vR.endOffset == vR.endContainer.childNodes.length) vR.setEnd(vR.endContainer.parentNode, this.getOffsetInParent(vR.endContainer)+1); vListR.push(vR); } do{ var vUpdt = false; for(var i = 0; i < vListR.length; i++) { var vFirstR = vListR[i]; for(var k = (i == 0 ? 1 : 0); k < vListR.length; (k==i ? k = k + 2 : k++) ) { var vOtherR = vListR[k]; if(vFirstR.endContainer==vOtherR.startContainer && vFirstR.endOffset==vOtherR.startOffset) { vFirstR.setEnd(vOtherR.endContainer, vOtherR.endOffset); vOtherR.detach(); vListR.splice(k--, 1); vUpdt = true; } } } } while(vUpdt); //xed.debug("vListR.length::::"+vListR.length); if(vListR.length==1) { var vR = vListR[0]; if(vR.startContainer.nodeName=="TABLE" && vR.endContainer.nodeName=="TABLE" ) { //On ne retourne un résultat que si des lignes entières sont sélectionnées. //bloque des suppresssion ou des copier / coller de fragments lignes car non géré. vSel.removeAllRanges(); vSel.addRange(vR); return vR; } } //Echec fusion, on purge for(var i = 0; i < vListR.length; i++) vListR[i].detach(); } return null; }catch(e){xed.debug("getRangeFromSel::"+e);} ]]> if(!pNode) return null; while(pNode) { switch(this.fClasses[pNode.nodeName].type) { case 0: case 6: return null; case 5: case 7: return pNode; default : pNode = pNode.parentNode; } } 1) return; var vRange = vSel.getRangeAt(0); var vStartBlock = vRange.startContainer; SEARCHBLOCKP: while(vStartBlock) { switch(this.fClasses[vStartBlock.nodeName].type) { case 6: case 0: vStartBlock = null; case 5: break SEARCHBLOCKP; } vStartBlock = vStartBlock.parentNode; } var vEndBlock = vRange.endContainer; SEARCHBLOCKN: while(vEndBlock) { switch(this.fClasses[vEndBlock.nodeName].type) { case 6: case 0: vEndBlock = null; case 5: break SEARCHBLOCKN; } vEndBlock = vEndBlock.parentNode; } //xed.debug("vStartBlock:::"+xed.getXml(vStartBlock)+"\n"+xed.getXml(vEndBlock)); if(vStartBlock == vEndBlock) return vStartBlock; return null; ]]> 0 && vNode.data.match(/[^\t\n\v\f\r ]/)) return false; } else { if(this.fClasses[vNode.nodeName].isForced){ return false; } else { if(vNode.hasChildNodes()) { vNode = vNode.firstChild; continue; } } } if(vNode == pNode) return true; while( ! vNode.nextSibling){ vNode = vNode.parentNode; if(vNode == pNode) return true; } vNode = vNode.nextSibling; } return true; ]]> 0 && vNode.data.match(/[^\t\n\v\f\r ]/)) return false; } else { var vClass = this.fClasses._xml[vNode.localName]; if(vClass && vClass.isForced){ return false; } else { if(vNode.hasChildNodes()) { vNode = vNode.firstChild; continue; } } } if(vNode == pNode) return true; while( ! vNode.nextSibling){ vNode = vNode.parentNode; if(vNode == pNode) return true; } vNode = vNode.nextSibling; } return true; ]]> 0){ //Noeud texte non vide this.fHTMLEditor.selection.collapse(vNode, 0); return; } //On est sur un noeud texte vide, on test l'elt suivant. var vNext = vNode.nextSibling; while(vNext) { if(vNext.nodeType == 3){ if(vNext.data.length > 0) { //Noeud texte non vide this.fHTMLEditor.selection.collapse(vNext, 0); return; } } else { switch(this.fClasses[vNext.nodeName].type) { case 1: case 9: this.fHTMLEditor.selection.collapse(vNode, 0); break; default : this.setCaretInBlock(vNext); } return; } vNode = vNext; vNext = vNext.nextSibling; } this.fHTMLEditor.selection.collapse(vNode, 0); ]]> 0) { if(vParentPoint.nodeType!=1) return false; vOffsetPoint--; var vPrev = vParentPoint.childNodes[vOffsetPoint]; if(vPrev.nodeType==1) return false; if(vPrev.nodeValue.length>0) return false; } pOffsetPoint = this.getOffsetInParent(vParentPoint); vParentPoint = vParentPoint.parentNode; } return true; ]]> =0) { vCur.replaceData(vOffs, 1, this.fNbspCar); vOffs = vVal.indexOf(vOldCar, vOffs+1); } vCur = vTw.nextNode(); } ]]> 1) { xed.setTemporaryNotif(xed.getEditor(this), "Il est impossible d\'insérer un élément dans une sélection multiple.", "NotAllowed", 6); return; } if(vSel.isCollapsed) vSel.collapseToEnd(); var vRange = vSel.getRangeAt(0); var vParentElt = vRange.endContainer; if(vParentElt.nodeType == 3) vParentElt = vParentElt.parentNode; switch(this.fClasses[vParentElt.nodeName].type) { case 1: case 2: //On est dans un TextLeaf ou un ObjectLeaf, on en sort var vLen = vRange.endContainer.nodeType==1 ? vRange.endContainer.childNodes.length : vRange.endContainer.nodeValue.length; if(vRange.endOffset == 0) { //On se déplace avant vSel.collapse(vParentElt.parentNode, this.getOffsetInParent(vParentElt)); } else if(vRange.endOffset == vLen) { //On se déplace après vSel.collapse(vParentElt.parentNode, this.getOffsetInParent(vParentElt)+1); } else { //On informe qu'on n'a pas le droit d'insérer au milieu d'un textLeaf var vTagName = this.fClasses[vParentElt.nodeName].getStructuralNodes(vParentElt).title; xed.setTemporaryNotif(xed.getEditor(this), xed.formatStr("?syntax=Formatter;Il est impossible d'insérer cet élément au sein d'une balise '%1$s'.", vTagName), "NotAllowed", 6); return; } vRange = vSel.getRangeAt(0); } //Création et insertion du nouveau noeud var vNewNode = this.fHtmlRoot.ownerDocument.createElement(pTag); if(pRole) vNewNode.setAttribute("role", pRole); vNewNode.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); if(pTag=="img") { if(pUriItem) vNewNode.setAttribute("refUri", pUriItem||""); this.loadInlineImg(vNewNode, pUriItem); } else if(pTag=="objectLeaf") { if(pUriItem) vNewNode.setAttribute("refUri", pUriItem||""); this.loadObjectLeaf(vNewNode, pUriItem); } this.fHTMLEditor.insertElementAtSelection(vNewNode, false); //bugué Gecko 1.9.1 si insertion à la fin d'un container. //this.fHTMLEditor.insertNode(vNewNode, vRange.startContainer, vRange.startOffset); //Fin de traitement et ouverture de la fenetre de propriété this.fRichTextInput.setDirty(true); if( ! pUriItem) { var vStructNode = this.fClasses[vNewNode.nodeName].getStructuralNodes(vNewNode); if(vStructNode.hasLinkEditor) { this.openSubWindowEditor(vStructNode.urlLinkEditor, vNewNode); } else if(vStructNode.hasSubEditor) { this.openSubWindowEditor(vStructNode.urlSubEditor, vNewNode); } } this.addTransSelForRedo(); }catch(e){ xed.debug(this.tagName+"->insertInlineObject :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } ]]> insertInlineText :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } ]]> 0) { var vPrev = pRange.endContainer.childNodes[pRange.endOffset-1]; if(vPrev && vPrev.nodeType==3) { if(/[\t\n\v\f\r ]/.test(vPrev.data.charAt(vPrev.data.length-1))) pRange.setEnd(vPrev, vPrev.data.length-1); } } } return true; ]]> insertInlineStyle :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } ]]> =0; i--) { this.fNewStyle.insertBefore(this.fNodes[i], vNext); } } } vTrans.undoTransaction = function(){ this.fNewStyle.parentNode.removeChild(this.fNewStyle); if(this.fTextNodeToCut) { this.fTextNodeToCut.insertData(0, this.fText); } if(this.fNodes) { var vNextSibling = this.fParent.firstChild; for(var i=this.fNodes.length-1; i>=0; i--) { this.fParent.insertBefore(this.fNodes[i], vNextSibling); } } } vTrans.redoTransaction = function(){ this.fParent.parentNode.insertBefore(this.fNewStyle, this.fParent); if(this.fTextNodeToCut) { this.fTextNodeToCut.deleteData(0, this.fOffset); } if(this.fNodes) { var vNext = this.fNewTextNode || null; for(var i=this.fNodes.length-1; i>=0; i--) { this.fNewStyle.insertBefore(this.fNodes[i], vNext); } } } } else { vTrans.doTransaction = function(){ if(this.fTextNodeToCut) { this.fText = this.fTextNodeToCut.substringData(0, this.fOffset); this.fTextNodeToCut.deleteData(0, this.fOffset); this.fNewTextNode = this.fHTMLEditor.document.createTextNode(this.fText); this.fParent.parentNode.insertBefore(this.fNewTextNode, this.fParent); } if(this.fNodes) { var vRoot = this.fParent.parentNode; var vNext = this.fNewTextNode || this.fParent; for(var i=this.fNodes.length-1; i>=0; i--) { vRoot.insertBefore(this.fNodes[i], vNext); } } } vTrans.undoTransaction = function(){ if(this.fTextNodeToCut) { this.fTextNodeToCut.insertData(0, this.fText); this.fParent.removeChild(this.fNewTextNode); } if(this.fNodes) { var vNextSibling = this.fParent.firstChild; for(var i=this.fNodes.length-1; i>=0; i--) { this.fParent.insertBefore(this.fNodes[i], vNextSibling); } } } vTrans.redoTransaction = function(){ if(this.fTextNodeToCut) { this.fTextNodeToCut.deleteData(0, this.fOffset); this.fParent.parentNode.insertBefore(this.fNewTextNode, this.fParent); } if(this.fNodes) { var vRoot = this.fParent.parentNode; var vNext = this.fNewTextNode || this.fParent; for(var i=this.fNodes.length-1; i>=0; i--) { vRoot.insertBefore(this.fNodes[i], this.fParent); } } } } this.fHTMLEditor.doTransaction(vTrans); vRange.setEndBefore(vParent); vParent = vParent.previousSibling; break; default: xed.debug("insertInlineContainer:: bug node at end:"+vParent.nodeName); return; } vChild = vParent; vParent = vChild.parentNode; } if(vRange.endContainer.nodeType==3) { var vLast = vRange.endContainer.data.charAt(vRange.endOffset-1); if(/[\t\n\v\f\r ]/.test(vLast) && (vRange.endContainer != vRange.startContainer || vRange.startOffset < vRange.endOffset)) vRange.setEnd(vRange.endContainer, vRange.endOffset - 1); } //On cree la nouvelle balise var vNewNode = this.fHtmlRoot.ownerDocument.createElement(pTag); if(pRole) vNewNode.setAttribute("role", pRole); vNewNode.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); if(pUriItem) { vNewNode.setAttribute("refUri", pUriItem); } //On wrap le contenu avec la nouvelle balise... var vEmpty = vRange.collapsed; if(! vEmpty) { var vFrag = vRange.cloneContents(); var vChild = vFrag.firstChild; while(vChild) { var vNext = vChild.nextSibling; vNewNode.appendChild(vChild); vChild = vNext; } } else if(pUriItem){ vEmpty = ! vNewNode.appendChild(this.fHtmlRoot.ownerDocument.createTextNode(this.getTitleItem(pUriItem))); } else { vNewNode.appendChild(this.fHtmlRoot.ownerDocument.createTextNode("")); } //On reaffecte la sel au range calculé et on remplace vSel.removeAllRanges(); vSel.addRange(vRange.cloneRange()); //On insère //XXX bugué Gecko 1.9.1 si insertion à la fin d'un container. //https://bugzilla.mozilla.org/show_bug.cgi?id=500690 this.fHTMLEditor.insertElementAtSelection(vNewNode, true); //this.deleteSelection(); //this.fHTMLEditor.insertNode(vNewNode, vSel.anchorNode, vSel.anchorOffset); //On regère la sel. if(vEmpty) { vSel.collapse(vNewNode, 0); } else { vSel.selectAllChildren(vNewNode); } this.fRichTextInput.setDirty(true); if( ! pUriItem) { var vStructNode = this.fClasses[vNewNode.nodeName].getStructuralNodes(vNewNode); if(vStructNode.hasLinkEditor) { this.openSubWindowEditor(vStructNode.urlLinkEditor, vNewNode); } else if(vStructNode.hasSubEditor) { this.openSubWindowEditor(vStructNode.urlSubEditor, vNewNode); } } else { if(pTag=="uLink") { this.loadULink(vNewNode, pUriItem); } } this.addTransSelForRedo(); }catch(e){ xed.debug(this.tagName+"->insertInlineContainer :\n"+e); } finally{ this.fHTMLEditor.endTransaction(); vRange.detach(); } ]]> new Object() insertTable :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } ]]> insert_row :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } } ]]> insert_row :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } } ]]> 1) } else { //la cell vient d'une TR précédente, on n'insère pas de cell, mais on incrémente le rowSpan var vTrans = { fCell : vCell, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ this.fCell.rowSpan++; } vTrans.undoTransaction = function(){ this.fCell.rowSpan--; } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); } vPrevCell = vCell; } } this.checkForEdit(vNewTR, true); return vNewTR; ]]> 0 ? vTableEd.getCellAt(pTable, vRowIdx, pOffsetCol-1) : null; var vNextCell = pOffsetCol < vTotalCol.value ? vTableEd.getCellAt(pTable, vRowIdx, pOffsetCol) : null; if(vPrevCell==vNextCell && vPrevCell!=null) { //On insert au milieu d'une cell fusionnée if(vPrevCell.parentNode == vTR) { if(!vFirstTD) vFirstTD = vPrevCell; //Et cette cell est dans ce Tr : on étend le colSpan var vTrans = { fCell : vPrevCell, fCount : pCount, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ this.fCell.colSpan += this.fCount; } vTrans.undoTransaction = function(){ this.fCell.colSpan -= this.fCount; } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); } } else { var vNextTd = vNextCell; var vOffsetCol = pOffsetCol; while(vNextTd && vNextTd.parentNode != vTR) { //On cherche la cell suivante appartenant à cette row. vNextTd = vOffsetCol < vTotalCol.value ? vTableEd.getCellAt(pTable, vRowIdx, vOffsetCol) : null; } vTd = vDoc.createElement("td"); this.insertElt(vTd, vTR, vNextTd); this.setDefaultRole(vTd, this.fClasses.TD); this.checkForEdit(vTd, true); if(!vFirstTD) vFirstTD = vTd; } vTR = vTR.nextSibling; while(vTR && vTR.nodeName != "TR") vTR = vTR.nextSibling; vRowIdx++; } this.checkTableWidth(pTable, true); return vFirstTD; ]]> insertBlock :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } ]]> removeParent :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } ]]> 0) { var vTrans = { fChilds : vAllChildren, fParents : pHtmlNodes, fStartN : vStartN, fEndN : vEndN, fXbl : this, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ for (var k = 0; k < this.fParents.length; k++) { var vParent = this.fParents[k]; var vChilds = this.fChilds[k]; var vOffset = this.fXbl.getOffsetInParent(vParent); for(var i = 0; i < vChilds.length; i++) { vParent.parentNode.insertBefore(vChilds[i], vParent); } var vRoot = vParent.parentNode; vRoot.removeChild(vParent); } vRange = this.fXbl.fHTMLEditor.document.createRange(); vRange.setStartBefore(this.fStartN); vRange.setEndAfter(this.fEndN); var vSel = this.fXbl.fHTMLEditor.selection; vSel.removeAllRanges(); vSel.addRange(vRange); } vTrans.undoTransaction = function(){ for (var k = 0; k < this.fParents.length; k++) { var vParent = this.fParents[k]; var vChilds = this.fChilds[k]; var vLast = vChilds[vChilds.length-1]; var vRoot = vLast.parentNode; var vNext = vLast.nextSibling; for(var i = 0; i < vChilds.length; i++) { vParent.appendChild(vChilds[i]); } vRoot.insertBefore(vParent, vNext); } } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); } this.fRichTextInput.setDirty(true); //this.addTransSelForRedo(); géré dans le do/redo }catch(e){ xed.debug(this.tagName+"->removeParent :\n"+e) } finally{ this.fHTMLEditor.endTransaction(); } ]]> 0) { //xed.debug("vNodesToSel::::"+vNodesToSel.length+" - "+xed.getXml(vNodesToSel[0])); var vRange = this.fHTMLEditor.document.createRange(); vRange.selectNodeContents(vNodesToSel[0]); var vIsEmpty = this.isNodeEmpty(vNodesToSel[0]); for (var i = 1; i < vNodesToSel.length; i++) { var vRes = vRange.comparePoint(vNodesToSel[i], 0); if(vRes == 1) { vRange.setEndAfter(vNodesToSel[i]); } else if(vRes == -1) { vRange.setStartBefore(vNodesToSel[i]); } if(vIsEmpty) vIsEmpty = this.isNodeEmpty(vNodesToSel[i]); } //On vérifie que le range contienne au moins un noeud texte non vide, sinon, la sel est invisible. vSel.removeAllRanges(); vSel.addRange(vRange); if(vIsEmpty) this.setCaretInBlock(vNodesToSel[0]); } else { this.controlSelection(vSel); var vBlck = this.getBlockWrappingSel(); if(vBlck) this.setCaretInBlock(vBlck); } this.fRichTextInput.setDirty(true); this.addTransSelForRedo(); }catch(e){ xed.debug("unwrap: "+e); } finally { this.fHTMLEditor.endTransaction(); } return true; ]]> 0) { var vLevelEntry = pUnwrappables.pop(); if(!vLevelEntry) continue; if(vLevelEntry==true) break; //limite atteinte. while(vLevelEntry.length > 0) { var vListToUnwrap = vLevelEntry.pop(); if(!vListToUnwrap) continue; var vParent = vListToUnwrap[0].parentNode; var vCountItems = 0; var vCh = vParent.firstChild; while(vCh) { var vClass=this.fClasses[vCh.nodeName] if(vClass.isClonable||vClass.isSplitable) vCountItems++; vCh = vCh.nextSibling; } if(vCountItems > vListToUnwrap.length) { //Le container parent n'est pas à dewrapper entièrement, on split le container. //for each(var vX in vListToUnwrap) xed.debug("vX::::\n"+xed.getXml(vX)); var vCh = vParent.firstChild; //On refait un tableau des fils en ne renseignant que ceux à unwrapper. var vMap = []; var vOffset = 0; while(vCh) { if(vListToUnwrap.indexOf(vCh)>=0) vMap[vOffset] = vCh; vOffset++; vCh = vCh.nextSibling; } if(pUnwrappables.countSplit == 0) { //Au 1er split, on autorise toujours de poursuivre l'unwrap. pUnwrappables.countSplit++; } else { //Si on a d'autres noeuds à unwrapper de level inférieur ou égal, alors on va //poursuivre l'unwrap des élements splittés. var vIsUnwrapUpNeeded = pUnwrappables.some(function(){return true;}); if(! vIsUnwrapUpNeeded) break; } //xed.debug("levels:" + pUnwrappables+"\nsiblings:"+vLevelEntry); var vOutUnwrap = ! vMap[0]; //true si on n'est pas dans la liste à unwrapper. for(var i = 1; i < vOffset; i++) { if(vOutUnwrap != ! vMap[i]){ //On change in/out, il faut splitter var vNewStruct = this.splitStruct(vParent, vMap[i] || vMap[i-1].nextSibling); if(!vOutUnwrap) { //On était dans la liste à unwrapper this.unwrapListAddChildren(pUnwrappables, vParent); } vParent = vNewStruct; vOutUnwrap = ! vMap[i]; } } //On traite la dernière série if( ! vOutUnwrap) { //On était dans la liste à unwrapper this.unwrapListAddChildren(pUnwrappables, vParent); } } else { //Tous les fils sont à dewrapper, on dewrap tout le container vParent. var vGrandParentClass = this.fClasses[vParent.parentNode.nodeName]; if(vGrandParentClass.isParaParent) { //On va supprimer la struct vParent (et ses balises esclaves). //On purge vParent des noeuds à préserver. var vNodesToMove = []; var vCh = vParent.firstChild; while(vCh) { var vClass = this.fClasses[vCh.nodeName]; if(vClass.isParaSibling || vClass.nameForParaSibling) { //if( ! this.isNodeEmpty(vCh)) vNodesToMove.push(vCh); //On va déplacer vCh } else { //On est sur une struct intermédiaire (item d'une liste,...). if(vCh.hasChildNodes()) { vCh = vCh.firstChild; continue; } } while(! vCh.nextSibling && vCh !== vParent) vCh = vCh.parentNode; vCh = (vCh === vParent) ? null : vCh.nextSibling; } if(vNodesToMove.length > 0) this.unwrapMoveElts(vNodesToMove, pNodesToSel, vParent.parentNode, vParent.nextSibling); //On suppr vParent this.deleteElt(vParent); //On élimine le 1er noeud déplacé si il est vide (issu du double entrée...) //if(vNodesToMove.length > 1 && this.isNodeEmpty(vNodesToMove[0])) this.deleteElt(vNodesToMove[0]); } else { //On a des balises intermédiaires, on remonte d'un cran pour unwrapper un objet fils d'un ParaParent. //On saute les structures intermédiaires qui ne seraient pas splitables (VARLISTENTRY). //var vParentUnwrap = vParent; //while( ! vGrandParentClass.isSplitable) { // vParentUnwrap = vParentUnwrap.parentNode; // vGrandParentClass = this.fClasses[vParentUnwrap.parentNode.nodeName]; //} //this.unwrapListAdd(pUnwrappables, vParentUnwrap); this.unwrapListAdd(pUnwrappables, vParent); } } } } ]]> = 0 ; i--){ var vNode = this.fNodes[i]; var vNext = null; if(this.fOldPosition[i]>=0) { vNext = this.fOldParents[i].firstChild; for(var k = this.fOldPosition[k]; vNext && k>0; k--) vNext = vNext.nextSibling; } if(vNode.fRenamed) { while(vNode.fRenamed.hasChildNodes()){ vNode.insertBefore(vNode.fRenamed.lastChild, vNode.firstChild); } this.fOldParents[i].insertBefore(vNode, vNext); vNode.fRenamed.parentNode.removeChild(vNode.fRenamed); } else { this.fOldParents[i].insertBefore(vNode, vNext); } } }catch(e) {xed.debug("unwrapMoveElts.undoTransaction::"+e)}; }; vTrans.redoTransaction = vTrans.doTransaction; for(var i = 0; i < vTrans.fNodes.length; i++){ var vNode = vTrans.fNodes[i]; vTrans.fOldParents[i] = vNode.parentNode; if(this.fClasses[vNode.nodeName].nameForParaSibling) { vNode.fRenamed = this.fHTMLEditor.document.createElement(this.fClasses[vNode.nodeName].nameForParaSibling); var vAttrs = vNode.attributes; for(var iA=vAttrs.length-1; iA>=0; iA--) { vNode.fRenamed.setAttribute(vAttrs[iA].name, vAttrs[iA].value); } pNodesToSel.push(vNode.fRenamed); } else { pNodesToSel.push(vNode); } } this.fHTMLEditor.doTransaction(vTrans); ]]> 0) { vEndNode = vEndNode.childNodes.item(vRange.endOffset-1); } //On remonte au bloc susceptible d'etre wrapppé. while(vEndNode) { if( vStartNode.nodeType == 1 && this.fClasses[vEndNode.nodeName].isParaSibling) break; vEndNode = vEndNode.parentNode; } } if(vStartNode && vEndNode){ function getDeep(pNode){ var vDeep = 0; while(pNode) { vDeep++; pNode = pNode.parentNode; } return vDeep; } var vStartDeep = getDeep(vStartNode); var vEndDeep = getDeep(vEndNode); //On se place à la même profondeur for(; vStartDeep > vEndDeep; vStartDeep--) {vStartNode = vStartNode.parentNode;} for(; vEndDeep > vStartDeep; vEndDeep--) {vEndNode = vEndNode.parentNode;} var vNewParent; var vDoc = this.fHtmlRoot.ownerDocument; switch(pTagName) { case "dir" : //On vérifie que ce ne sont que des para var vNode = vStartNode; while(vNode){ if(vNode.nodeName != "PARA") { xed.setTemporaryNotif(xed.getEditor(this), "Une liste simple ne peut contenir que des paragraphes, ce qui n\'est pas le cas de votre sélection.", "NotAllowed", 6); return; } vNode = (vNode == vEndNode) ? null : vNode.nextSibling; } //On crée la liste var vList = vDoc.createElement(pTagName); if(pRole) vList.setAttribute("role", pRole); vList.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); this.fHTMLEditor.insertNode(vList, vStartNode.parentNode, this.getOffsetInParent(vStartNode)); //On remplace les para par des member vNode = vStartNode; var vPos = 0; while(vNode) { var vNextNode = (vNode == vEndNode) ? null : vNode.nextSibling; this.deleteElt(vNode); var vMember = vDoc.createElement("member"); vMember.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); this.fHTMLEditor.insertNode(vMember, vList, vPos++); var vCh = vNode.firstChild; var vPos2 = 0; while(vCh) { var vNextCh = vCh.nextSibling; this.deleteElt(vCh); this.fHTMLEditor.insertNode(vCh, vMember, vPos2++); vCh = vNextCh; } vNode = vNextNode; } this.checkForEdit(vList, true); this.fRichTextInput.setDirty(true); this.addTransSelForRedo(); return; case "ul" : case "ol" : var vList = vDoc.createElement(pTagName); vList.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); if(pRole) vList.setAttribute("role", pRole); var vParent = vStartNode.parentNode; var vOffset = this.getOffsetInParent(vStartNode); var vNode = vStartNode; while(vNode) { var vNextNode = (vNode == vEndNode) ? null : vNode.nextSibling; vNewParent = vDoc.createElement("litem"); vNewParent.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); this.deleteElt(vNode); this.fHTMLEditor.insertNode(vNode, vNewParent, 0); vList.appendChild(vNewParent); vNode = vNextNode; } this.fHTMLEditor.insertNode(vList, vParent, vOffset); this.checkForEdit(vList, true); this.setCaretInBlock(this.getNextEditableBlock(vList, 0)); this.fRichTextInput.setDirty(true); this.addTransSelForRedo(); return; /* case "variableList" : var vList = vDoc.createElement("variableList"); if(pRole) vList.setAttribute("role", pRole); vList.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); var vEntry = vDoc.createElement("varListEntry"); vEntry.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); var vTerm = vDoc.createElement("term"); vTerm.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); vNewParent = vDoc.createElement("varListItem"); vNewParent.setAttribute("id", xed.getEditor(this.fRichTextInput).generateId("t")); vEntry.appendChild(vTerm); vEntry.appendChild(vNewParent); vList.appendChild(vEntry); this.fHTMLEditor.insertNode(vList, vStartNode.parentNode, this.getOffsetInParent(vStartNode)); var vNode = vStartNode; var vPos = 0; while(vNode) { var vNextNode = (vNode == vEndNode) ? null : vNode.nextSibling; this.deleteElt(vNode); this.fHTMLEditor.insertNode(vNode, vNewParent, vPos++); vNode = vNextNode; } this.fRichTextInput.setDirty(true); this.addTransSelForRedo(); return; */ } } } finally { this.fHTMLEditor.endTransaction(); } ]]> = 0; i--) { var vRow = vRowsIdxToDel[i]; if(vRow) { //On supprime cette ligne. var vPrevCell = null; var vCellsToMove = null; var vCellsToReduce = null; for(var c = 0; c < vColCount.value; c++) { var vCell = vTableEd.getCellAt(vTable, i, c); if(vCell != vPrevCell) { //Cell non encore traitée if(vCell.parentNode==vRow) { //La cell appartient à la row if(vCell.rowSpan>1) { //mais elle span la row suivante, on va la déplacer et décrémenter son rowSpan if(!vCellsToMove) vCellsToMove = []; vCellsToMove.push({fCell:vCell, fOldParent:vRow, fOldNextS:vCell.nextSibling, fNewRowIdx:i, fNewColIdx:c, fNewParent:vRow.nextElementSibling}); } } else { //Cell d'une ligne supérieure, on décrémente le rowSpan if(!vCellsToReduce) vCellsToReduce = []; vCellsToReduce.push(vCell); } } vPrevCell = vCell; } this.deleteElt(vRow); if(vCellsToReduce) { var vTrans = { fCells : vCellsToReduce, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ for each (var vCel in this.fCells) vCel.rowSpan--; } vTrans.undoTransaction = function(){ for each (var vCel in this.fCells) vCel.rowSpan++; } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); } if(vCellsToMove) { var vTrans = { fCellsToMove : vCellsToMove, fTable : vTable, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ for(var k=0; k < this.fCellsToMove.length; k++) { var vData = this.fCellsToMove[k]; var vNewTr = vData.fNewParent; var vPrevCol = vData.fNewColIdx-1; var vCell = vPrevCol>=0 ? vTableEd.getCellAt(this.fTable, vData.fNewRowIdx, vPrevCol) : null; while(vCell && vCell.parentNode!=vNewTr && vPrevCol>=0) { vCell = vTableEd.getCellAt(this.fTable, vData.fNewRowIdx, --vPrevCol); } if(vCell) { vNewTr.insertBefore(vData.fCell, vCell.nextSibling); } else { vNewTr.insertBefore(vData.fCell, vNewTr.firstChild); } vData.fCell.rowSpan--; } } vTrans.undoTransaction = function(){ for(var k=this.fCellsToMove.length-1; k>=0; k--) { var vData = this.fCellsToMove[k]; vData.fOldParent.insertBefore(vData.fCell, vData.fOldNextS); vData.fCell.rowSpan++; } } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); } } } this.checkForEdit(vTable, true); //Dans le cas où toutes les rows on été suppr. this.addTransRedraw(vTable); this.addTransRefresh(); //En attendant de gérer la sel } finally { this.fHTMLEditor.endTransaction(); } this.fRichTextInput.setDirty(true); ]]> = 0; i--) { var vPrevCol = vColNode ? vColNode.previousSibling : null; if(vColsIdxToDel[i] == true) { var vNodes = []; var vCellsToReduce = null; if(vColNode) vNodes.push(vColNode); var vPrevCell = null; for(var k = 0; k < vRowCount.value; k++) { var vCell = vTableEd.getCellAt(vTable, k, i); if(vCell != vPrevCell && vCell!=null) { //Cell non déjà traitée if(vCell.colSpan > 1) { if(vCellsToReduce==null) vCellsToReduce = []; vCellsToReduce.push(vCell); } else { vNodes.push(vCell); } } vPrevCell = vCell; } if(vNodes.length > 0) this.deleteElts(vNodes); if(vCellsToReduce) { var vTrans = { fCells : vCellsToReduce, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ for each (var vCel in this.fCells) vCel.colSpan--; } vTrans.undoTransaction = function(){ for each (var vCel in this.fCells) vCel.colSpan++; } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); } } vColNode = vPrevCol; while(vColNode && vColNode.nodeName!="COL") vColNode = vColNode.previousSibling; } this.checkForEdit(vTable, true); //Dans le cas où toutes les coll on été suppr. this.setCaretInBlock(this.getNextEditableBlock(vParent, vOffset) || this.getPreviousEditableBlock(vParent, vOffset)); this.addTransSelForRedo(); this.addTransRedraw(vTable); this.fRichTextInput.setDirty(true); } finally { this.fHTMLEditor.endTransaction(); } ]]> 1 && ! vClassTable.isColSpanAllowed(vTable)) return null; if(vCountRow>1 && ! vClassTable.isRowSpanAllowed(vTable)) return null; //On vérifie qu'un rectangle parfait soit sélectionné var vCheckSel = []; for(var i = 0; i vRowIdx.value) return 1; return vCol1 - vColIdx.value; }); this.fHTMLEditor.beginTransaction(); try { this.addTransSelForUndo(); var vTrans = { fCells : vCells, fXbl : this, merge : function(pTrans){return false;}, isTransient : false }; //Préparation var vCell = vCells[0]; vTrans.fOldRowSpan = vCell.rowSpan; vTrans.fOldColSpan = vCell.colSpan; vTrans.fCellsChildren = []; vTrans.fCellsParent = []; vTrans.fCellsNextSibling = []; for(var i = 1; i < vCells.length; i++) { vTrans.fCellsParent[i] = vCells[i].parentNode; vTrans.fCellsNextSibling[i] = vCells[i].nextSibling; vTrans.fCellsChildren[i] = []; var vCh = vCells[i].firstChild; while(vCh) { vTrans.fCellsChildren[i].push(vCh); vCh = vCh.nextSibling; } } vTrans.doTransaction = function(){ var vCell = this.fCells[0]; vCell.rowSpan = this.fCells.fFutureRowSpan; vCell.colSpan = this.fCells.fFutureColSpan; for(var i = 1; i < this.fCells.length; i++) { this.fCellsParent[i].removeChild(this.fCells[i]); for each (var vCh in this.fCellsChildren[i]) { if(this.fXbl.isNodeEmpty(vCh)) { vCh.parentNode.removeChild(vCh); } else { vCell.appendChild(vCh); } } } this.fXbl.redrawNode(vCell.parentNode.parentNode); var vSel = this.fXbl.fHTMLEditor.selection; vSel.removeAllRanges(); var vRange = this.fXbl.fHTMLEditor.document.createRange(); vRange.selectNode(vCell); vSel.addRange(vRange); } vTrans.undoTransaction = function(){ var vCell = this.fCells[0]; vCell.rowSpan = this.fOldRowSpan; vCell.colSpan = this.fOldColSpan; for(var i = this.fCells.length-1; i > 0; i--) { for each (var vCh in this.fCellsChildren[i]) this.fCells[i].appendChild(vCh); this.fCellsParent[i].insertBefore(this.fCells[i], this.fCellsNextSibling[i]); } this.fXbl.redrawNode(vCell.parentNode.parentNode); } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); this.fRichTextInput.setDirty(true); } finally { this.fHTMLEditor.endTransaction(); } ]]> 1 || vCell.colSpan>1) vResults.push(vCell); vCell = vTableEd.getNextSelectedCell(this.fObj); } return vResults.length>0 ? vResults : null; ]]> 1) { var vTr = vCell.parentNode; var vOffsetRow={}; var vOffsetCol={}; var vTableEd = this.fXbl.fHTMLEditor.QueryInterface(Components.interfaces.nsITableEditor); vTableEd.getCellIndexes(vCell, vOffsetRow, vOffsetCol); for (var r=1; r < vOldRowSpan; r++) { vTr = vTr.nextElementSibling; if(!vTr) break; var vNextCell = vTableEd.getCellAt(vTr.parentNode, vOffsetRow.value + r, vOffsetCol.value); this.duplicateCell(vCell, this.fOldColSpan[i], vTr, vNextCell); } } } this.fXbl.redrawNode(this.fCells[0].parentNode.parentNode); this.updateSel(); }catch(e){ xed.debug("unspan failed : "+e); } } vTrans.duplicateCell = function(pCell, pCount, pNewParent, pNewNextSibling){ var vRole = pCell.getAttribute("role"); var vDoc = pCell.ownerDocument; for (var c=0; c < pCount; c++) { var vNewTD = vDoc.createElement("td"); if(vRole) vNewTD.setAttribute("role", vRole); pNewParent.insertBefore(vNewTD, pNewNextSibling); this.fXbl.checkForEdit(vNewTD, false); this.fNewCells.push(vNewTD); } } vTrans.updateSel = function(){ //Gestion de la sélection var vSel = this.fXbl.fHTMLEditor.selection; vSel.removeAllRanges(); var vDoc = this.fXbl.fHTMLEditor.document; for (var i=0; i < this.fCells.length; i++) { var vRange = vDoc.createRange(); vRange.selectNode(this.fCells[i]); vSel.addRange(vRange); } for (var i=0; i < this.fNewCells.length; i++) { var vRange = vDoc.createRange(); vRange.selectNode(this.fNewCells[i]); vSel.addRange(vRange); } } vTrans.undoTransaction = function(){ this.fNewCellsParent = []; this.fNewCellsNextSibling = []; for (var i=0; i < this.fNewCells.length; i++) { var vCell = this.fNewCells[i]; this.fNewCellsParent[i] = vCell.parentNode; this.fNewCellsNextSibling[i] = vCell.nextSibling; vCell.parentNode.removeChild(vCell); } for (var i=0; i < this.fCells.length; i++) { var vCell = this.fCells[i]; vCell.rowSpan = this.fOldRowSpan[i]; vCell.colSpan = this.fOldColSpan[i]; } this.fXbl.redrawNode(this.fCells[0].parentNode.parentNode); } vTrans.redoTransaction = function(){ for (var i=0; i < this.fCells.length; i++) { var vCell = this.fCells[i]; vCell.removeAttribute("rowSpan"); vCell.removeAttribute("colSpan"); } for (var i=this.fNewCells.length-1; i >= 0; i--) { var vCell = this.fNewCells[i]; this.fNewCellsParent[i].insertBefore(this.fNewCells[i], this.fNewCellsNextSibling[i]); } this.fXbl.redrawNode(this.fCells[0].parentNode.parentNode); this.updateSel(); } this.fHTMLEditor.doTransaction(vTrans); this.fRichTextInput.setDirty(true); } finally { this.fHTMLEditor.endTransaction(); } ]]> 0) { vW = this.computeTDWidthFromScWidth(vW); for(var i = 0; i < vColsIdx.length; i++) { if(vColsIdx[i] == true) { this.fHTMLEditor.setAttribute(vCol, "width", vW); } if(vCol) vCol = vCol.nextSibling; while(vCol && vCol.nodeName!="COL") vCol = vCol.nextSibling; } } } else { for(var i = 0; i < vColsIdx.length; i++) { if(vColsIdx[i] == true) { var vW = vCol.offsetWidth || 10; vW *= pPercent; this.fHTMLEditor.setAttribute(vCol, "width", Math.round(vW)); } if(vCol) vCol = vCol.nextSibling; while(vCol && vCol.nodeName!="COL") vCol = vCol.nextSibling; } } this.checkTableWidth(vTable, true); this.addTransRefresh(); this.fRichTextInput.setDirty(true); } finally { this.fHTMLEditor.endTransaction(); } ]]> 8 0) { this.fHTMLEditor.selection.collapse(pNodeToDel, pFromRight ? pNodeToDel.length : 0); //On laisse le delete de Moz opérer this.fHTMLEditor.deleteSelection(pFromRight ? 2 : 1); } else { //text vide, on passe la main if(pFromRight && pNodeToDel.previousSibling) { this.deleteByCaret(pNodeToDel.previousSibling, pFromInside, pFromRight); } else if( ! pFromRight && pNodeToDel.nextSibling) { this.deleteByCaret(pNodeToDel.nextSibling, pFromInside, pFromRight); } else { this.deleteByCaret(pNodeToDel.parentNode, true, pFromRight); } } break; } }catch(e){xed.debug("deleteByCaret"+e);} ]]> 1) return; var vRange = vSel.getRangeAt(0); var vStart = vRange.startContainer; var vStartOffset = vRange.startOffset; var vEnd = vRange.endContainer; var vEndOffset = vRange.endOffset; var vAncestor = vRange.commonAncestorContainer; vSel.collapseToStart(); //On dégage la sel sinon, des problèmes de refresh apparaissent var vDelStack = []; while(vStart !== vAncestor) { if(vStart.nodeType == 3) { if(vStartOffset == 0) { //On supprime le noeud text vStartOffset = this.getOffsetInParent(vStart); vStart = vStart.parentNode; continue; } else { this.deleteText(vStart, vStartOffset, vStart.data.length); } } else { this.xDeleteSiblings(vStart, vStart.childNodes[vStartOffset], vStart.lastChild, vDelStack); } vStartOffset = this.getOffsetInParent(vStart) + 1; vStart = vStart.parentNode; } while(vEnd !== vAncestor) { if(vEnd.nodeType == 3) { var vLen = vEnd.data.length; if(vLen == vEndOffset) { //On supprime le noeud text vEndOffset = this.getOffsetInParent(vEnd)+1; vEnd = vEnd.parentNode; continue; } else { this.deleteText(vEnd, 0, vEndOffset); } } else if(vEndOffset > 0){ this.xDeleteSiblings(vEnd, vEnd.firstChild, vEnd.childNodes[vEndOffset-1], vDelStack); } vEndOffset = this.getOffsetInParent(vEnd); vEnd = vEnd.parentNode; } if(vAncestor.nodeType == 3) { this.deleteText(vAncestor, vStartOffset, vEndOffset); } else if(vEndOffset > vStartOffset) { this.xDeleteSiblings(vAncestor, vAncestor.childNodes[vStartOffset], vAncestor.childNodes[vEndOffset-1], vDelStack); } this.deleteElts(vDelStack); this.checkForEdit(vAncestor, true); this.controlSelection(vSel); //Cas d'une sel curieuse de paragraphe sur click droit à droite d'un paragraphe. }catch(e){xed.debug("richTextZone.deleteSelection::"+e);} ]]> pStart) { var vTrans = { fTextNode : pTextNode, fData : pTextNode.data.substring(pStart, pEnd), fStart : pStart, fEnd : pEnd, fHTMLEditor : this.fHTMLEditor, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ this.fTextNode.deleteData(this.fStart, this.fEnd - this.fStart); } vTrans.undoTransaction = function(){ this.fTextNode.insertData(this.fStart , this.fData); } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); } }catch(e){xed.debug("richTextZone.deleteText::"+e);} ]]> =0 ; i--) { var vN = this.fNodes[i]; this.fParents[i] = vN.parentNode; this.fNexts[i] = vN.nextSibling; vN.parentNode.removeChild(vN); } } vTrans.undoTransaction = function(){ for(var i = 0; i < this.fNodes.length; i++) { this.fParents[i].insertBefore(this.fNodes[i], this.fNexts[i]); } } vTrans.redoTransaction = function(){ for(var i = this.fNodes.length - 1; i >=0 ; i--) { var vN = this.fNodes[i]; vN.parentNode.removeChild(vN); } } this.fHTMLEditor.doTransaction(vTrans); ]]> =0 ; i--) { this.fParent.removeChild(this.fNodes[i]); } } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); ]]> 0) vNode = pParent.childNodes[pOffset-1]; if(vNode && vNode.nodeType == 3) { pParent = vNode; pOffset = vNode.data.length; } else { //Pas de noeud text autour, on crée un nouveau noeud. this.insertElt(this.fHTMLEditor.document.createTextNode(pCdata), pParent, pParent.childNodes[pOffset]); return; } } } var vTrans = { fTextNode : pParent, fOffset : pOffset, fInsertText : pCdata, fZoneEditor : this, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ this.fTextNode.insertData(this.fOffset, this.fInsertText); var vSel = this.fZoneEditor.fHTMLEditor.selection; var vOri = vSel.anchorNode; var vOriOffset = vSel.anchorOffset; var vEndOffset = this.fOffset+this.fInsertText.length; vSel.collapse(this.fTextNode, vEndOffset); if(this.fZoneEditor.inlineSpellChecker) { this.fZoneEditor.inlineSpellChecker.spellCheckAfterEditorChange ( 1001, vSel, vOri, vOriOffset, null, 0, null, 0); this.fZoneEditor.inlineSpellChecker.spellCheckAfterEditorChange ( 1001, vSel, vOri, vOriOffset, this.fTextNode, this.fOffset , this.fTextNode, vEndOffset); } } vTrans.undoTransaction = function(){ this.fTextNode.deleteData(this.fOffset, this.fInsertText.length); this.fZoneEditor.fHTMLEditor.selection.collapse(this.fTextNode, this.fOffset); } vTrans.redoTransaction = function(){ this.doTransaction(); } this.fHTMLEditor.doTransaction(vTrans); ]]> pRange.startOffset) { vFirst = pRange.startContainer.childNodes[pRange.startOffset]; } else { vFirst = (pRange.startOffset > 0) ? pRange.startContainer.childNodes[pRange.startOffset-1] : pRange.startContainer; vNeedNext = true; } } else vFirst = pRange.startContainer; if(vFirst && (vNeedNext || vFirst.nodeType!=1)) { //On cherche le suivant if(vFirst.firstElementChild) vFirst = vFirst.firstElementChild; else { while(vFirst && ! vFirst.nextElementSibling) vFirst = vFirst.parentNode; if(vFirst) vFirst = vFirst.nextElementSibling; } } if(vFirst) { //First trouvé, on cherche le last var vLast; var vLookForDeepestLast = false; if(pRange.endContainer.nodeType == 1) { if(pRange.endOffset > 0) { vLast = pRange.endContainer.childNodes[pRange.endOffset-1]; vLookForDeepestLast = true; } else vLast = pRange.endContainer; } else vLast = pRange.endContainer; if(vLast.nodeType!=1) { //noeud text on remonte if(vLast.previousElementSibling) { vLast = vLast.previousElementSibling; vLookForDeepestLast = true; } else vLast = vLast.parentNode; } if(vLookForDeepestLast) { var vDeepest; while( (vDeepest=vLast.lastElementChild) ) vLast = vDeepest; } if(vFirst==vLast || (vFirst.compareDocumentPosition(vLast) & 4)){ //Trouvé vWalker.fFirst = vFirst; vWalker.fLast = vLast; vWalker.fCurrent = vFirst; } } return vWalker; ]]> = pParent.data.length : pParent.childNodes.length){ return this.pasteAsInline(pNodeRoot, vElParent.parentNode, this.getOffsetInParent(vElParent)+1, pEraseId); } case 7: //On est au milieu du TextLeaf ou dans un TextBlock, donc on insert un nouveau noeud text. return this.pasteAsCDATA(pNodeRoot.textContent, pParent, pOffset, pEraseId); case 6: case 0: //On crée un para là où on a le droit pParent = this.insertParaBlock(pParent, pOffset); if(pParent) { pOffset = 0; } else { return null; } case 3: case 4: case 5: //De l'inline est autorisé, on insert l'inline, on simule un paragraphe. var vFrag = this.fHTMLEditor.document.createDocumentFragment(); this.xml2html(pNodeRoot, vFrag, pEraseId, pParent); vFrag.normalize(); //Fusion des noeuds texte frères this.checkForEdit(vFrag, false); if( ! vFrag.hasChildNodes()) return null; if(vFrag.childNodes.length == 1 && vFrag.firstChild.nodeType == 3) { return this.pasteAsCDATA(vFrag.firstChild.data, pParent, pOffset, pEraseId); } var vTrans = { fParent : pParent, fOffset : pOffset, fFrag : vFrag, fXbl : this, fHTMLEditor : this.fHTMLEditor, merge : function(pTrans){return false;}, isTransient : false }; vTrans.doTransaction = function(){ //xed.debug(this.fInsertText+" - "+this.fOffset); if( ! this.fLeftNode) { //1er passage (pas en redo), on prépare if(this.fParent.nodeType == 3) { if(this.fOffset == 0) { this.fLeftNode = this.fParent.previousSibling; this.fRightNode = this.fParent; this.fOffset = this.fXbl.getOffsetInParent(this.fParent); this.fParent = this.fParent.parentNode; } else if(this.fOffset >= this.fParent.data.length){ this.fLeftNode = this.fParent; this.fRightNode = this.fParent.nextSibling; this.fOffset = this.fXbl.getOffsetInParent(this.fParent)+1; this.fParent = this.fParent.parentNode; } else { //on prépare pour splitter le text this.fSplitTextParent = true; this.fLeftNode = this.fParent; this.fRightNode = this.fHTMLEditor.document.createTextNode(this.fParent.data.substring(this.fOffset)); this.fOffset = this.fXbl.getOffsetInParent(this.fParent)+1; this.fParent = this.fParent.parentNode; } } else { this.fLeftNode = (this.fOffset > 0) ? this.fParent.childNodes.item(this.fOffset-1) : null; this.fRightNode = (this.fOffset < this.fParent.childNodes.length) ? this.fParent.childNodes.item(this.fOffset) : null; } } if(this.fSplitTextParent) { //On doit splitter le text parent var vRightLen = this.fRightNode.data.length; this.fLeftNode.deleteData(this.fLeftNode.data.length - vRightLen, vRightLen); this.fParent.insertBefore(this.fRightNode, this.fLeftNode.nextSibling); } //On traite la fusion des noeuds text au début if(this.fLeftNode && this.fLeftNode.nodeType == 3 && this.fFrag.firstChild.nodeType == 3) { //On fusionne this.fMergedFirstNode = this.fFrag.firstChild; this.fFrag.removeChild(this.fMergedFirstNode); this.fLeftNode.appendData(this.fMergedFirstNode.data); } //On traite la fusion des noeuds text à la fin if(this.fRightNode && this.fRightNode.nodeType == 3 && this.fFrag.lastChild.nodeType == 3) { //On fusionne this.fMergedLastNode = this.fFrag.lastChild; this.fFrag.removeChild(this.fMergedLastNode); this.fRightNode.insertData(0, this.fMergedLastNode.data); } //On boucle sur tous les noeuds restant du fragment while(this.fFrag.hasChildNodes()) { var vCh = this.fFrag.firstChild; this.fFrag.removeChild(vCh); this.fParent.insertBefore(vCh, this.fRightNode); } } vTrans.undoTransaction = function(){ //On boucle sur tous les noeuds restant du fragment var vCh = this.fRightNode ? this.fRightNode.previousSibling : this.fParent.lastChild; while(vCh && vCh != this.fLeftNode) { var vPrevCh = vCh.previousSibling; this.fParent.removeChild(vCh); this.fFrag.insertBefore(vCh, this.fFrag.firstChild); vCh = vPrevCh; } //On traite la fusion des noeuds text à la fin if(this.fMergedLastNode) { this.fFrag.appendChild(this.fMergedLastNode); this.fRightNode.deleteData(0, this.fMergedLastNode.data.length); } //On traite la fusion des noeuds text au début if(this.fMergedFirstNode) { this.fFrag.insertBefore(this.fMergedFirstNode, this.fFrag.firstChild); this.fLeftNode.deleteData(this.fLeftNode.length - this.fMergedFirstNode.data.length, this.fLeftNode.length); } //On traite le split if(this.fSplitTextParent) { this.fLeftNode.appendData(this.fRightNode.data); this.fParent.removeChild(this.fRightNode); } } vTrans.redoTransaction = vTrans.doTransaction; this.fHTMLEditor.doTransaction(vTrans); var vRange = this.fHTMLEditor.document.createRange(); if(vTrans.fMergedFirstNode) { vRange.setStart(vTrans.fLeftNode, vTrans.fLeftNode.length - vTrans.fMergedFirstNode.data.length); } else { vRange.setStart(vTrans.fParent, vTrans.fOffset); } if(vTrans.fRightNode) { vRange.setEnd(vTrans.fRightNode, vTrans.fMergedLastNode ? vTrans.fMergedLastNode.data.length : 0); } else { vRange.setEnd(vTrans.fParent, vTrans.fParent.childNodes.length); } return vRange; } }catch(e){xed.debug("pasteAsInline::"+e)} ]]> pOffset ? pParent.childNodes.item(pOffset) : pParent; while(vNode) { //On remonte la hiérarchie if(vNode.nodeType == 3) { //Si ce texte n'est pas vide, on n'est pas en bordure du paragrpahe. if(vNode.data.length > 0) break; } else { var vType = this.fClasses[vNode.nodeName].type; if(vType == 1) { //ObjectLeaf => on n'est pas en bordure du paragrpahe. break; } else if(vType == 5) { var vRes = this.pasteAsTextDtd(pNodeRoot, vNode.parentNode, this.getOffsetInParent(vNode)+1, pEraseId); if(vRes && vNode.nextSibling && this.isNodeEmpty(vNode)) this.deleteElt(vNode); return vRes; } } if(vNode.nextSibling) { vNode = vNode.nextSibling; } else { vNode = vNode.parentNode; } } } //On essaye de sortir avant le block if(pParent.nodeType != 3 || pOffset == 0) { //On n'est pas dans un cdata ou en bordure d'un cdata var vNode = (pParent.nodeType == 3) ? pParent.previousSibling || pParent.parentNode : pOffset > 0 ? pParent.childNodes.item(pOffset-1) : pParent; while(vNode) { //On remonte la hiérarchie if(vNode.nodeType == 3) { //Si ce texte n'est pas vide, on n'est pas en bordure du paragrpahe. if(vNode.data.length > 0) break; } else { var vType = this.fClasses[vNode.nodeName].type; if(vType == 1) { //ObjectLeaf => on n'est pas en bordure du paragrpahe. break; } else if(vType == 5) { return this.pasteAsTextDtd(pNodeRoot, vNode.parentNode, this.getOffsetInParent(vNode), pEraseId); } } if(vNode.previousSibling) { vNode = vNode.previousSibling; } else { vNode = vNode.parentNode; } } } //On est au milieu d'un paragraphe, on split var vBlock = this.getEditableBlockFromNode(pParent); if( ! this.fClasses[vBlock.nodeName].isClonable) return null; //block non splittable var vNextBlock = this.splitBlock(vBlock, pParent, pOffset); var vRes = this.pasteAsTextDtd(pNodeRoot, vBlock.parentNode, this.getOffsetInParent(vBlock)+1, pEraseId); if(vRes && vBlock.nextSibling && this.isNodeEmpty(vBlock)) this.deleteElt(vBlock); return vRes; case 7: //TextBlock -> term //On essaye de sortir du textBlock if(vElParent.previousSibling == null && pOffset == 0) { //On est sur au début du 1er term, on remonte au dessus de l'entrée de la liste return this.pasteAsTextDtd(pNodeRoot, vElParent.parentNode.parentNode, this.getOffsetInParent(vElParent.parentNode), pEraseId); } var vNextBlock = this.getNextEditableBlock(vElParent, 0); if( ! vNextBlock || this.fClasses[vNextBlock.nodeName].type == 7) { xed.setTemporaryNotif(xed.getEditor(this), "Il est impossible d\'insérer ce contenu à cet emplacement.", "NotAllowed", 6); return null; } return this.pasteAsTextDtd(pNodeRoot, vNextBlock.parentNode, this.getOffsetInParent(vNextBlock), pEraseId); case 0: //Body case 6: //Structure //xed.debug("insert in Structure:::"+vElParent.localName+"\npNodeRoot ::: "+xed.getXml(pNodeRoot)); if(vElParent.nodeName == "DIR") { //On transforme tous les parablocks/textblock pour les insérer en member de la liste var vThis = this; var vNodeToInsert = []; function insertBlock(pXmlParent) { var vCh = pXmlParent.firstChild; while(vCh) { var vClass = vThis.fClasses._xml[vCh.localName]; if(vClass) { if(vClass.type==5 || vClass.type==7) { //xed.debug("pParent::\n"+xed.getXml(pParent)); var vNewPara = vThis.fHTMLEditor.document.createElement("member"); //xed.debug("c::\n"+xed.getXml(vNewPara)); //xed.debug("vCh::\n"+xed.getXml(vCh)); vThis.xml2html(vCh, vNewPara, pEraseId, vElParent); vThis.checkForEdit(vNewPara, false); vNodeToInsert.push(vNewPara); //xed.debug("result::\n"+xed.getXml(vNewPara)); } else if(vClass.type==6) { //on descend pour chercher les blocks para (type 5 ou 7) insertBlock(vCh); } } vCh = vCh.nextSibling; } } insertBlock(pNodeRoot); if(vNodeToInsert.length>0) { this.insertElts(vNodeToInsert, vElParent, vElParent.childNodes.item(pOffset)); var vRange = this.fHTMLEditor.document.createRange(); vRange.setStart(pParent, pOffset); vRange.setEnd(pParent, pOffset + vNodeToInsert.length); return vRange; } else return null; } else if(vParentClass.isParaParent){ //On supprime tout ce qui n'est pas un block valide var vCh = pNodeRoot.firstChild; while(vCh) { var vClass = this.fClasses._xml[vCh.localName]; if(vClass && vClass.type >= 5 && vClass.type <= 7 && vClass.isParaSibling) { vCh = vCh.nextSibling; } else { var vNewCh = vCh.nextSibling; pNodeRoot.removeChild(vCh); vCh = vNewCh; } } var vFrag = this.fHTMLEditor.document.createDocumentFragment(); this.xml2html(pNodeRoot, vFrag, pEraseId, vElParent); this.checkForEdit(vFrag, false); //xed.debug("insert in Structure HTML:::"+xed.getXml(vFrag)); if(vFrag.hasChildNodes()) { var vRange = this.fHTMLEditor.document.createRange(); vRange.setStart(vElParent, pOffset); var vNodeToInsert = []; while(vFrag.hasChildNodes()) vNodeToInsert.push(vFrag.removeChild(vFrag.firstChild)); this.insertElts(vNodeToInsert, vElParent, vElParent.childNodes.item(pOffset)); vRange.setEnd(vElParent, pOffset + vNodeToInsert.length); return vRange; } return null; } else { var vTagDef = vParentClass.getStructuralNodes(vElParent); xed.setTemporaryNotif(xed.getEditor(this), xed.formatStr("?syntax=Formatter;Il est impossible d'insérer ce contenu à cet emplacement : %s", vTagDef ? vTagDef.title : vElParent.nodeName), "NotAllowed", 6); return null; } } return null; }catch(e){xed.debug("pasteAsTextDtd::"+e)} ]]> = vLen) { this.deleteByCaret(vNode.nextSibling || vNode.parentNode, ! vNode.nextSibling, false); } else if(vOffset == vLen-1){ this.deleteText(vNode, vLen-1, vLen); //pour empêcher la suppr du noeud text. } else { this.fHTMLEditor.deleteSelection(1); } } else { this.deleteByCaret(vOffset >= vNode.childNodes.length ? vNode : vNode.childNodes.item(vOffset), (vOffset >= vNode.childNodes.length), false); } } else { this.fHTMLEditor.beginTransaction(); try{ this.addTransSelForUndo(); this.deleteSelection(); //this.controlSelection(this.fHTMLEditor.selection); this.addTransSelForRedo(); }finally { this.fHTMLEditor.endTransaction(); } } this.fRichTextInput.setDirty(true); ]]> "+pString+"" : pString, "text/xml"); if(vDom.documentElement.localName == "parsererror" && vDom.documentElement.namespaceURI == "http://www.mozilla.org/newlayout/xml/parsererror.xml") { //Echec au parsing : on tente de le formater pour préserver les retours charriot, etc. return this.pasteStringToFormat(pString, pParent, pOffset, pEraseId); } var vNodeRoot = (vRootAdded) ? vDom.documentElement : vDom; xed.debug("pasteXmlString::vDom::::::"+xed.getXml(vDom)); var vTypeContent = this.filterAsTextFragment(vNodeRoot); switch(vTypeContent) { case 0 : //Rien reconnu (peut-etre de l'html...), on extrait le texte pur qu'on colle. if("textContent" in vNodeRoot) return this.pasteAsCDATA(vNodeRoot.textContent, pParent, pOffset); break; case 1 : //Text pur (dans du xml, donc pas de tentative d'interprétation des retours charriot, etc.) if("textContent" in vNodeRoot) return this.pasteAsCDATA(vNodeRoot.textContent, pParent, pOffset); return this.pasteAsCDATA(pString, pParent, pOffset, pEraseId); case 2 : //contenu contenant des éléments de la dtd inline return this.pasteAsInline(vNodeRoot, pParent, pOffset, pEraseId); case 3 : //contenu contenant des éléments de la dtd text complète if(this.isEditorWithBlocks) return this.pasteAsTextDtd(vNodeRoot, pParent, pOffset, pEraseId); } return null; }catch(e){xed.debug("pasteXmlString::"+e)} ]]> 1) { var vDoc = document.implementation.createDocument(null, null, null); var vFrag = vDoc.createDocumentFragment(); for(var i = 0; i < vStrings.length; i++) { if(/\S/.test(vStrings[i])) vFrag.appendChild(vDoc.createElementNS(SCNS, "sc:para")).appendChild(vDoc.createTextNode(this.filterString(vStrings[i].trim()))); } return this.pasteAsTextDtd(vFrag, pParent, pOffset, pEraseId); } else { return this.pasteAsCDATA(pString, pParent, pOffset, pEraseId); } } else { return this.pasteAsCDATA(pString, pParent, pOffset, pEraseId); } ]]> var vNode = this.fLastHtmlFocus; if(!vNode) return; var vClass = this.fClasses[vNode.nodeName]; var vStructuralNode = null; var vCurrentSNode = null; while(vClass.type != 0){ var vS = ("getStructuralNodes" in vClass) ? vClass.getStructuralNodes(vNode) : null; if(vS) { if(vStructuralNode == null) { vStructuralNode = vS; vCurrentSNode = vS; } else { vCurrentSNode.parent = vS; vCurrentSNode = vS; } } vNode = vNode.parentNode; if(!vNode) break; vClass = this.fClasses[vNode.nodeName]; } return vStructuralNode; try{ this.openSubWindowEditor(pStructNode.urlLinkEditor, pStructNode._node); }catch(e){xed.debug("openLinkEditor::"+e);} try{ this.openSubWindowEditor(pStructNode.urlSubEditor, pStructNode._node); }catch(e){xed.debug("openSubEditor::"+e);} =vNode.data.length) { vNode.parentNode.insertBefore(this._TmpDragImg, vNode.nextSibling); } else { //Au milieu du texte vNode.parentNode.insertBefore(this._TmpDragImg, vNode); this._TmpDragTextInserted = this.fHTMLEditor.document.createTextNode(vNode.data.substring(0, vStart)); vNode.parentNode.insertBefore(this._TmpDragTextInserted, this._TmpDragImg); vNode.deleteData(0, vStart); } } else { var vClass = this.fClasses[vNode.nodeName]; if( ! vClass.isInlineSibling && vClass.type!=5 && vClass.type!=7){ //Caret en dehors des zones de contenu. vNode = this.getNextEditableBlock(vNode, vStart) || this.getPreviousEditableBlock(vNode, vStart); this.setCaretInBlock(vNode); vNode = vRange.startContainer; vStart = vRange.startOffset; } this._TmpDragCanDrop = 2; vNode.insertBefore(this._TmpDragImg, vNode.childNodes.item(vStart)); } } else { //Sélection if(this.getBlockWrappingSel()) { //Drop Autorisé. this._TmpDragCanDrop = 3; } } ]]> var vCtx = {}; var vCh = pParentNode.firstElementChild; while(vCh) { if(vCh.fAction && vCh.fAction.refresh) vCh.fAction.refresh(vCh, vCtx); vCh = vCh.nextElementSibling; } =112 && vKey<=123) vStopPropagation = false; switch(vKey) { case 9 : //pEvent.DOM_VK_TAB case 13 : //pEvent.DOM_VK_RETURN case 14 : //pEvent.DOM_VK_ENTER vStopPropagation = false; break; default : pEvent.preventDefault(); break; } } return; } switch(vKey){ case 0 : break; case 27 : //pEvent.DOM_VK_ESCAPE pEvent.preventDefault(); vStopPropagation = false; break; case 9 : //pEvent.DOM_VK_TAB pEvent.preventDefault() this.inlineSpellCheckHandleNav(pEvent); if( ! vSel.isCollapsed) vSel.collapseToStart(); var vTD = vSel.anchorNode; while(vTD && vTD.nodeName != "TD") vTD = vTD.parentNode; if(vTD) { if(pEvent.shiftKey) { var vNextTD = vTD.previousSibling; while(vNextTD && vNextTD.nodeName != "TD") vNextTD = vNextTD.previousSibling; if(vNextTD) this.moveCaretIn(vNextTD, true); else { var vTR = vTD.parentNode; var vNextTR = vTR.previousSibling; while(vNextTR && vNextTR.nodeName != "TR") vNextTR = vNextTR.previousSibling; if(vNextTR) { vNextTD = vNextTR.lastChild; while(vNextTD && vNextTD.nodeName != "TD") vNextTD = vNextTD.previousSibling; if(vNextTD) this.moveCaretIn(vNextTD, true); } } } else { var vNextTD = vTD.nextSibling; while(vNextTD && vNextTD.nodeName != "TD") vNextTD = vNextTD.nextSibling; if(vNextTD) { this.moveCaretIn(vNextTD, true); } else { var vTR = vTD.parentNode; var vNextTR = vTR.nextSibling; while(vNextTR && vNextTR.nodeName != "TR") vNextTR = vNextTR.nextSibling; if(vNextTR) { vNextTD = vNextTR.firstChild; while(vNextTD && vNextTD.nodeName != "TD") vNextTD = vNextTD.nextSibling; if(vNextTD) this.moveCaretIn(vNextTD, true); } else { this.fHTMLEditor.beginTransaction(); try{ this.addTransSelForUndo(); var vNewTr = this.insertRowInTable(vTR.parentNode, vTR.nextSibling, this.fClasses.TR.getDefaultRole(null, vTR.parentNode)); this.moveCaretIn(vNewTr, true); this.addTransSelForRedo(); this.fRichTextInput.setDirty(true); } finally { this.fHTMLEditor.endTransaction(); } } } } } else { vStopPropagation = false; } break; case 13 : //pEvent.DOM_VK_RETURN case 14 : //pEvent.DOM_VK_ENTER pEvent.preventDefault(); if( ! this.isEditorWithBlocks) { vStopPropagation = false; break; } if(! vRange) break; // sel multiple d'un tableau : on ne fait rien this.fHTMLEditor.beginTransaction(); try{ this.addTransSelForUndo(); if(! vSel.isCollapsed){ this.deleteSelection(); //this.controlSelection(vSel); vRange = vSel.getRangeAt(0); } var vPara = this.getEditableBlockFromNode(vRange.startContainer); if(vPara && this.fClasses[vPara.nodeName].isClonable) { var vPrev = vPara.previousElementSibling; if(this.isNodeEmpty(vPara) || (vPrev && this.fClasses[vPrev.nodeName].isClonable && this.isPointOnFirstPosition(vPara, vRange.startContainer, vRange.startOffset) && this.isNodeEmpty(vPrev))) { if( ! this.unwrap()) { var vNewBlockDoc = this.newBlockOnDoubleReturn(vPara.parentNode); if(vNewBlockDoc) { this.pasteAsTextDtd(vNewBlockDoc, vPara.parentNode, this.getOffsetInParent(vPara), true); this.fRichTextInput.setDirty(true); this.controlSelection(vSel); } } } else { var vNext = this.splitBlock(vPara, vRange.startContainer, vRange.startOffset); this.setCaretInBlock(vNext); this.fRichTextInput.setDirty(true); this.inlineSpellCheckHandleNav(pEvent); } } this.addTransSelForRedo(); } finally { this.fHTMLEditor.endTransaction(); } break; case 8 : //DOM_VK_BACK_SPACE pEvent.preventDefault(); if(xed.isAccelPress(pEvent)) { //Ctrl+backSpace = unwrap this.unwrap(); break; } if(vSel.isCollapsed){ var vNode = vRange.startContainer; var vOffset = vRange.startOffset; if(vNode.nodeType==3) { if(vOffset == 0) { this.deleteByCaret(vNode.previousSibling || vNode.parentNode, ! vNode.previousSibling, true); } else if(vOffset == 1){ this.deleteText(vNode, 0, 1); //pour empêcher la suppr du noeud text. } else { this.fHTMLEditor.deleteSelection(2); } } else { this.deleteByCaret(vOffset == 0 ? vNode : vNode.childNodes.item(vOffset-1), (vOffset == 0), true); } } else { this.fHTMLEditor.beginTransaction(); try{ this.addTransSelForUndo(); if(vRange) { this.deleteSelection(); } else { var vTableEd = this.fHTMLEditor.QueryInterface(Components.interfaces.nsITableEditor); var vCell = vTableEd.getFirstSelectedCell(this.fObj); var vCells = []; var vListElt = []; while(vCell){ vCells.push(vCell); var vCh = vCell.firstChild; while(vCh){ vListElt.push(vCh); vCh = vCh.nextSibling; } vCell = vTableEd.getNextSelectedCell(this.fObj); } this.deleteElts(vListElt); for each(var vCell in vCells) this.checkForEdit(vCell, true); } //this.controlSelection(vSel); this.addTransSelForRedo(); }finally { this.fHTMLEditor.endTransaction(); } } this.fRichTextInput.setDirty(true); break; case 46 : //DOM_VK_DELETE pEvent.preventDefault(); this.cmdDelete(); break; case 37 : //DOM_VK_LEFT if(pEvent.ctrlKey || pEvent.shiftKey || pEvent.metaKey) break; if(!vRange) break; this.inlineSpellCheckHandleNav(pEvent); var vNode = vRange.startContainer; var vOffset = vRange.startOffset; if(vOffset==0) { this.moveCaretOut(vNode.firstChild||vNode, true, true); pEvent.preventDefault(); } else if(vNode.nodeType==3){ //On est au milieu d'un texte, comportement standard } else if(vOffset == vNode.childNodes.length) { this.moveCaretIn(vNode.childNodes.item(vOffset-1), false); pEvent.preventDefault(); } else { this.moveCaretOut(vNode.childNodes.item(vOffset), true, true); pEvent.preventDefault(); } break; case 39 : //DOM_VK_RIGHT if(pEvent.ctrlKey || pEvent.shiftKey || pEvent.metaKey) break; if(!vRange) break; this.inlineSpellCheckHandleNav(pEvent); var vNode = vRange.endContainer; var vOffset = vRange.endOffset; if(vNode.nodeType == 3) { if(vOffset == vNode.data.length) { this.moveCaretOut(vNode, false, true); pEvent.preventDefault(); } else { //On est au milieu d'un texte, comportement standard } } else { if(vOffset == vNode.childNodes.length) { this.moveCaretOut(vOffset==0 ? vNode : vNode.lastChild, false, true); } else if(vOffset==0){ this.moveCaretIn(vNode.firstChild, true); } else { this.moveCaretOut(vNode.childNodes.item(vOffset-1), false, true); } pEvent.preventDefault(); } break; case 33 : //page up case 34 : //page down case 35 : //Fin de ligne case 36 : //Début de ligne case 40 : //pEvent.DOM_VK_DOWN case 38 : //pEvent.DOM_VK_UP this.inlineSpellCheckHandleNav(pEvent); break; } //Touches F1 -> F12, on laisse sortir l'pEvent if(vKey>=112 && vKey<=123) vStopPropagation = false; if(vCar > 0) { //xed.debug("car="+vCar+" - pEvent.ctrlKey::"+pEvent.ctrlKey + " - shift:"+pEvent.shiftKey); if(xed.isAccelPress(pEvent)) { switch(vCar) { case 99 : // C pEvent.preventDefault(); this.cmdCopy(); break; case 120 : // X pEvent.preventDefault(); this.cmdCut(); break; case 118 : // V pEvent.preventDefault(); this.cmdPaste(); break; case 121 : // Y case 122 : // Z this.fRichTextInput.setDirty(true); break; case 32 : // espace if(pEvent.shiftKey) { // -> espace inseccable this.fHTMLEditor.QueryInterface(Components.interfaces.nsIPlaintextEditor).insertText(this.fNbspCar); this.fRichTextInput.setDirty(true); } else { // -> menu contextuel this.showContextMenu(pEvent); } break; case 100 : // D xed.debug(xed.getXml(this.fHtmlRoot)); default: //Autre action en CTRL + qqchose : on passe aux bindings paramétrables. vStopPropagation = this.onKeyBinding(vCar, pEvent); } } else { //Saisie d'un car if(! vRange) { pEvent.preventDefault(); return; } var vUpdated = false; if( ! vSel.isCollapsed){ vUpdated = true; this.fHTMLEditor.beginTransaction(); try{ this.addTransSelForUndo(); this.deleteSelection(); //this.controlSelection(vSel); this.addTransSelForRedo(); } finally { this.fHTMLEditor.endTransaction(); } } if(vCar==32){ //On check qu'il n'y ait pas déjà un espace autour. var vNode = vRange.startContainer; if(vNode.nodeType==3) { var vOffset = vRange.startOffset; if( (vOffset != 0 && vNode.data.charAt(vOffset-1) == ' ') ) { pEvent.preventDefault(); if(vUpdated) this.fRichTextInput.setDirty(true); return; } if(vOffset < vNode.data.length && vNode.data.charAt(vOffset) == ' ') { vSel.collapse(vNode, vOffset + 1); pEvent.preventDefault(); if(vUpdated) this.fRichTextInput.setDirty(true); return; } } } this.fRichTextInput.setDirty(true); var vNode = vRange.startContainer; var vStart = vRange.startOffset; if(vNode.nodeType==1 && vStart > 0) { var vPrev = vNode.childNodes.item(vStart-1); if(vPrev.nodeType==3) { vNode = vPrev; vStart = vNode.data.length; } } if(vNode.nodeType==3) { if(vStart > 0){ var vPrevCharCode = vNode.data.charCodeAt(vStart - 1); //ponctuation française sauf ':' suivant un protocole, comportement normal if((xed.getCurrentLang().indexOf("fr")>=0 && (vCar==59 || vCar==33 || vCar==63 || (vCar==58 && ! /\bmailto$|\b(ht|s?f)tp(s?)$/.test(vNode.data.substring(vStart-5, vStart))) )) ) { var vTrans = { fXbl : this, doTransaction : function(){ if(vPrevCharCode == 32) { vNode.replaceData(vStart-1, 1, this.fXbl.fNbspCar); vNode.insertData(vStart, String.fromCharCode(vCar)); vSel.collapse(vNode, vStart+1); } else { vNode.insertData(vStart, String.fromCharCode(this.fXbl.fNbspCar.charCodeAt(0), vCar)); vSel.collapse(vNode, vStart+2); } }, undoTransaction : function(){ if(vPrevCharCode == 32) vNode.replaceData(vStart-1, 2, " "); else vNode.deleteData(vStart, 2); vSel.collapse(vNode, vStart); }, redoTransaction : function(){ this.doTransaction(); }, isTransient : false, merge : function(pTrans){return false;} } this.fHTMLEditor.doTransaction(vTrans); pEvent.preventDefault(); } } } } } } catch(e){ xed.debug(this.tagName+"->keypress :\n"+e); } finally { if(vStopPropagation) pEvent.stopPropagation(); } ]]> this.refresh(); ?"; document.getAnonymousNodes(this)[0].innerHTML = vContent; ]]> this.refresh(); var vIframe = document.getAnonymousElementByAttribute(this, "anonid", "iframe"); var vEvent = vIframe.ownerDocument.createEvent("Events"); vEvent.initEvent("ScText_init", false, false); vIframe.parentNode.dispatchEvent(vEvent); document.getAnonymousElementByAttribute(this, "anonid", "box") document.getAnonymousElementByAttribute(this, "anonid", "area") document.getAnonymousElementByAttribute(this, "anonid", "ct") var vText = document.getAnonymousElementByAttribute(this, "anonid", "text"); var vX = Math.round(this.fBox.boxObject.width / 20); var vY = Math.round(this.fBox.boxObject.height / 20); vText.setAttribute("value", vX + " x "+ vY); //xed.debug("mousemove"); try { var vTarget = event.originalTarget; switch(vTarget.localName) { case "stack" : case "box" : this.fBox.width = Math.max(1, Math.ceil((event.pageX - this.fBox.boxObject.x) / 20))*20; this.fBox.height = Math.max(1, Math.ceil((event.pageY - this.fBox.boxObject.y) / 20))*20; break; case "hbox" : this.fArea.height = Math.min(500, this.fArea.boxObject.height + 20); this.sizeTo(this.fCt.boxObject.width, this.fCt.boxObject.height); break; case "vbox" : this.fArea.width = Math.min(400, this.fArea.boxObject.width + 20); this.sizeTo(this.fCt.boxObject.width, this.fCt.boxObject.height); } this.refresh(); } catch(e) { xed.debug(e); } event.stopPropagation(); var vNbRow = Math.round(this.fBox.boxObject.height / 20); var vNbCol = Math.round(this.fBox.boxObject.width / 20); const SCNS = "http://www.utc.fr/ics/scenari/v3/core"; var vXmlDoc = this.ownerDocument.implementation.createDocument(null, null, null); var vTable = vXmlDoc.appendChild(vXmlDoc.createElementNS(SCNS, "sc:table")); vTable.setAttribute("role", this.fRole); var vW = Math.max(5, 100/vNbCol); for(var i = 0 ; i < vNbCol; i++) { vTable.appendChild(vXmlDoc.createElementNS(SCNS, "column")).setAttribute("width", vW); } for(var i = 0 ; i < vNbRow; i++) { var vRow = vTable.appendChild(vXmlDoc.createElementNS(SCNS, "sc:row")); for(var k = 0 ; k < vNbCol; k++) { vRow.appendChild(vXmlDoc.createElementNS(SCNS, "sc:cell")); } } this.fEditorZone.insertTable(vXmlDoc); this.hidePopup();