Name
sn_outlook_addin.OfficeAddInManifestGenerator
Description
No description available
Script
var OfficeAddInManifestGenerator = Class.create();
OfficeAddInManifestGenerator.prototype = {
initialize: function(manifestId) {
var defaultManifestId = gs.getProperty('sn_outlook_addin.defaultManifestId', 'f2d445ff5390330048e5ddeeff7b1273');
this.supportedLanguages=[];
//maps SNC language ID to Microsoft Outlook locale
this.languageMap = {
'pb':'pt-br',
'zh':'zh-cn',
'cs':'cs-cz',
'nl':'nl-nl',
'et':'et-ee',
'fi':'fi-fi',
'fr':'fr-fr',
'de':'de-de',
'he':'he-il',
'hu':'hu-hu',
'it':'it-it',
'ja':'ja-jp',
'ko':'ko-kr',
'pl':'pl-pl',
'pt':'pt-pt',
'ru':'ru-ru',
'es':'es-es',
'th':'th-th',
'zt':'zh-tw',
'tr':'tr-tr'
};
this.digest = new GlideDigest();
this.baseUrl = gs.getProperty('glide.servlet.uri');
this.manifestXml = new XMLDocument2();
this.providerName = 'ServiceNow';
this.defaultLocale = 'en-US';
this.grManifest = this._getmanifestRecord(manifestId || defaultManifestId);
var applicationMetaMap = {
outlook: {
host: 'Mailbox',
hostType: 'MailHost',
appType: 'MailApp'
},
word: {
host: 'Document',
hostType: 'Document',
appType: 'TaskPaneApp'
},
powerpoint: {
host: 'Presentation',
hostType: 'Presentation',
appType: 'TaskPaneApp'
}
};
this.app = applicationMetaMap[this.grManifest.office_host || 'outlook'];
this._populateSupportedLanguages();
},
generate: function() {
if(!this.grManifest) {
throw "NOT_FOUND";
}
var appType = this.app.appType;
var root = this.manifestXml.createElement("OfficeApp");
root.setAttribute("xmlns", "http://schemas.microsoft.com/office/appforoffice/1.1");
root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
root.setAttribute("xmlns:bt", "http://schemas.microsoft.com/office/officeappbasictypes/1.0");
if(appType === 'MailApp')
root.setAttribute("xmlns:mailappor", "http://schemas.microsoft.com/office/mailappversionoverrides/1.0");
else if(appType === 'TaskPaneApp')
root.setAttribute("xmlns:ov",'http://schemas.microsoft.com/office/taskpaneappversionoverrides');
root.setAttribute("xsi:type", appType);
this._populateManifestRootElements();
this._populateAppDomains();
this._populateHosts();
if (appType === 'MailApp') {
this._populateRequirements();
this._populateFormSettings();
this._populateRules();
} else if(appType === 'TaskPaneApp') {
this._populateDefaultSettings();
}
this._populateVersionOverrides();
return this.manifestXml.toString();
},
_getmanifestRecord: function(manifestId) {
var gr=new GlideRecord('sn_office_manifest');
gr.addActiveQuery();
gr.addQuery("sys_id", manifestId);
gr.query();
if(gr.next()) {
return gr;
}
return null;
},
_getResourceId: function(sysId, attr) {
return this.digest.getMD5Hex(sysId+attr);
},
_populateManifestRootElements: function(){
var appType = this.app.appType;
var root, curNode, xmlDoc = this.manifestXml;
root = xmlDoc.getNode('/OfficeApp');
xmlDoc.setCurrentElement(root);
xmlDoc.createElementWithTextValue("Id",this.grManifest.plugin_id.toString());
xmlDoc.createElementWithTextValue("Version",this.grManifest.version.toString());
xmlDoc.createElementWithTextValue("ProviderName",this.providerName);
xmlDoc.createElementWithTextValue("DefaultLocale",this.defaultLocale);
xmlDoc.createElement("DisplayName").setAttribute("DefaultValue",this.grManifest.getValue("addin_name"));
this._addlocalizedElement(root, "Description", "Override", "", this.grManifest.getValue("description"));
xmlDoc.createElement("IconUrl").setAttribute("DefaultValue",this._getImageUrl(this.grManifest.getValue("icon")));
xmlDoc.createElement("HighResolutionIconUrl").setAttribute("DefaultValue",this._getImageUrl("/images/outlook-addin/now.png"));
xmlDoc.createElement("SupportUrl").setAttribute("DefaultValue","https://hi.service-now.com/hisp");
xmlDoc.createElement("AppDomains");
xmlDoc.createElement("Hosts");
var permission = this.grManifest.getValue("permission");
if(appType === 'MailApp'){
xmlDoc.createElement("Requirements");
xmlDoc.createElement("FormSettings");
} else if(appType === 'TaskPaneApp') {
xmlDoc.createElement("DefaultSettings");
permission = permission.replace('Item','Document');
}
xmlDoc.createElementWithTextValue("Permissions", permission);
if(appType === 'MailApp'){
curNode = xmlDoc.createElement("Rule");
curNode.setAttribute("xsi:type", "RuleCollection");
curNode.setAttribute("Mode", "Or");
xmlDoc.createElementWithTextValue("DisableEntityHighlighting", "false");
}
curNode = xmlDoc.createElement("VersionOverrides");
if(appType === 'MailApp'){
curNode.setAttribute("xmlns","http://schemas.microsoft.com/office/mailappversionoverrides");
} else if(appType === 'TaskPaneApp'){
curNode.setAttribute("xmlns","http://schemas.microsoft.com/office/taskpaneappversionoverrides");
}
curNode.setAttribute("xsi:type","VersionOverridesV1_0");
},
_populateAppDomains: function() {
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/AppDomains");
xmlDoc.setCurrentElement(node);
xmlDoc.createElementWithTextValue("AppDomain",this.baseUrl);
},
_populateHosts: function() {
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/Hosts");
xmlDoc.setCurrentElement(node);
xmlDoc.createElement("Host").setAttribute("Name",this.app.host);
},
_populateRequirements: function() {
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/Requirements");
xmlDoc.setCurrentElement(node);
var sets = xmlDoc.createElement("Sets");
xmlDoc.setCurrentElement(sets);
var set = xmlDoc.createElement("Set");
set.setAttribute("Name",this.app.host);
set.setAttribute("MinVersion", this.grManifest.getValue("min_version"));
},
_populateDefaultSettings: function(){
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/DefaultSettings");
xmlDoc.setCurrentElement(node);
xmlDoc.createElement("SourceLocation").setAttribute("DefaultValue", this.baseUrl);
},
_populateFormSettings: function () {
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/FormSettings");
xmlDoc.setCurrentElement(node);
var form = xmlDoc.createElement("Form");
form.setAttribute("xsi:type","ItemRead");
xmlDoc.setCurrentElement(form);
var desktopSettings = xmlDoc.createElement("DesktopSettings");
xmlDoc.setCurrentElement(desktopSettings);
xmlDoc.createElement("SourceLocation").setAttribute("DefaultValue", this.baseUrl);
xmlDoc.createElementWithTextValue("RequestedHeight","250");
},
_populateRules: function() {
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/Rule");
xmlDoc.setCurrentElement(node);
var childRuleNode = xmlDoc.createElement("Rule");
childRuleNode.setAttribute("xsi:type", "ItemIs");
childRuleNode.setAttribute("ItemType", "Message");
childRuleNode.setAttribute("FormType", "Read");
},
_populateVersionOverrides: function() {
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/VersionOverrides");
xmlDoc.setCurrentElement(node);
//add hosts node and default mailhost
var hostsNode = xmlDoc.createElement("Hosts");
xmlDoc.setCurrentElement(hostsNode);
var mailHostNode = xmlDoc.createElement("Host");
mailHostNode.setAttribute("xsi:type", this.app.hostType);
//add resources hierarchy
xmlDoc.setCurrentElement(node);
xmlDoc.setCurrentElement(xmlDoc.createElement("Resources"));
var imagesNode = xmlDoc.createElement("bt:Images");
var urlsNode = xmlDoc.createElement("bt:Urls");
var shortStringsNode = xmlDoc.createElement("bt:ShortStrings");
var longStringsNode = xmlDoc.createElement("bt:LongStrings");
this._populateDesktopFormFactor();
},
_populateDesktopFormFactor: function() {
var appType = this.app.appType;
var xmlDoc = this.manifestXml, node = xmlDoc.getNode("/OfficeApp/VersionOverrides/Hosts/Host");
var extPtType = 'MessageReadCommandSurface';
var grpId = 'msgReadGroup';
var tab = 'TabDefault';
if(appType === 'TaskPaneApp') {
extPtType = 'PrimaryCommandSurface';
grpId = 'CommandsGroup';
tab = "TabHome";
}
xmlDoc.setCurrentElement(node);
var desktopFormFactorNode = xmlDoc.createElement("DesktopFormFactor");
xmlDoc.setCurrentElement(desktopFormFactorNode);
var extensionPointNode = xmlDoc.createElement("ExtensionPoint");
extensionPointNode.setAttribute("xsi:type", extPtType);
xmlDoc.setCurrentElement(extensionPointNode);
var officeTabNode = xmlDoc.createElement("OfficeTab");
officeTabNode.setAttribute("id", tab);
xmlDoc.setCurrentElement(officeTabNode);
var groupNode = xmlDoc.createElement("Group");
groupNode.setAttribute("id", grpId);
xmlDoc.setCurrentElement(groupNode);
xmlDoc.createElement("Label").setAttribute("resid", this._getResourceId(this.grManifest.sys_id.toString(), "label"));
if(appType === 'MailApp') {
xmlDoc.createElement("Tooltip").setAttribute("resid", this._getResourceId(this.grManifest.sys_id.toString(), "tooltip"));
this._addResource("LongStrings", this._getResourceId(this.grManifest.sys_id.toString(), "tooltip"), this.grManifest.getValue("description"));
}
this._addResource("ShortStrings", this._getResourceId(this.grManifest.sys_id.toString(), "label"), this.grManifest.getValue("addin_name"));
this._populateControlsAndResources(groupNode);
},
_populateControlsAndResources: function(groupNode) {
var appType = this.app.appType;
var xmlDoc = this.manifestXml, grControl = new GlideRecord('sn_office_control'), controlNode, itemsNode;
grControl.addQuery('manifest', this.grManifest.sys_id.toString());
var qc = grControl.addQuery("type", "Button");
qc.addOrCondition("type", "Menu");
grControl.addNullQuery('parent_control');
grControl.addActiveQuery();
grControl.orderBy('order');
grControl.query();
var addedIconInGroup = false;
while(grControl.next()) {
if(!addedIconInGroup && appType === 'TaskPaneApp'){
xmlDoc.setCurrentElement(groupNode);
var iconNode = xmlDoc.createElement("Icon");
xmlDoc.setCurrentElement(iconNode);
imgNode = xmlDoc.createElement("bt:Image");
imgNode.setAttribute("size", "16");
imgNode.setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "icon16"));
imgNode = xmlDoc.createElement("bt:Image");
imgNode.setAttribute("size", "32");
imgNode.setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "icon32"));
imgNode = xmlDoc.createElement("bt:Image");
imgNode.setAttribute("size", "80");
imgNode.setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "icon80"));
addedIconInGroup = true;
}
xmlDoc.setCurrentElement(groupNode);
controlNode = xmlDoc.createElement("Control");
controlNode.setAttribute("xsi:type", grControl.getValue("type"));
controlNode.setAttribute("id", grControl.sys_id.toString());
xmlDoc.setCurrentElement(controlNode);
//populate all the attributes for the control
this._populateControlNode(controlNode, grControl);
if(grControl.type.toString() === 'Menu') {
xmlDoc.setCurrentElement(controlNode);
itemsNode = xmlDoc.createElement("Items");
this._populateMenuItems(itemsNode, grControl.sys_id.toString());
}
}
},
_populateMenuItems: function(itemsNode, parentId) {
var xmlDoc = this.manifestXml, grControl = new GlideRecord('sn_office_control'), ItemNode;
grControl.addQuery("type", "MenuItem");
grControl.addQuery("parent_control", parentId);
grControl.addActiveQuery();
grControl.orderBy('order');
grControl.query();
while(grControl.next()) {
xmlDoc.setCurrentElement(itemsNode);
itemNode = xmlDoc.createElement("Item");
itemNode.setAttribute("id", grControl.sys_id.toString());
this._populateControlNode(itemNode, grControl);
}
},
//populates the button, menu or menuItem nodes in the manifest
_populateControlNode: function(controlNode, grControl) {
var xmlDoc = this.manifestXml, addTooltip = false;
xmlDoc.setCurrentElement(controlNode);
xmlDoc.createElement("Label").setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "label"));
//tooltips are only available for control elements
if((grControl.getValue("type") === 'Menu' || grControl.getValue("type") === 'Button') && this.app.appType === 'MailApp') {
addTooltip= true;
xmlDoc.createElement("Tooltip").setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "tooltip"));
}
//add supertip and Icon parents
superTipNode = xmlDoc.createElement("Supertip");
iconNode = xmlDoc.createElement("Icon");
//add supertip elements
xmlDoc.setCurrentElement(superTipNode);
xmlDoc.createElement("Title").setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "label"));
xmlDoc.createElement("Description").setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "description"));
//add images to icons
xmlDoc.setCurrentElement(iconNode);
imgNode = xmlDoc.createElement("bt:Image");
imgNode.setAttribute("size", "16");
imgNode.setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "icon16"));
imgNode = xmlDoc.createElement("bt:Image");
imgNode.setAttribute("size", "32");
imgNode.setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "icon32"));
imgNode = xmlDoc.createElement("bt:Image");
imgNode.setAttribute("size", "80");
imgNode.setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "icon80"));
//addResource resets teh currentElement
//always resetCurrentElement post invocation of addResource
this._addResource("ShortStrings", this._getResourceId(grControl.sys_id.toString(), "label"), grControl.getValue("label"));
this._addResource("LongStrings", this._getResourceId(grControl.sys_id.toString(), "description"), grControl.getValue("description"));
this._addResource("Images", this._getResourceId(grControl.sys_id.toString(), "icon16"), this._getImageUrl(grControl.getValue('icon16')));
this._addResource("Images", this._getResourceId(grControl.sys_id.toString(), "icon32"), this._getImageUrl(grControl.getValue('icon32')));
this._addResource("Images", this._getResourceId(grControl.sys_id.toString(), "icon80"), this._getImageUrl(grControl.getValue('icon80')));
if(addTooltip) {
this._addResource("LongStrings", this._getResourceId(grControl.sys_id.toString(), "tooltip"), grControl.getValue("description"));
}
if(grControl.type.toString() === 'Button' || grControl.type.toString() === 'MenuItem') {
xmlDoc.setCurrentElement(controlNode);
actionNode = xmlDoc.createElement("Action");
actionNode.setAttribute("xsi:type", "ShowTaskpane");
xmlDoc.setCurrentElement(actionNode);
if(this.app.appType === 'TaskPaneApp' && this.grManifest.autoshow_taskpane)
xmlDoc.createElementWithTextValue('TaskpaneId','Office.AutoShowTaskpaneWithDocument');
xmlDoc.createElement("SourceLocation").setAttribute("resid", this._getResourceId(grControl.sys_id.toString(), "url"));
this._addResource("Urls", this._getResourceId(grControl.sys_id.toString(), "url"), this._getPageUrl(grControl.getValue('relative_url')));
}
},
_getImageUrl: function(value) {
if(value && value.startsWith("/")) {
return this.baseUrl + value.substring(1);
} else if(value && value.startsWith("https")) {
return value;
} else {
return this.baseUrl + "/images/outlook-addin/now80.png";
}
},
//adds resource to the right resource node
_addResource: function(type, id, value) {
var xmlDoc = this.manifestXml, resourceNode, curNode;
if(type === 'ShortStrings') {
resourceNode = xmlDoc.getNode('/OfficeApp/VersionOverrides/Resources/bt:ShortStrings');
this._addlocalizedElement(resourceNode, "bt:String", "bt:Override", id, value);
} else if(type === 'LongStrings') {
resourceNode = xmlDoc.getNode('/OfficeApp/VersionOverrides/Resources/bt:LongStrings');
this._addlocalizedElement(resourceNode, "bt:String", "bt:Override", id, value);
} else if(type === 'Urls') {
resourceNode = xmlDoc.getNode('/OfficeApp/VersionOverrides/Resources/bt:Urls');
xmlDoc.setCurrentElement(resourceNode);
curNode = xmlDoc.createElement('bt:Url');
curNode.setAttribute("id", id);
curNode.setAttribute("DefaultValue", value);
} else if(type === 'Images') {
resourceNode = xmlDoc.getNode('/OfficeApp/VersionOverrides/Resources/bt:Images');
xmlDoc.setCurrentElement(resourceNode);
curNode = xmlDoc.createElement('bt:Image');
curNode.setAttribute("id", id);
curNode.setAttribute("DefaultValue", value);
}
},
_populateSupportedLanguages: function() {
var gr = new GlideRecord('sys_language');
if(!gr.isValid()) {
return;
}
gr.addActiveQuery();
gr.query();
while(gr.next()) {
this.supportedLanguages.push(gr.id.toString());
}
},
_getPageUrl: function(relativeUrl) {
if (this.grManifest.login_not_required)
return this.baseUrl + (relativeUrl.startsWith('/') ? relativeUrl.substring(1): relativeUrl);
var encodedUrl = encodeURIComponent(relativeUrl);
return this.baseUrl+'sn_outlook_addin_OutlookLogin.do?page='+encodedUrl;
},
_addlocalizedElement: function(parentNode, tag, overrideTag, id, defaultValue) {
var i, node, key, curChild, xmlDoc = this.manifestXml;
xmlDoc.setCurrentElement(parentNode);
node = xmlDoc.createElement(tag);
if(id) {
node.setAttribute("id",id);
}
node.setAttribute("DefaultValue",gs.getMessageLang(defaultValue, 'en'));
xmlDoc.setCurrentElement(node);
for(i in this.supportedLanguages) {
key = this.supportedLanguages[i];
if(this.languageMap[key]) {
curChild = xmlDoc.createElement(overrideTag);
curChild.setAttribute('Locale', this.languageMap[key]);
curChild.setAttribute('Value', gs.getMessageLang(defaultValue, key));
}
}
xmlDoc.setCurrentElement(parentNode);
},
type: 'OfficeAddInManifestGenerator'
};
Sys ID
ada53689ff70230048e505f6793bf1c6