1 function ActiveSourceTree(aEditor)
3 this.mOldSourceElt = null;
4 this.mOneEltSelected = false;
5 this.mOldSelectedLi = null;
8 this.mEditedNode = null;
10 this.mMutationsEnabled = true;
12 this.mSourceTreeXULElement = null;
15 this.mRefuseNextMergeTransaction = false;
17 this.startup(aEditor);
20 ActiveSourceTree.prototype.startup =
23 function ActiveSourceTreeContentListener(aActiveSourceTree)
25 this.init(aActiveSourceTree);
28 ActiveSourceTreeContentListener.prototype = {
30 init : function(aActiveSourceTree)
32 this.mActiveSourceTree = aActiveSourceTree;
35 QueryInterface : function(aIID)
37 if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
38 aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
39 aIID.equals(Components.interfaces.nsISupports))
41 throw Components.results.NS_NOINTERFACE;
44 onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
46 const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
48 if (aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT)
50 if (aStateFlags & nsIWebProgressListener.STATE_STOP)
52 this.mActiveSourceTree.postStartup();
57 onProgressChange : function(aWebProgress, aRequest,
58 aCurSelfProgress, aMaxSelfProgress,
59 aCurTotalProgress, aMaxTotalProgress)
62 onLocationChange : function(aWebProgress, aRequest, aLocation)
65 onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
68 onSecurityChange : function(aWebProgress, aRequest, aState)
72 var sourceTreeDeck = gDialog.sourceTreeDeck;
74 var browser = document.createElement("browser");
75 browser.setAttribute("flex", "1");
77 sourceTreeDeck.appendChild(browser);
78 sourceTreeDeck.selectedPanel = browser;
80 this.mSourceTreeXULElement = browser;
81 this.mEditor = aEditor;
82 browser.setAttribute("src", "chrome://bluegriffon/content/sourceViewTemplate.html");
83 var docShell = browser.docShell;
84 var progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
85 var progressListener = new ActiveSourceTreeContentListener(this);
86 progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
91 ActiveSourceTree.prototype.postStartup =
94 this.mSourceTreeXULElement.contentWindow.startup();
95 this.addEditorListeners();
96 this.addSourceTreeListeners();
98 this.serializeInSourceTree();
101 ActiveSourceTree.prototype.shutdown =
104 this.removeEditorListeners();
105 this.removeSourceTreeListeners()
109 ActiveSourceTree.prototype.addEditorListeners =
112 var doc = this.mEditor.contentDocument;
115 doc.addEventListener("DOMAttrModified", function(aEvent){_self.onBrowserMutateAttribute(aEvent)}, false);
116 doc.addEventListener("DOMNodeInserted", function(aEvent){_self.onBrowserMutateNode(aEvent)}, false);
117 doc.addEventListener("DOMNodeRemoved", function(aEvent){_self.onBrowserMutateNode(aEvent)}, false);
118 doc.addEventListener("DOMCharacterDataModified", function(aEvent){_self.onBrowserMutateText(aEvent)}, false);
120 NotifierUtils.addNotifierCallback("selection", function(a,b,c){_self.onBrowserSelectionChanged(a,b,c)}, this);
123 ActiveSourceTree.prototype.removeEditorListeners =
126 var doc = this.mEditor.contentDocument;
129 doc.removeEventListener("DOMAttrModified", function(aEvent){_self.onBrowserMutateAttribute(aEvent)}, false);
130 doc.removeEventListener("DOMNodeInserted", function(aEvent){_self.onBrowserMutateNode(aEvent)}, false);
131 doc.removeEventListener("DOMNodeRemoved", function(aEvent){_self.onBrowserMutateNode(aEvent)}, false);
132 doc.removeEventListener("DOMCharacterDataModified", function(aEvent){_self.onBrowserMutateText(aEvent)}, false);
134 NotifierUtils.removeNotifierCallback("selection", function(a,b,c){_self.onBrowserSelectionChanged(a,b,c)});
137 ActiveSourceTree.prototype.addSourceTreeListeners =
140 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
143 sourceDoc.addEventListener("mousemove", function(aEvent){_self.onSourceViewMouseMove(aEvent)}, true);
144 sourceDoc.addEventListener("click", function(aEvent){_self.onSourceViewClick(aEvent)}, true);
145 sourceDoc.addEventListener("keypress", function(aEvent){_self.onSourceViewKeyPress(aEvent)}, true);
146 sourceDoc.addEventListener("blur", function(aEvent){_self.onSourceViewBlur(aEvent)}, true);
147 sourceDoc.addEventListener("DOMCharacterDataModified", function(aEvent){_self.onSourceViewMutateText(aEvent)}, false);
150 ActiveSourceTree.prototype.removeSourceTreeListeners =
153 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
156 sourceDoc.removeEventListener("mousemove", function(aEvent){_self.onSourceViewMouseMove(aEvent)}, true);
157 sourceDoc.removeEventListener("click", function(aEvent){_self.onSourceViewClick(aEvent)}, true);
158 sourceDoc.removeEventListener("keypress", function(aEvent){_self.onSourceViewKeyPress(aEvent)}, true);
159 sourceDoc.removeEventListener("blur", function(aEvent){_self.onSourceViewBlur(aEvent)}, true);
160 sourceDoc.removeEventListener("DOMCharacterDataModified", function(aEvent){_self.onSourceViewMutateText(aEvent)}, false);
163 ActiveSourceTree.prototype.onSourceViewBlur =
166 var target = aEvent.target;
168 target.nodeType == Node.ELEMENT_NODE &&
169 target.getAttribute("contenteditable") == "true")
170 this.mRefuseNextMergeTransaction = true;
172 this.mOneEltSelected = false;
173 if (this.mOldSelectedLi)
174 this.mOldSelectedLi.removeAttribute("selected");
175 this.mOldSelectedLi = null;};
177 ActiveSourceTree.prototype.serializeInSourceTree =
180 this.cleanupSourceTree();
182 this.mMutationsEnabled = false;
184 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
185 var doc = this.mEditor.contentDocument;
187 // create the initial UL that will hold the root element
188 var currentUL = sourceDoc.createElement("ul");
189 sourceDoc.body.appendChild(currentUL);
191 this.addEltToSourceView(sourceDoc,
195 this.mMutationsEnabled = true;
198 ActiveSourceTree.prototype.addEltToSourceView =
199 function(aDoc, aNode, aCurrentUL)
204 switch (aNode.nodeType)
207 li = this.createSourceViewForTextNode(aDoc, aNode, aCurrentUL);
208 aCurrentUL.appendChild(li);
209 if (!aNode.data.match( /\S/g ))
210 li.setAttribute("style", "display: none");
212 case Node.ELEMENT_NODE:
213 if (aNode.nodeName.toLowerCase() != "br" ||
214 aNode.getAttribute("type") != "_moz")
216 li = this.createSourceViewForElementNode(aDoc, aNode, aCurrentUL, null);
217 aCurrentUL.appendChild(li);
223 aNode = aNode.nextSibling;
227 ActiveSourceTree.prototype.createSourceViewForTextNode =
228 function(aDoc, aNode, aCurrentUL)
230 var span = aDoc.createElement("span");
231 span.setAttribute("class", "textNode");
233 var t = aDoc.createTextNode(aNode.data);
234 var li = aDoc.createElement("li");
235 var id = this.getRandomID();
236 li.setAttribute("id", id);
237 li.setAttribute("contenteditable", "true");
239 li.appendChild(span);
240 li.setUserData("originalNode", aNode, null);
241 aNode.setUserData("sourceViewID", id, null);
242 li.setAttribute("empty", "true");
246 ActiveSourceTree.prototype.createSourceViewForElementNode =
247 function(aDoc, aNode, aCurrentUL, aCurrentLI)
254 var id = this.getRandomID();
255 li = aDoc.createElement("li");
256 li.setAttribute("id", id);
257 aNode.setUserData("sourceViewID", id, null);
260 var img = aDoc.createElement("img");
261 img.setAttribute("src", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADgSURBVHjalFFLDgFBFKw2RAwJiVjYOIA4gI0zuI6jOAFrC4mt2FhYij0SvxHjMxmjP1r3zCBMCJW87uq86pfqaiKlxK+I66UzGMvhZPZRVC2XUK9VCPTkRrMrvyHsB5M1hOAgJOCGkQDnTDEJRi+vNjQYoyEL3kCViNEznIP9EMfu5HrlSKXSqjL+2TQzyOYK6pIXnSyEwH6/VTtDPl/EZj3H5ezCc09R8dG24KkmD+1sV3OfC9/7m3hnLeAcbXBK0e+1YS2nflKGoSXpp1jn2BrpnJNhRXPWIP/84E2AAQCcuIfwPqAmjQAAAABJRU5ErkJggg==");
262 img.setAttribute("class", "minusTwisty");
265 var img = aDoc.createElement("img");
266 img.setAttribute("src", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADHSURBVHjalJE9CsJAEIXfEsEihTfwAOIBbDyD1/EonsDewhPYWFiJ2FgIFjYRE2PIz/5k3DExQRZFH+wPzDePt7OCiPCrOrwtVjta708fodGgj8l4KMDO09mSvqmuV84sYzSEaN2qdAQli/cYLKXkC2tgJTMkt9CFy1LD93tO3uNh68LGGETRxZ4KVJJtNiiyFHl6d+E4DJDborZxiMrnw/lutHLha3BGEofQ0sJNboLnMeK3MM9xvuE5d+vlzpkl/vnBhwADALPWiKYmr0SBAAAAAElFTkSuQmCC");
267 img.setAttribute("class", "plusTwisty");
270 var lt = aDoc.createTextNode("<");
273 var span = aDoc.createElement("span");
274 span.setAttribute("class", "tagName");
275 var tagName = aNode.nodeName.toLowerCase();
276 var t = aDoc.createTextNode(tagName);
278 li.appendChild(span);
280 if (aNode.attributes.length)
282 var attributes = aNode.attributes;
283 for (var i = 0; i < attributes.length; i++)
285 var name = attributes[i].nodeName;
286 if (name.substr(0, 4) == "_moz")
289 // the @ in the line below is here because of bug 455992
290 span = aDoc.createElement("span");
291 span.setAttribute("class", "at-separator");
292 span.appendChild(aDoc.createTextNode("@"));
293 li.appendChild(span);
295 span = aDoc.createElement("span");
296 span.setAttribute("class", "attrName");
297 span.setAttribute("originalAttrName", name);
298 span.setAttribute("contenteditable", "true");
299 span.appendChild(aDoc.createTextNode(name));
300 li.appendChild(span);
302 li.appendChild(aDoc.createTextNode("=\""));
304 span = aDoc.createElement("span");
305 span.setAttribute("class", "attrValue");
306 span.setAttribute("originalAttrName", name);
307 span.setAttribute("contenteditable", "true");
308 span.appendChild(aDoc.createTextNode(attributes[i].nodeValue));
309 li.appendChild(span);
311 li.appendChild(aDoc.createTextNode("\""));
315 if (tagName == "style" ||
316 tagName == "script" ||
318 li.setAttribute("class", "pre-content");
319 li.appendChild(aDoc.createTextNode(">"));
320 li.setUserData("originalNode", aNode, null);
324 if (aNode.firstChild)
326 var newUL = aDoc.createElement("ul");
327 li.appendChild(newUL);
329 this.addEltToSourceView(aDoc, aNode.firstChild, newUL);
332 li.setAttribute("empty", "true");
338 ActiveSourceTree.prototype.getRandomID =
341 return "moz" + new Date().valueOf() +
342 "_" + Math.round(Math.random() * 100000);
345 ActiveSourceTree.prototype.onBrowserMutateNode =
348 if (!this.mMutationsEnabled)
351 this.mMutationsEnabled = false;
353 var target = aEvent.target;
354 var parent = aEvent.relatedNode;
355 var removal = aEvent.type == "DOMNodeRemoved";
357 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
360 var sourceViewID = target.getUserData("sourceViewID");
363 this.mMutationsEnabled = true;
366 var sourceTarget = sourceDoc.getElementById(sourceViewID);
369 this.mMutationsEnabled = true;
372 var sourceParent = sourceTarget.parentNode;
373 sourceParent.removeChild(sourceTarget);
374 if (!sourceParent.childNodes.length)
375 sourceParent.parentNode.removeChild(sourceParent);
379 var sourceViewID = parent.getUserData("sourceViewID");
380 var sourceParent = sourceDoc.getElementById(sourceViewID);
381 var currentUL = null;
382 if (sourceParent.lastChild.nodeName.toLowerCase() == "ul")
383 currentUL = sourceParent.lastChild;
386 currentUL = sourceDoc.createElement("ul");
387 sourceParent.appendChild(currentUL);
390 var nextSibling = target.nextSibling;
391 var sourceNextSibling = null;
394 var sourceViewNextSiblingID = nextSibling.getUserData("sourceViewID");
395 sourceNextSibling = sourceDoc.getElementById(sourceViewNextSiblingID);
399 switch (target.nodeType)
402 if (target.data.match( /\S/g ))
404 li = this.createSourceViewForTextNode(sourceDoc, target, currentUL);
405 currentUL.insertBefore(li, sourceNextSibling);
409 case Node.ELEMENT_NODE:
410 if (target.nodeName.toLowerCase() == "br" &&
411 target.getAttribute("type") == "_moz")
413 li = this.createSourceViewForElementNode(sourceDoc, target, currentUL, null);
414 li.setAttribute("open", "true");
415 currentUL.insertBefore(li, sourceNextSibling);
417 li.setAttribute("selected", "true");
418 if (this.mOldSelectedLi && this.mOneEltSelected)
420 this.mOldSelectedLi.removeAttribute("selected");
422 this.mOneEltSelected = true;
423 this.mOldSelectedLi = li;
429 this.ensureElementIsVisible(this.mSourceTreeXULElement, li);
432 this.mMutationsEnabled = true;
436 ActiveSourceTree.prototype.cleanupSourceTree =
439 this.mMutationsEnabled = false;
441 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
442 sourceDoc.body.innerHTML = "";
444 this.mMutationsEnabled = true;
447 ActiveSourceTree.prototype.onBrowserMutateText =
450 if (!this.mMutationsEnabled)
453 this.mMutationsEnabled = false;
455 var target = aEvent.target;
456 var sourceViewID = target.getUserData("sourceViewID");
457 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
458 var sourceTarget = sourceDoc.getElementById(sourceViewID);
459 sourceTarget.firstChild.firstChild.data = target.data;
461 this.mMutationsEnabled = true;
464 ActiveSourceTree.prototype.onBrowserSelectionChanged =
465 function(aArgs, aElt, aOneElementSelected)
467 if (!this.mMutationsEnabled)
470 var elt = EditorUtils.getSelectionContainer().node;
471 var sourceViewID = elt.getUserData("sourceViewID");
472 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
473 var sourceElt = sourceDoc.getElementById(sourceViewID);
479 if (e.nodeType == Node.ELEMENT_NODE &&
480 e.nodeName.toLowerCase() == "li")
481 e.setAttribute("open", "true");
484 this.ensureElementIsVisible(this.mSourceTreeXULElement, sourceElt);
486 sourceElt.setAttribute("selected", "true");
487 if (this.mOldSelectedLi && this.mOneEltSelected)
489 this.mOldSelectedLi.removeAttribute("selected");
491 this.mOneEltSelected = true;
492 this.mOldSelectedLi = sourceElt;
495 ActiveSourceTree.prototype.onSourceViewMouseMove =
498 if (!this.mMutationsEnabled)
501 if (this.mOneEltSelected)
503 this._onSourceViewMouseMove(aEvent);
507 ActiveSourceTree.prototype._onSourceViewMouseMove =
510 var e = aEvent.originalTarget;
513 if (e != this.mOldSourceElt &&
514 this.mOldSourceElt &&
515 this.mOldSourceElt.style)
517 //this.mOldSourceElt.style.outline = "";
518 if (this.mOldSelectedLi)
519 this.mOldSelectedLi.removeAttribute("selected");
521 this.mOldSourceElt = null;
523 var tagName = e.nodeName.toLowerCase();
524 if (tagName != "li" &&
531 if (this.mOneEltSelected)
532 this.mOldSelectedLi = e;
533 e = e.getUserData("originalNode");
536 this.flash(EditorUtils.getCurrentEditorElement(), e);
540 ActiveSourceTree.prototype.ensureElementIsVisible =
541 function(aXULContainer, aHTMLElement)
546 y += aHTMLElement.offsetTop;
547 aHTMLElement = aHTMLElement.offsetParent;
549 aXULContainer.contentWindow.scroll(0, Math.max(0, y - 10));
552 ActiveSourceTree.prototype.flash =
553 function(aXULContainer, aHTMLElement)
555 this.mOldSourceElt = aHTMLElement;
556 //aHTMLElement.style.outline = "blue solid 2px";
558 this.ensureElementIsVisible(aXULContainer, aHTMLElement);
561 ActiveSourceTree.prototype.onSourceViewClick =
564 if (!this.mMutationsEnabled)
567 var e = aEvent.explicitOriginalTarget;
568 var p = e.parentNode;
569 var currentTag = e.nodeName.toLowerCase();
570 if (e.nodeType == Node.TEXT_NODE &&
571 p.nodeType == Node.ELEMENT_NODE)
573 if (p.className == "tagName")
575 var li = p.parentNode;
576 li.setAttribute("selected", "true");
577 this.mOneEltSelected = true;
578 this._onSourceViewMouseMove(
579 { originalTarget: li }
582 else if (p.className == "textNode" ||
583 p.className == "attrName" ||
584 p.className == "attrValue")
586 this.mEditing = true;
587 this.mEditedNode = p;
588 this.mOneEltSelected = true;
592 this._onSourceViewMouseMove(
593 { originalTarget: p.parentNode.parentNode.firstChild }
598 this._onSourceViewMouseMove(
599 { originalTarget: p.parentNode }
606 else if (this.mOneEltSelected &&
607 (currentTag == "li" ||
608 currentTag == "ul" ||
609 currentTag == "body"))
611 this.mOneEltSelected = false;
612 if (this.mOldSelectedLi)
613 this.mOldSelectedLi.removeAttribute("selected");
614 this.mOldSelectedLi = null;
618 ActiveSourceTree.prototype.getIndexOfNode =
619 function getIndexOfNode(aNode)
623 // the following 3 lines are an excellent suggestion from Neil Rashbrook
624 var range = aNode.ownerDocument.createRange();
625 range.selectNode(aNode);
626 return range.startOffset;
631 ActiveSourceTree.prototype.onSourceViewKeyPress =
634 if (!this.mMutationsEnabled)
637 if (aEvent.keyCode == 27 && // ESCAPE KEY
641 this.mEditing = false;
642 this.mEditedNode.blur();
643 this.mEditedNode = null;
647 ActiveSourceTree.prototype.onSourceViewMutateText = function(aEvent)
649 if (!this.mMutationsEnabled)
652 this.mMutationsEnabled = false;
654 var e = aEvent.originalTarget;
655 if (e.parentNode.nodeName.toLowerCase() == "span")
658 var type = e.parentNode.className;
659 if (type != "textNode" &&
660 type != "attrName" &&
665 switch (e.parentNode.className)
669 var textNode = e.parentNode.parentNode.getUserData("originalNode");
670 var txn = new diTextNodeChangedTxn(this, textNode, e.data);
671 EditorUtils.getCurrentEditor().transactionManager.doTransaction(txn);
676 var targetElement = e.parentNode.parentNode.getUserData("originalNode");
677 var attrName = e.parentNode.getAttribute("originalattrname");
678 var txn = new diAttrChangedTxn(this, targetElement, attrName, e.data);
679 EditorUtils.getCurrentEditor().transactionManager.doTransaction(txn);
684 var targetElement = e.parentNode.parentNode.getUserData("originalNode");
685 var attrName = e.parentNode.getAttribute("originalattrname");
686 var newName = e.data;
687 var txn = new diAttrNameChangedTxn(this, targetElement, attrName, newName);
688 EditorUtils.getCurrentEditor().transactionManager.doTransaction(txn);
689 e.parentNode.setAttribute("originalattrname", newName);
690 e.parentNode.nextSibling.nextSibling.setAttribute("originalattrname", newName);
698 this.mMutationsEnabled = true;
702 ActiveSourceTree.prototype.onBrowserMutateAttribute =
705 if (!this.mMutationsEnabled)
708 var target = aEvent.target;
710 var attrChange = aEvent.attrChange;
711 var attrName = aEvent.attrName;
712 var newValue = aEvent.newValue;
714 // early way out in case of a scrollbar change
715 if (attrName == "curpos" ||
716 attrName.substr(0, 4) == "_moz")
719 this.mMutationsEnabled = false;
721 var sourceViewID = target.getUserData("sourceViewID");
722 var sourceDoc = this.mSourceTreeXULElement.contentDocument;
723 var sourceElt = sourceDoc.getElementById(sourceViewID);
727 case MutationEvent.ADDITION:
728 case MutationEvent.MODIFICATION: break;
729 case MutationEvent.REMOVAL: break;
733 var child = sourceElt.firstChild;
734 while (child && child.nodeName.toLowerCase() != "ul")
736 var tmp = child.nextSibling;
737 sourceElt.removeChild(child);
741 this.createSourceViewForElementNode(sourceDoc, target, sourceElt.parentNode, sourceElt);
742 if (sourceElt.firstChild.nodeName.toLowerCase() == "ul")
743 sourceElt.appendChild(sourceElt.firstChild);
745 this.mMutationsEnabled = true;
749 /********************** diTextNodeChangedTxn **********************/
751 function diTextNodeChangedTxn(aContext, aNode, aData)
753 this.mContext = aContext;
755 this.mOldData = aNode.data;
756 this.mNewData = aData;
759 diTextNodeChangedTxn.prototype = {
761 getNode: function() { return this.mNode; },
762 getOldData: function() { return this.mOldData; },
763 getNewData: function() { return this.mNewData; },
765 QueryInterface : function(aIID)
767 if (aIID.equals(Components.interfaces.nsITransaction) ||
768 aIID.equals(Components.interfaces.diITextNodeChangedTxn) ||
769 aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
770 aIID.equals(Components.interfaces.nsISupports))
772 throw Components.results.NS_NOINTERFACE;
775 doTransaction: function()
777 this.mNode.data = this.mNewData;
780 undoTransaction: function()
782 this.mNode.data = this.mOldData;
785 redoTransaction: function()
787 this.doTransaction();
792 merge: function(aTransaction)
794 var txn = aTransaction.QueryInterface(Components.interfaces.diITextNodeChangedTxn);
797 if (this.getNode() == txn.getNode())
799 if (this.mContext.mRefuseNextMergeTransaction)
800 this.mContext.mRefuseNextMergeTransaction = false;
803 this.mNewData = txn.getNewData();
812 /********************** diAttrChangedTxn **********************/
814 function diAttrChangedTxn(aContext, aNode, aAttrName, aData)
816 this.mContext = aContext;
818 this.mAttrName = aAttrName;
819 this.mAttrWasSet = this.mNode.hasAttribute(this.mAttrName);
820 this.mOldData = this.mNode.getAttribute(this.mAttrName);
821 this.mNewData = aData;
824 diAttrChangedTxn.prototype = {
826 getNode: function() { return this.mNode; },
827 getOldData: function() { return this.mOldData; },
828 getNewData: function() { return this.mNewData; },
829 getAttributeName: function() { return this.mAttrName; },
831 QueryInterface : function(aIID)
833 if (aIID.equals(Components.interfaces.nsITransaction) ||
834 aIID.equals(Components.interfaces.diIAttrChangedTxn) ||
835 aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
836 aIID.equals(Components.interfaces.nsISupports))
838 throw Components.results.NS_NOINTERFACE;
841 doTransaction: function()
843 this.mNode.setAttribute(this.mAttrName, this.mNewData);
846 undoTransaction: function()
848 if (this.mAttrWasSet)
849 this.mNode.setAttribute(this.mAttrName, this.mOldData);
851 this.mNode.removeAttribute(this.mAttrName);
854 redoTransaction: function()
856 this.doTransaction();
861 merge: function(aTransaction)
863 var txn = aTransaction.QueryInterface(Components.interfaces.diIAttrChangedTxn);
866 if (this.getNode() == txn.getNode() &&
867 this.getAttributeName() == txn.getAttributeName())
869 if (this.mContext.mRefuseNextMergeTransaction)
870 this.mContext.mRefuseNextMergeTransaction = false;
873 this.mNewData = txn.getNewData();
882 /********************** diAttrNameChangedTxn **********************/
884 function diAttrNameChangedTxn(aContext, aNode, aOldAttrName, aNewAttrName)
886 this.mContext = aContext;
888 this.mOldAttrName = aOldAttrName;
889 this.mNewAttrName = aNewAttrName;
891 this.mValue = this.mNode.getAttribute(this.mOldAttrName);
894 diAttrNameChangedTxn.prototype = {
896 getNode: function() { return this.mNode; },
897 getNewAttributeName: function() { return this.mNewAttrName; },
900 QueryInterface : function(aIID)
902 if (aIID.equals(Components.interfaces.nsITransaction) ||
903 aIID.equals(Components.interfaces.diIAttrNameChangedTxn) ||
904 aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
905 aIID.equals(Components.interfaces.nsISupports))
907 throw Components.results.NS_NOINTERFACE;
910 doTransaction: function()
912 this.mNode.removeAttribute(this.mOldAttrName);
913 this.mNode.setAttribute(this.mNewAttrName, this.mValue);
916 undoTransaction: function()
918 this.mNode.removeAttribute(this.mNewAttrName);
919 this.mNode.setAttribute(this.mOldAttrName, this.mValue);
922 redoTransaction: function()
924 this.doTransaction();
929 merge: function(aTransaction)
931 var txn = aTransaction.QueryInterface(Components.interfaces.diIAttrChangedTxn);
934 if (this.getNode() == txn.getNode())
936 if (this.mContext.mRefuseNextMergeTransaction)
937 this.mContext.mRefuseNextMergeTransaction = false;
940 this.mNewAttrName = txn.getNewAttributeName();