[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