/**************************************************************************
*
* @@@BUILDINFO@@@ 35omvUI-2.jsx 2.0.1.74 12-June-2007
* Copyright 2006-2007 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents,patents in process,and are protected by trade secret or copyright
* law. Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained from
* Adobe Systems Incorporated.
**************************************************************************/
// Object Model Viewer.
// Current limitations:
// 1) The first TOC level is ignored.
// 2) Namespace and interface declarations are not interpreted.
// 3) Only the first is interpreted.
// Create an OMV viewer. Takes the BridgeTalk ID of the target.
// Properties:
// data the OMVData object containing XML.
// w the window
// classes the Classes listbox
// types the Element Types listbox
// elements the Properties and Methods listbox
// display the HTML display
// classesItems an object with class names as properties and the class list items as values
function OMV (data)
{
this.data = data;
this.classesItems = {};
this.classHrefs = {
// Object : "$COMMON/javascript.xml#/",
Array : "$COMMON/javascript.xml#/",
Math : "$COMMON/javascript.xml#/",
Date : "$COMMON/javascript.xml#/",
Function : "$COMMON/javascript.xml#/",
String : "$COMMON/javascript.xml#/",
Number : "$COMMON/javascript.xml#/",
Boolean : "$COMMON/javascript.xml#/",
RegExp : "$COMMON/javascript.xml#/",
Error : "$COMMON/javascript.xml#/",
File : "$COMMON/javascript.xml#/",
Folder : "$COMMON/javascript.xml#/",
Socket : "$COMMON/javascript.xml#/",
ReflectionInfo : "$COMMON/javascript.xml#/",
Reflection : "$COMMON/javascript.xml#/",
Dictionary : "$COMMON/javascript.xml#/",
QName : "$COMMON/javascript.xml#/",
Namespace : "$COMMON/javascript.xml#/",
XML : "$COMMON/javascript.xml#/",
UnitValue : "$COMMON/javascript.xml#/",
ScriptUI : "$COMMON/scriptui.xml#/",
Window : "$COMMON/scriptui.xml#/",
LayoutManager : "$COMMON/scriptui.xml#/",
ScriptUIGraphics: "$COMMON/scriptui.xml#/",
ScriptUIPen : "$COMMON/scriptui.xml#/",
ScriptUIBrush : "$COMMON/scriptui.xml#/",
ScriptUIPath : "$COMMON/scriptui.xml#/",
ScriptUIFont : "$COMMON/scriptui.xml#/",
ScriptUIImage : "$COMMON/scriptui.xml#/",
DrawState : "$COMMON/scriptui.xml#/",
StaticText : "$COMMON/scriptui.xml#/",
Button : "$COMMON/scriptui.xml#/",
IconButton : "$COMMON/scriptui.xml#/",
EditText : "$COMMON/scriptui.xml#/",
ListBox : "$COMMON/scriptui.xml#/",
DropDownList : "$COMMON/scriptui.xml#/",
ListItem : "$COMMON/scriptui.xml#/",
Checkbox : "$COMMON/scriptui.xml#/",
Scrollbar : "$COMMON/scriptui.xml#/",
RadioButton : "$COMMON/scriptui.xml#/",
Slider : "$COMMON/scriptui.xml#/",
Progressbar : "$COMMON/scriptui.xml#/",
TreeView : "$COMMON/scriptui.xml#/",
FlashPlayer : "$COMMON/scriptui.xml#/",
Group : "$COMMON/scriptui.xml#/",
Panel : "$COMMON/scriptui.xml#/",
Point : "$COMMON/scriptui.xml#/",
Dimension : "$COMMON/scriptui.xml#/",
Bounds : "$COMMON/scriptui.xml#/",
UIEvent : "$COMMON/scriptui.xml#/",
MenuElement : "$COMMON/scriptui.xml#/"
};
// The preferred size is == the default size of a doc window
this.w = new Window (
"documentwindow { \
preferredSize : [470, 510], \
orientation : 'column', \
margins : 2, \
spacing : 2, \
properties : \
{ \
minimumSize : [350, 180], \
closeOnKey : 'OSCmnd+W', \
}, \
grp : Group { \
orientation : 'row', \
size : [ 100, 300 ], \
alignment : ['fill', 'top' ], \
classes : Group { \
orientation : 'column', \
size : [ 100, 300 ], \
alignment : ['fill', 'top' ], \
label : StaticText { \
alignment : 'left', \
text : '$$$/ESToolkit/OMV/Classes=Classes', \
}, \
classes : ListBox { \
properties : { \
multiselect : true, \
helpTip : '$$$/ESToolkit/OMV/htClasses=Classes', \
} \
alignment : ['fill', 'fill' ] \
}, \
}, \
elements : Group { \
orientation : 'column', \
size : [ 100, 300 ], \
alignment : ['fill', 'top' ], \
label : StaticText { \
alignment : 'left', \
text : '$$$/ESToolkit/OMV/Elements=Properties and Methods', \
}, \
types : ListBox { \
size : [ 100, 70 ], \
alignment : ['fill', 'top' ], \
helpTip : '$$$/ESToolkit/OMV/htTypes=Types', \
}, \
elements : ListBox { \
properties : { \
multiselect : true \
}, \
alignment : ['fill', 'fill' ], \
helpTip : '$$$/ESToolkit/OMV/htElements=Elements', \
} \
} \
}, \
find : Group { \
orientation : 'row', \
alignment : 'fill', \
btns : Group { \
margins : 0, \
spacing : 2, \
back : IconButton { \
preferredSize: [24, 24], \
enabled : false, \
helpTip : '$$$/ESToolkit/OMV/htBack=Go to previous entry.', \
}, \
fwd : IconButton { \
preferredSize: [24, 24], \
enabled : false, \
helpTip : '$$$/ESToolkit/OMV/htNext=Go to next entry.', \
}, \
copy : IconButton { \
preferredSize: [24, 24], \
enabled : false, \
helpTip : '$$$/ESToolkit/OMV/htCopy=Copy description to clipboard', \
}, \
}, \
label : StaticText { \
alignment : ['left', 'center' ], \
text : '$$$/ESToolkit/FindReplaceDlg/FindLbl=Find:', \
}, \
find : EditText { \
preferredSize: [100,20], \
alignment : ['fill', 'top' ], \
helpTip : '$$$/ESToolkit/OMV/htFind=Type in the element you are looking for here.', \
} \
}, \
dispBorder : Panel { \
properties : { \
borderStyle : 'sunken', \
}, \
alignment : ['fill', 'fill' ], \
display : FlashPlayer { \
minimumSize : [10, 10], \
alignment : ['fill', 'fill' ] \
} \
} \
}");
this.classes = this.w.grp.classes.classes;
this.types = this.w.grp.elements.types;
this.elements = this.w.grp.elements.elements;
this.display = this.w.dispBorder.display;
this.find = this.w.find.find;
this.findLabel= this.w.find.label;
this.fwd = this.w.find.btns.fwd;
this.back = this.w.find.btns.back;
this.copy = this.w.find.btns.copy;
this.w.omv =
this.classes.omv =
this.types.omv =
this.elements.omv =
this.display.omv =
this.find.omv =
this.fwd.omv =
this.back.omv =
this.copy.omv = this;
OMV.windows.push (this.w);
this.w.text = this.data.xml.map.@title;
this.fwd.icon = ScriptUI.newImage ('#BrowseRight_R', '#BrowseRight_N');
this.back.icon = ScriptUI.newImage ('#BrowseLeft_R', '#BrowseLeft_N');
this.copy.icon = ScriptUI.newImage ('#Copy_R', '#Copy_N');
this.copy.enabled = true;
this.fwd.enabled = false;
this.back.enabled = false;
// This is set to nonzero if only a list box selection changes,
// and no data is supposed to be reloaded.
this.ignoreChanges = 0;
this.w.onNotify = function( reason )
{
if( reason == 'shutdown' )
{
globalBroadcaster.unregisterClient( this );
this.omv.detachHandlers();
this.hide();
}
}
this.w.onClose = function()
{
// no XML = no use for this window
if (!this.omv.data.xml)
return true;
// otherwise, just hide it
this.hide();
return false;
}
globalBroadcaster.registerClient( this.w );
this.w.onResize = function ()
{
this.layout.resize();
}
this.setupHTMLControl (this.display);
var ok = true;
// LAYOUT BUG: need to show now already
this.w.show();
this.startHTML();
if (this.data.showProgress)
{
this.dlg = new ProgressBox ('$$$/ESToolkit/OMV/SetupUI=Initializing the UI...');
ok = this.loadTOC();
this.dlg.stop();
this.dlg = null;
}
else
ok = this.loadTOC();
/* if (ok)
{
// LAYOUT BUG: enable this statement
this.w.show();
this.startHTML();
}
*/
}
// This is the array of all OMV windows.
OMV.windows = [];
// This is the default font size of the OMV HTML viewer.
OMV.htmlFontSize = 11;
// The OMV icons are here, addressed by their names.
OMV.icons = {};
// The list of OMV that need to unpdate their HTML.
// HTML is updated delayed.
OMV.update = [];
// Set up all OMV entries in the Help menu.
OMV.setup = function()
{
// Set up the OMVData
OMVData.setup();
// Set up the icons
this.icons.ENUMERATION = ScriptUI.newImage ("#Enumeration");
this.icons.CLASS = ScriptUI.newImage ("#Class");
this.icons.METHOD = ScriptUI.newImage ("#Method");
this.icons.ROPROPERTY = ScriptUI.newImage ("#PropertyRO");
this.icons.RWPROPERTY = ScriptUI.newImage ("#PropertyRW");
}
//////////////////////////////////////////////////////////////////
//
// onChange Handlers
// These handlers are attached to the list and edit boxes.
// The Classes onChange handler is attached after the
// list box has been filled to avoid unnecessary calls.
//
//////////////////////////////////////////////////////////////////
OMV.prototype.attachHandlers = function()
{
// Classes change notification.
this.classes.onChange = function()
{
if (this.omv.ignoreChanges)
return;
var item = this.selection;
if (item)
{
var xml = null;
if (item.length == 1)
{
if (!item[0].xml)
item[0].xml = this.omv.data.findXML (item[0].clsName);
if (!item[0].xml)
return;
this.omv.loadClass (item[0].xml);
return;
}
else
{
xml = XML("
").children();
for (var i = 0; i < item.length; i++)
{
if (!item[i].xml)
item[i].xml = this.omv.data.findXML (item[i].clsName);
xml += item[i].xml;
}
}
}
this.omv.ignoreChanges++;
this.omv.types.xml = null;
this.omv.types.removeAll();
this.omv.elements.xml = null;
this.omv.elements.removeAll();
this.omv.ignoreChanges--;
this.omv.displayXML (xml);
}
// Element types change notification.
this.types.onChange = function()
{
if (this.omv.ignoreChanges)
return;
var item = this.selection;
if (item)
this.omv.loadClassElements (item.xml);
else
{
this.omv.ignoreChanges++;
this.omv.elements.xml = null;
this.omv.elements.removeAll();
this.omv.setHTML (null);
this.omv.ignoreChanges--;
}
}
// Methods/properties change notification
this.elements.onChange = function()
{
if (this.omv.ignoreChanges)
return;
var item = this.selection;
var xml = null;
if (item)
{
if (item.length > 1)
{
xml = XML("
").children();
for (var i = 0; i < item.length; i++)
xml += item[i].xml;
}
else
xml = item[0].xml;
}
this.omv.displayXML (xml);
}
this.find.onChanging = function()
{
if (!this.ignoreChanges)
this.omv.findText (this.text);
}
}
OMV.prototype.detachHandlers = function()
{
delete this.classes.onChange;
delete this.types.onChange;
delete this.elements.onChange;
delete this.find.onChanging;
}
//////////////////////////////////////////////////////////////////
//
// Deleting
// Called when a dynamic OMV was reloaded
//
//////////////////////////////////////////////////////////////////
OMV.prototype.detach = function()
{
for (var i = 0; i < OMV.windows.length; i++)
{
if (OMV.windows [i] == this.w)
{
OMV.windows.splice (i, 1);
break;
}
}
this.w.hide();
this.w = null;
this.data.omv = null;
this.data.menu.omv = null;
this.data.menu.enabled = true;
}
//////////////////////////////////////////////////////////////////
//
// Disabling
//
//////////////////////////////////////////////////////////////////
// Disable this UI due to errors.
// Also a callback from the OMVData instance in case on errors.
OMV.prototype.disable = function()
{
this.data.badXML();
this.data.menu.enabled = false;
this.data.xml = null;
if (this.w)
this.w.close();
}
//////////////////////////////////////////////////////////////////
//
// Data Loading
//
//////////////////////////////////////////////////////////////////
// Load the TOC into the Classes listbox. Returns false if aborted.
OMV.prototype.loadTOC = function()
{
var list = this.sortedXML (this.data.map.children(), "navtitle");
if (this.dlg)
this.dlg.setProgress (0, list.length);
for (var i = 0; i < list.length; i++)
{
if (this.dlg && !this.dlg.setProgress (i))
{
this.disable();
return false;
}
var href = this.data.splitHref (list[i].@href.toString());
// no packages!
var xpath = 'classdef[@name = "' + href.cls + '"]';
var xml = null;
if (this.data.xml['package'])
{
xml = this.data.xml['package'].xpath (xpath);
if (!xml.length())
{
this.disable();
return false;
}
}
var item = this.classes.add ("item", list [i].@navtitle);
this.classesItems [href.cls] = item;
this.classHrefs [href.cls] = "#/";
item.xml = xml;
item.omv = this;
item.clsName = href.cls;
if (item.xml)
item.icon = ((item.xml.@enumeration == "true") ? OMV.icons.ENUMERATION : OMV.icons.CLASS);
}
// Attach onChange handlers here
this.attachHandlers();
return true;
}
// Load the next-level class info (which is the elements group).
OMV.prototype.loadClass = function (xml, noStack)
{
if (xml == this.types.xml)
return;
var currentItem = this.types.selection ? this.types.selection.text : "";
this.types.removeAll();
this.types.xml = xml;
var item;
var selItem = null;
var types = [ "constructor", "class", "instance", "prototype", "event" ];
var typeNames = [
"$$$/ESToolkit/OMV/Types/Constructors=Constructors",
"$$$/ESToolkit/OMV/Types/ClassElements=Class Elements",
"$$$/ESToolkit/OMV/Types/InstanceElements=Instance Elements",
"$$$/ESToolkit/OMV/Types/PrototypeElements=Prototype Elements",
"$$$/ESToolkit/OMV/Types/Events=Events" ];
this.ignoreChanges++;
for (var i = 0; i < types.length; i++)
{
var container = xml.xpath ("elements[@type='" + types [i] + "']");
if (container.length() > 0)
{
item = this.types.add ("item", localize (typeNames [i]));
item.xml = container;
item.omv = this;
// Select either the first occurence, the last type, or instance elements
if ((!selItem && types [i] == "instance") || item.text == currentItem)
selItem = item;
}
}
if (!selItem)
selItem = this.types.items [0];
this.ignoreChanges--;
this.types.selection = selItem;
// and load the HTML
if (!noStack)
this.pushHTMLStack (xml);
this.setHTML (this.getHTML (xml));
}
// Fill in the elements for a class. The parent is the 2nd level.
OMV.prototype.loadClassElements = function (xml)
{
// this is the container
if (this.elements.xml == xml)
return;
this.elements.xml = xml;
this.ignoreChanges++;
this.elements.removeAll();
var href = xml.parent().@name.toString() + "/" + xml.@type + "/";
var isEnum = (xml.parent().@enumeration == "true");
var props = this.sortedXML (xml.property, "name");
var meths = this.sortedXML (xml.method, "name");
var name, type;
for (var i = 0; i < props.length; i++)
{
name = this.makeElementName (props [i]);
var item = this.elements.add ("item", name);
item.xml = props [i];
item.omv = this;
if (props[i].@name == "activeDocument")
item.yes = true;
if (isEnum)
item.icon = OMV.icons.ENUMERATION;
else
item.icon = (props[i].@rwaccess == "readonly") ? OMV.icons.ROPROPERTY : OMV.icons.RWPROPERTY;
}
for (var i = 0; i < meths.length; i++)
{
name = this.makeElementName (meths [i]);
item = this.elements.add ("item", name);
item.xml = meths [i];
item.omv = this;
item.icon = OMV.icons.METHOD;
}
this.ignoreChanges--;
}
// Create an element name. Properties get a colon and the data type,
// and methods get the parameter list and the return type. If a data
// type is linkable, makeTypeInfo() creates a link.
OMV.prototype.makeElementName = function (xml)
{
var name = xml.@name;
var type = this.makeTypeInfo (xml.datatype, false);
if (xml.localName() != "method")
{
if (type == "")
type = "any";
name += ": " + type;
}
else
{
var args = "(";
var params = xml.parameters.children();
for (var j = 0; j < params.length(); j++)
{
if (j)
args += ", ";
args += params [j].@name;
}
args += ")";
if (args.length > 2)
name += " ";
name += args;
if (type != "")
name += ": " + type;
}
return name;
}
//////////////////////////////////////////////////////////////////
//
// HTML Generation
//
//////////////////////////////////////////////////////////////////
// Generate HTML for a given XML. This XML could be one or more
// class-level entries, or one or more element level entries.
OMV.prototype.getHTML = function (xml)
{
var html = null;
if (!xml)
html = XML ('');
else
{
if (xml.length() == 1)
{
switch (xml.localName())
{
case "classdef":
html = this.getClassHTML (xml);
break;
case "method":
html = this.getMethodHTML (xml);
break;
case "property":
html = this.getPropertyHTML (xml);
break;
}
}
if (html == null)
{
html = new XML ('');
if (xml)
{
var br = new XML ('
');
var sorted = this.sortedXML (xml, "name");
for (var i = 0; i < sorted.length; i++)
{
if (sorted [i].localName() == "classdef")
html.body.appendChild (this.makeLink (this.data.getHrefForXML (sorted [i]), sorted [i].@name.toString()));
else
{
var name;
if (sorted[i].parent().@type == "constructor")
name = "new " + this.makeElementName (sorted [i]);
else
name = sorted [i].parent().parent().@name + "." + this.makeElementName (sorted [i]);
html.body.appendChild (this.makeLink (this.data.getHrefForXML (sorted [i]), name));
}
html.body.appendChild (br);
}
}
}
}
return html;
}
// Generate and return HTML for a class.
OMV.prototype.getClassHTML = function (xml)
{
var html = XML ('