[Phoenix-commits] rev 14679 - in public/phoenix: misc trunk/phoenix/prototypes/prototype1/src/chrome/content

andi at wyona.com andi at wyona.com
Mon Jun 26 18:28:33 CEST 2006


Author: andi
Date: 2006-06-26 18:28:31 +0200 (Mon, 26 Jun 2006)
New Revision: 14679

Added:
   public/phoenix/misc/conversation_062606_extdev_component-overriding.txt
Modified:
   public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/controller.js
   public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/model.js
   public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/view.js
Log:
The edit state controller is now informed about model state changes via an event listener.


Added: public/phoenix/misc/conversation_062606_extdev_component-overriding.txt
===================================================================
--- public/phoenix/misc/conversation_062606_extdev_component-overriding.txt	2006-06-26 16:20:47 UTC (rev 14678)
+++ public/phoenix/misc/conversation_062606_extdev_component-overriding.txt	2006-06-26 16:28:31 UTC (rev 14679)
@@ -0,0 +1,63 @@
+#extdev
+	[INFO]	Channel view for “#extdev” opened.
+	-->|	YOU have joined #extdev
+	=-=	Topic for #extdev is “Welcome to #extdev, the extension development channel || References: http://developer.mozilla.org/ http://www.xulplanet.com/ http://kb.mozillazine.org/Extension_development || Pastebin: http://mozilla.pastebin.com/ || FAQ: http://developer.mozilla.org/en/docs/Extension_FAQ”
+	=-=	Topic for #extdev was set by Mossop on Mo, 12. Jun 2006 19:22:36 Uhr
+	aw1	Hi! Is it possible to override Mozilla components (like "@mozilla.org/editor/editorcontroller;1") from a component (of course, sticking to the given interface definitions)?
+	aw1	s/from a component/from an extension/
+	asqueella	it should be possible, but I never understood how does mozilla choose the component to use
+	asqueella	register your component with that contractID (but a different CID)
+	aw1	Uhhm, I see. I guess it depends if Mozilla registers its internal components first, or the extension components.
+	aw1	Ok, same contractID, different compnentID.
+	aw1	Do I have to override all component from a given shared object (DLL), or can I pick individual components?
+	asqueella	if they're meant to be overriden, then you should be able to pick individual components
+	aw1	Yeah, sounds sensible! :)
+	aw1	Hey asqueella, thanks a dozen!! :)
+	asqueella	you're welcome
+	luser	you can override them, but i don't know what order they get chosen either
+	luser	i wrote an extension that overrode about:blank at one point
+	aw1	luser, thanks. Maybe I just have to try it out. Well, if they can be overridden, then Mozilla should obviously choose components provided by extensions first. Now, if two extensions ty to override the same component, things might get a bit messy...
+	luser	yes
+	luser	i think that just because you *can* do it doesn't mean you *should* :)
+	aw1	Yeah... On the other hand, the alterative is to provide custom Mozilla builds, which doesn't sound too sweet either.
+	asqueella	why, that's the point of contract ids, isn't it?
+	asqueella	(being able to provide your components adhering to a particular contract)
+	aw1	Yes. But if two extensions provide components for the same contract, then what?
+	asqueella	I was replying to luser
+	aw1	Oh, sorry.
+	asqueella	people installing more than a single extension are in a big trouble anyway ;)
+	aw1	heh :)
+	luser	asqueella: yes, but unless there's a defined rule for choosing among multiple implementations, then the behavior is undefined
+	aw1	Or better: people installing other extensions than *my* extensions are in big trouble...
+	asqueella	luser: which is why I mentioned this problem when I answered the original question
+	-->|	NSA (pwned at F1C75BC9.A45D8B2F.126E0C5B.IP) has joined #extdev
+	luser	yes.
+	asqueella	unfortunately I'm too lazy to find out how is the component to use chosen
+	=-=	NSA is now known as IRCMonkey8142979
+	aw1	luser, yes. For instance, nsEditingSession.cpp makes calls to @mozilla.org/editor/editorcontroller;1, now I'd like to reroute them to my own extensions editorcontroller implementation. Now, if two extensions are trying to do that: doom.
+	aw1	asqueella, should I head over to #developers to find out?
+	aw1	Or are they going to kill me?
+	asqueella	this is the kind of thing I would read the source to figure out
+	asqueella	but I don't think #developers enjoy killing anybody but babies
+	luser	if i were to make a wild-ass-guess, i would say that it probably picks the component that was registered last
+	aw1	asqueella, hmm, ok. So I might have to poke around in the XPCOM registration or discovery code.
+	luser	and that your extension compoents tend to be registered after components in the app directory
+	asqueella	luser: that would be my guess too, and that's why I always assumed it works
+	aw1	luser, yes, sounds reasonable. And the order of extension registration is arbitrary or something.
+	luser	it's the order they're installed in
+	aw1	ok. Anyway, I just hope I'm the only one doing this then, for a given installation.
+	luser	:)
+	asqueella	iirc, the order in the EM window used to matter
+	asqueella	guess it's order in extensions.ini that matters now
+	aw1	Guess I'll show a dialog at startup then, containing, in big fat letters, "if you install anything besides this, don't come to me whining" or something.
+	luser	asqueella: but component registration only happens on installation, doesn't it
+	luser	not on every restart
+	asqueella	luser: assuming something has triggered the autoregistration process
+	asqueella	aw1: technically, almost every extension should show that dialog on startup, so don't bother
+	asqueella	I don't think many people would override something editor-related anyway
+	
+IRCMonkey8142979	mossop!
+	aw1	asqueella, ok. So maybe we could lobby a standard dialog into Mozilla then... ;)
+	aw1	openHitUserOnTheHeadDialog()
+	luser	"your shit is probably already broken"
+	aw1	:)

Modified: public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/controller.js
===================================================================
--- public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/controller.js	2006-06-26 16:20:47 UTC (rev 14678)
+++ public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/controller.js	2006-06-26 16:28:31 UTC (rev 14679)
@@ -122,15 +122,6 @@
         // editor initialisation completed
         gEditorController.editStateController.modelStateChanged("editorinitialised");
 
-        /* TODO: we pretend that the document was modified.
-         * Of course, we should listen to the editor elements
-         * and catch any modifications until we set the model
-         * to be dirty. But since this does not yet work, we
-         * have to make the model dirty here because otherwise,
-         * we couldn't save the document. Remove this hack when
-         * we finally get the editor elements to report changes. */
-        gEditorController.model.setDirty();
-
         PhoenixEditController.updateView();
 
         // give information about the views
@@ -311,9 +302,49 @@
         return (this.currentState & aState) == aState;
     },
 
+    addStateString: function (aString, aStringToAdd) {
+        if (aString == "") {
+            aString += aStringToAdd;
+        } else {
+            aString += " " + aStringToAdd;
+        }
+        return aString;
+    },
+
+    translateState: function (aState) {
+        var stateString = "";
+
+        // translate state to human-readable string
+        if ((aState & this.STATE_SUPERIOR_UNITIALISED) == this.STATE_SUPERIOR_UNITIALISED)
+            stateString = this.addStateString(stateString, "STATE_SUPERIOR_UNITIALISED");
+        if ((aState & this.STATE_UNINITIALISED) == this.STATE_UNINITIALISED)
+            stateString = this.addStateString(stateString, "STATE_UNINITIALISED");
+        if ((aState & this.STATE_DOCUMENTLOADED) == this.STATE_DOCUMENTLOADED)
+            stateString = this.addStateString(stateString, "STATE_DOCUMENTLOADED");
+        if ((aState & this.STATE_DOCUMENTNEW) == this.STATE_DOCUMENTNEW)
+            stateString = this.addStateString(stateString, "STATE_DOCUMENTNEW");
+        if ((aState & this.STATE_NODOCUMENT) == this.STATE_NODOCUMENT)
+            stateString = this.addStateString(stateString, "STATE_NODOCUMENT");
+        if ((aState & this.STATE_SUPERIOR_DOCUMENTOK) == this.STATE_SUPERIOR_DOCUMENTOK)
+            stateString = this.addStateString(stateString, "STATE_SUPERIOR_DOCUMENTOK");
+        if ((aState & this.STATE_DOCUMENTREADY_PRISTINE) == this.STATE_DOCUMENTREADY_PRISTINE)
+            stateString = this.addStateString(stateString, "STATE_DOCUMENTREADY_PRISTINE");
+        if ((aState & this.STATE_DOCUMENTREADY_MODIFIED) == this.STATE_DOCUMENTREADY_MODIFIED)
+            stateString = this.addStateString(stateString, "STATE_DOCUMENTREADY_MODIFIED");
+        if ((aState & this.STATE_SUPERIOR_EDITORREADY) == this.STATE_SUPERIOR_EDITORREADY)
+            stateString = this.addStateString(stateString, "STATE_SUPERIOR_EDITORREADY");
+        if ((aState & this.STATE_DOCUMENTOK) == this.STATE_DOCUMENTOK)
+            stateString = this.addStateString(stateString, "STATE_DOCUMENTOK");
+        if ((aState & this.STATE_NODOCUMENT_READY) == this.STATE_NODOCUMENT_READY)
+            stateString = this.addStateString(stateString, "STATE_NODOCUMENT_READY");
+
+        return stateString;
+    },
+
     illegalTransition: function (aTransition, aState) {
-        /* DEBUG */ dump("Phoenix:controller.js:PhoenixEditStateController.illegalTransition: transition \"" + aTransition + "\" not allowed on state \"" + aState + "\"\n");
-        throw new PhoenixEditorException("Illegal transition \"" + aTransition + "\" on state \"" + aState + "\".");
+        /* DEBUG */ dump("Phoenix:controller.js:PhoenixEditStateController.illegalTransition: transition \"" + aTransition + "\" not allowed on state \"" + aState + " (" + this.translateState(aState) + ")\"\n");
+
+        throw new PhoenixEditorException("Illegal transition \"" + aTransition + "\" on state \"" + aState + " (" + this.translateState(aState) + ")\".");
     },
 
     modelStateChanged: function (aTransition) {
@@ -356,13 +387,13 @@
                         if (gEditorController.neutronIntrospection) {
                             if (gEditorController.neutronIntrospection.queryFragmentSaveURI(gEditorController.currentNeutronFragment)) {
                                 // enable save operation
-                                document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", false);
+                                document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", true);
                                 document.getElementById("uiFileOperationSave").setAttribute("disabled", false);
                             }
                             if (gEditorController.neutronIntrospection.queryFragmentCheckinURI(gEditorController.currentNeutronFragment)) {
                                 // enable checkin operation
                                 // TODO: at the moment, <save> == <checkin>
-                                document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", false);
+                                document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", true);
                                 document.getElementById("uiFileOperationSave").setAttribute("disabled", false);
                             }
                         }
@@ -384,6 +415,18 @@
             case "modified":
                 if (this.currentState == this.STATE_DOCUMENTREADY_PRISTINE) {
                     this.currentState = this.STATE_DOCUMENTREADY_MODIFIED;
+                    // check for introspection (save and checkin)
+                    if (gEditorController.neutronIntrospection) {
+                        if (gEditorController.neutronIntrospection.queryFragmentSaveURI(gEditorController.currentNeutronFragment)) {
+                            // enable save operation
+                            document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", false);
+                        }
+                        if (gEditorController.neutronIntrospection.queryFragmentCheckinURI(gEditorController.currentNeutronFragment)) {
+                            // enable checkin operation
+                            // TODO: at the moment, <save> == <checkin>
+                            document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", false);
+                        }
+                    }
                 } else {
                     this.illegalTransition(aTransition, this.currentState);
                     return;
@@ -392,6 +435,18 @@
             case "saved":
                 if (this.currentState == this.STATE_DOCUMENTREADY_MODIFIED) {
                     this.currentState = this.STATE_DOCUMENTREADY_PRISTINE;
+                    // check for introspection (save and checkin)
+                    if (gEditorController.neutronIntrospection) {
+                        if (gEditorController.neutronIntrospection.queryFragmentSaveURI(gEditorController.currentNeutronFragment)) {
+                            // enable save operation
+                            document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", true);
+                        }
+                        if (gEditorController.neutronIntrospection.queryFragmentCheckinURI(gEditorController.currentNeutronFragment)) {
+                            // enable checkin operation
+                            // TODO: at the moment, <save> == <checkin>
+                            document.getElementById("uiFileOperationSaveCMSMenuitem").setAttribute("disabled", true);
+                        }
+                    }
                 } else {
                     this.illegalTransition(aTransition, this.currentState);
                     return;

Modified: public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/model.js
===================================================================
--- public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/model.js	2006-06-26 16:20:47 UTC (rev 14678)
+++ public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/model.js	2006-06-26 16:28:31 UTC (rev 14679)
@@ -98,14 +98,10 @@
 
     setDirty: function () {
         this.dirty = true;
-
-        this.stateController.modelStateChanged("modified");
     },
 
     unsetDirty: function () {
         this.dirty = false;
-
-        this.stateController.modelStateChanged("saved");
     },
 
     /**
@@ -116,6 +112,12 @@
      */
     isDirty: function () {
         /* DEBUG */ dump("Phoenix:model.js:isDirty() invoked\n");
+
+        /* TODO: What we really want to do is the editor element
+         * reporting to the model upon modification. Since this
+         * does not work yet, we simply poll the editor here. */
+        this.dirty = gEditorController.activeView.view.documentModified;
+
         return this.dirty;
     },
 

Modified: public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/view.js
===================================================================
--- public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/view.js	2006-06-26 16:20:47 UTC (rev 14678)
+++ public/phoenix/trunk/phoenix/prototypes/prototype1/src/chrome/content/view.js	2006-06-26 16:28:31 UTC (rev 14679)
@@ -48,6 +48,24 @@
 function View(aEditorController, aModel) {
     /* DEBUG */ dump("Phoenix:view.js:View(" + aEditorController + ", " + aModel + ") invoked.\n");
 
+    this.constructor.DocumentStateListener = function (aEditorController) {
+        this.editorController = aEditorController;
+    };
+
+    this.constructor.DocumentStateListener.prototype = {
+        editorController:              null,
+
+        NotifyDocumentCreated:         function () {},
+        NotifyDocumentWillBeDestroyed: function () {},
+        NotifyDocumentStateChanged:    function (aDocumentChanged) {
+            if (aDocumentChanged) {
+                this.editorController.editStateController.modelStateChanged("modified");
+            } else {
+                this.editorController.editStateController.modelStateChanged("saved");
+            }
+        }
+    };
+
     this.controller = aEditorController;
     this.model      = aModel;
     this.editor     = null;
@@ -107,7 +125,7 @@
 View.prototype.syncToModel = function () {
     /* DEBUG */ dump("Phoenix:view.js:View.syncToModel() invoked\n");
 
-    // TODO: where is documentModified coming from??
+    // documentModified is a readonly attribute of nsIEditor
     if (this.view.documentModified) {
         try {
             this.model.setDocument(this.contentToString());
@@ -159,6 +177,7 @@
 
             this.editorImpl = sourceEditor.getEditor(sourceEditor.contentWindow);
             this.editorImpl.QueryInterface(Components.interfaces.nsIEditor);
+            this.editorImpl.addDocumentStateListener(new View.DocumentStateListener(this.controller));
 
             this.view = sourceEditor.getEditor(sourceEditor.contentWindow);
             this.view.QueryInterface(Components.interfaces.nsIPlaintextEditor);




More information about the Phoenix-commits mailing list