Breaking the grip JS has on the DOM: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
 
No edit summary
Line 21: Line 21:


== Identified task list ==
== Identified task list ==
These are the tasks identified during the analysis and implementation phases of the project.  
These are the tasks identified during the analysis and implementation phases of the project.  


=== nsScriptLoader ===
=== Overview ===
* nsScriptLoader's interface is language neutralTheoretically only the implementation need change.
 
The existing nsIScriptContext interface will remain tied to a specific language.  The "void *" params in its interface will remain.  This means that a "void *" and a suitable nsIScriptContext must always be treated as a pair (ie, given just a "void *", there is no way to determine an appropriate nsIScriptContext suitable for it - although "assume JS" is likely to remain for existing code that does exactly this)
 
nsIScriptContext will grow new methods relating to:
* language specific cleanup and "default language context" type code.  For example, nsGlobalWindow.cpp has a number of calls to ::JS_ClearScope/::JS_ClearWatchPointsForObject etc - these need to be hidden behind one of the interfaces.
* The "WrapNative" process.
 
The existing nsIScriptGlobalObject interface will move towards a model where there is a global script context per language.  GetGlobalJSObject and GetContext would be deprecated, with a new method allowing the desired language to be specified.
 
Some concept of a "language ID" will need to be invented. enum/char */atom?
 
The 'context stack' will need to be enhanced to allow each language to have their own implementation for pushing and poping context.  Thus, when the DOM requires an item on or off the context stack, each language will be called once to do its own thing.
 
nsDOMClassInfo needs to be addressed - presumably its functionality is necessary for other languages - but it is heavily JS specific.
 
Below are specific implementation notes:


=== nsIScriptContext ===
=== nsIScriptContext ===
* nsIScriptContext is not language neutral.  In some cases, what would otherwise be a "JSObject *" has been replaced with a "void *" - however, callers and implementation still make JS assumptions.  Most consumers of this interface are suspect.
The primary usage of nsIScriptContext falls into the following categories:
* Getting the global object for a context, and/or getting a default context - but not actually doing anything with them other than pass them on.
* Futzing with the global context and/or global object - setting globals or event handlers, etc??
* Explicit execution of script code.


We need to either:
* Existing JSObject replaced with void
* Clone and adapt this interface for non JS languages.  Every consumer would need to be changed heavily for each new language.
 
* Invent nsIScriptObject and related interfaces/structures.  This would allow most call sites can move towards a fully language-independent model.
* Need a "WrapNative" type function
 
* ExecuteScript - param 2 changes from "void *aScopeObject" to "nsIScriptGlobalObject *aScopeObject".  JS impl fetches underlying JSObject.
 
* FinalizeClasses method - JS does the ClearScope/ClearWatchpointsForObject/ClearRegExpStatistics?
 
* Some kind of "SetProperty" function - as needed by nsGlobalWindow - "arguments", "navigator" etc.  http://lxr.mozilla.org/seamonkey/source/dom/src/base/nsGlobalWindow.cpp#871
 
=== nsIScriptGlobalObject / nsGlobalWindow ===
 
http://lxr.mozilla.org/seamonkey/source/dom/public/nsIScriptGlobalObject.h
 
nsGlobalWindow is the main implemention of nsIScriptGlobalObject
 
* nsIScriptGlobalObject probably needs to remain a single object (ie, not per language).  It will move towards keeping a list of "IScriptContext *ctx, void *global" items, one for each language.  New method:
  nsresult GetLanguageContext( [in] language_id language, [out] nsIScriptContext **retLangContext, [out]void **retLangGlobal);
mJSObject and mContext will both be dropped in favour of the list.  The concept of a single context/global will be deprecated - callers will be encouraged to use the new method.
GetContext()/GetGlobalJSObject() remain for b/w compat.  They are equivilent to "GetLanguageContext('js', ...)"
 
* New method to set and get "properties" - nsGlobalWindow does this for JS.  Setting a property should presumably set it in all languages (via the global attached to the context).  Getting is tricker - what if the property is in a different language?  Or in multiple languages?
** Properties set include "arguments" and "navigator"Presumably other code also sets additional properties?
** Properties fetched seem arbitrary.
 
* "Arguments" will need to be specified in a language neutral way.  Maybe array of nsVariants?
 
* Serializing scripts?
 
* CompileScript:
  nsXulElement. Line 3666:
  // XXXbe violate nsIScriptContext layering because its version parameter
  // is mis-typed as const char *  
  sets mJSObject
 
=== Context Stack ===
 
Existing nsIJSContextStack "@mozilla.org/js/xpc/ContextStack;1" service is replaced with language generic ContextStack.  This is almost identical to the JS version, but all functions accept a 'language_id' param, to indicate which language they are interested in.  Existing 'js' specific context stack could be re-implemented using the new one.
 
Probably need a new interface for each language to do their thing.  The DOM will simply ask for a new context - something must do the delegation to the languages.
 
What about http://lxr.mozilla.org/seamonkey/source/dom/public/nsIScriptContext.h#356 - it
checks flags.  Will there be flags for a single stack entry, or flags for each language in a single stack entry, or both?
 
::JS_GetContextPrivate ???
 
=== nsScriptLoader ===
 
* nsScriptLoader's interface is language neutral.  Theoretically only the implementation need change.


=== nsDOMClassInfo ===
=== nsDOMClassInfo ===
Some of this will need to be generalized for use by multiple languages.  Specifically, the "tables" of interfaces and access to the extended type information would be unmaintainable across multiple languages.
Some of this will need to be generalized for use by multiple languages.  Specifically, the "tables" of interfaces and access to the extended type information would be unmaintainable across multiple languages.


=== nsIScriptGlobalObject and nsIScriptGlobalObjectOwner ===
=== nsXULPrototypeScript ===


There remains a "JSObject *global" here.  Hopefully this is used primarily to provide either a default "context", or to set global variables.
Change JSObject *mJSObject -> void *mScriptObject, and add new nsIScriptContext reference.


=== Exceptions ===
=== Event listeners ===
Exceptions should be chained across languages. This should just mean diligent use of nsIExceptionService?
http://lxr.mozilla.org/seamonkey/source/content/events/src/nsEventListenerManager.cpp#1160


=== New Interfaces ===
Changes required:
* AddScriptEventListener() needs a "language_id" passed in
* 'context' still comes from ScriptGlobal
* Use of "@mozilla.org/js/xpc/ContextStack;1" needs to be abstracted into the nsIScript interfaces.


nsIScriptLanguageContext - replaces "JSContext *".  hrm - why not simply nsIScriptContext
=== Exceptions ===


nsIScriptObject - replaces "JSObject *" and some "void *"?
Exceptions should be chained across languages.  This should just mean diligent use of nsIExceptionService?
 
existing nsIScriptGlobalObject - inherits from nsIScriptObject?
 
nsIScriptLanguage - new "manager" of globals etc?


== Identified list of things we will *not* do ==
== Identified list of things we will *not* do ==
Line 63: Line 119:




=== Stuff Mark still needs to grok ===
== Stuff Mark still needs to grok ==


* Whole JS "globals" concept - need to understand JS namespaces better.  It seems a "js global" is analogous to a Python dict which will be used as the globals namespace.
* Still a little gray on the relationship between a JSContext, a "scope" and a "global"
** JSContext a DOM specific concept, so script_language -> C++ -> script_language preserves the state of the globals (correct?)
** What is in a "context" beyond the global object?


* What exactly does nsDOMClassInfo do???
* WrapNative and what it really means to this


* nsEventListenerManager::AddScriptEventListener is interesting and a good place to look for factoring opportunities. It does quite a bit JS specific - but it really is *not* JS specific at all.
* What exactly does nsDOMClassInfo do??? How can we factor it?
http://lxr.mozilla.org/seamonkey/source/content/events/src/nsEventListenerManager.cpp#1160


* nsBindingManager - very JS specific and not using nsIScript interfaces
* nsBindingManager - very JS specific and not using nsIScript interfaces


* Need to understand the desired 'undefined' semantics for the return value.   
* Need to understand the desired 'undefined' semantics for the return value.  Python's builtin None is closer to a JS null, so may not be suitable for 'undefined'. However, a simple 'return' will return None.
  Python's builtin None is closer to a JS null, so may not be suitable for 'undefined'.
  However, a simple 'return' will return None.


* Timeouts look tricky.
* Timeouts look tricky.
Line 86: Line 141:
Some notes about existing callers of certain interfaces.
Some notes about existing callers of certain interfaces.


=== nsIScriptContext ===
nsDOMParser:
nsDOMParser:
* Gets "native call context" to end up with nsIScriptContext - apparently all just to get the script URI
 
nsDocShell - security related functions
* Gets "native call context" to end up with nsIScriptContext - apparently all just to get the script URI nsDocShell
** http://lxr.mozilla.org/seamonkey/source/extensions/xmlextras/base/src/nsDOMParser.cpp#476
** Will need to know the language_id that should process the data from the stream
* Security related functions


nsXMLHttpRequest.cpp
nsXMLHttpRequest.cpp
Line 95: Line 152:


mozXMLTermUtils.cpp:
mozXMLTermUtils.cpp:
   * mozXMLTermUtils::ExecuteScript called nsIScriptContext::ExecuteScript -  
   * mozXMLTermUtils::ExecuteScript called nsIScriptContext::ExecuteScript -      but with NULL "void *" pointers. Needs to have nsIScriptContext passed?
     but with NULL "void *" pointers.


nsScriptSecurityManager.cpp/nsSecurityManagerFactory.cpp:
nsScriptSecurityManager.cpp/nsSecurityManagerFactory.cpp:
*Almost all functions convert a JSContext to an nsIScriptContext.  Most just use to GetGlobalObject - GetPrincipalAndFrame has JS assumptions
*Almost all functions convert a JSContext to an nsIScriptContext.  Most just use to GetGlobalObject - GetPrincipalAndFrame has JS assumptions
* nsSecurityNameSet::InitializeNameSet - Lots of JS specific code.
* nsSecurityNameSet::InitializeNameSet - Lots of JS specific code.
   
 
docshell/base/nsDocShell.cpp:
docshell/base/nsDocShell.cpp:
  1 use:
1 use nsDocShell::CheckLoadingPermissions() - use of JF ContextStack to fetch nsIScriptContext - just to GetGlobalObject
    nsDocShell::CheckLoadingPermissions() - use of JF ContextStack to fetch
    nsIScriptContext - just to GetGlobalObject


embedding/components/windowwatcher/src/nsWWJSUtils.cpp
embedding/components/windowwatcher/src/nsWWJSUtils.cpp
  Converts JSContext to nsIScriptContext.  Mainly for GetGlobalObject, but
* Converts JSContext to nsIScriptContext.  Mainly for GetGlobalObject, but nsIScriptGlobalObject *nsWWJSUtils::GetStaticScriptGlobal has JS deps.
  nsIScriptGlobalObject *nsWWJSUtils::GetStaticScriptGlobal
 
  has JS deps.
 
embedding/components/windowwatcher/src/nsWindowWatcher.cpp:
embedding/components/windowwatcher/src/nsWindowWatcher.cpp:


Line 152: Line 204:
nsXBLProtoImpl:
nsXBLProtoImpl:
   Lots of JS Specific code.
   Lots of JS Specific code.
  Fairly generic compile function: http://lxr.mozilla.org/seamonkey/source/content/xbl/src/nsXBLProtoImpl.cpp#192


content/xul:
content/xul:
Line 182: Line 235:


xpfe/appshell/src/nsAppShellService.cpp
xpfe/appshell/src/nsAppShellService.cpp


plugins/activex/embedding/crypto: ignoring for now.
plugins/activex/embedding/crypto: ignoring for now.
=== nsIScriptGlobalObject ===
http://lxr.mozilla.org/seamonkey/source/dom/public/nsIScriptGlobalObject.h
* GetGlobalJSObject -> nsIScriptLanguageObject *GetGlobalObject(const char *language);??
* JSObject references (GetGlobalJSObject/OnFinalize)
* SetNewArguments - nsVariant[]?
* CompileScript:
  nsXulElement.  Line 3666:
  // XXXbe violate nsIScriptContext layering because its version parameter
  // is mis-typed as const char *
  sets mJSObject
32

edits

Navigation menu