Merge branch 'UIOptions'

Conflicts:
	src/modules/FiretrayIconLinux.jsm
	src/modules/gdk.jsm
This commit is contained in:
foudfou 2011-11-03 22:49:52 +01:00
commit 61b8e305ad
10 changed files with 498 additions and 113 deletions

15
TODO
View File

@ -1,5 +1,18 @@
=TODO=
* options: in mail_accounts, have serverTypes interact with excludedAccounts
* add "enable biff notification" option. And if true:
radio choice option with:
"display message count"
"display new-mail image"
"display custom image"
* also disable notification for excluded mail account servers
Not easily feasible since newmailalerts are hard-coded
http://mxr.mozilla.org/comm-central/find?string=content/newmailalert
* make multi-platform. At least have js-ctypes library call dependant on OS detection. (best would be to have the OS-dependant modules loaded at startup)
* convert to a https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions
@ -7,7 +20,7 @@
see ../restartless-restart-ffext/ and
http://erikvold.com/blog/index.cfm/2010/10/28/restartless-firefox-addons-part-1-giving-your-addon-the-bootstrap
WONTFIX:
=WONTFIX=
* ability to hide windows individually/globally

View File

@ -15,69 +15,275 @@ if ("undefined" == typeof(firetray)) {
};
firetray.UIOptions = {
accountBoxId: "accounts_box",
onLoad: function() {
if(firetray.Handler.inMailApp) {
Cu.import("resource://firetray/FiretrayMessaging.jsm");
this.insertMailAccountsExcluded(this.accountBoxId);
this.populateTreeAccountsOrServerTypes();
} else {
this.hideMailAccountsExcluded(this.accountBoxId);
this.hideElement("mail_tab");
}
},
onQuit: function() {
// cleaning: removeEventListener on cells
// NOTE: not sure this is necessary on window close
let tree = document.getElementById("ui_mail_accounts");
for (let i=0; i < tree.view.rowCount; i++) {
let cells = tree.view.getItemAtIndex(i).getElementsByTagName("treecell");
if (tree.view.getLevel(i) === 0) { // serverTypes
// account_or_server_type_excluded, account_or_server_type_order
[cells[1], cells[2]].map(
function(c) {
c.removeEventListener(
'DOMAttrModified', that._userChangeValueTreeServerTypes, true);
});
} else if (tree.view.getLevel(i) === 1) { // excludedAccounts
cells[1].removeEventListener(
'DOMAttrModified', that._userChangeValueTreeAccounts, true);
}
}
},
hideMailAccountsExcluded: function(parentId) {
hideElement: function(parentId) {
let targetNode = document.getElementById(parentId);
targetNode.hidden = true; //!(appType & Firetray_MAIL);
targetNode.hidden = true;
},
insertMailAccountsExcluded: function(parentId) {
// the DOM parent where we do appendChild
let targetNode = document.getElementById(parentId);
let accounts = new firetray.Messaging.Accounts(true);
for (let accountServer in accounts) {
if (firetray.Messaging.SERVER_TYPES[accountServer.type].excluded)
continue;
let nodeAccount = document.createElement("checkbox");
let accountServerKey = accountServer.key.toString();
nodeAccount.setAttribute('id', accountServerKey);
nodeAccount.setAttribute('label', accountServer.rootFolder.name);
nodeAccount.setAttribute('checked',
(firetray.Messaging.getPrefAccountsExcluded().indexOf(accountServerKey) >= 0));
let that = this;
nodeAccount.addEventListener('command', function(e){
that.updateMailAccountsExcluded(that.accountBoxId);});
targetNode.appendChild(nodeAccount);
_disableTreeRow: function(row, disable) {
let that = this;
try {
let cells = row.childNodes; // .getElementsByTagName('treecell');
LOG("CELLS: "+cells);
for (let i=0; i< cells.length; i++) {
LOG("i: "+i+", cell:"+cells[i]);
if (disable === true) {
cells[i].setAttribute('properties', "disabled");
cells[i].removeEventListener(
'DOMAttrModified', that._userChangeValueTreeAccounts, true);
cells[i].setAttribute('editable', "false");
} else {
cells[i].removeAttribute('properties');
cells[i].addEventListener(
'DOMAttrModified', that._userChangeValueTreeAccounts, true);
cells[i].setAttribute('editable', "true");
}
}
} catch(e) {
ERROR(e);
}
// let disable_notify=prefManager.getIntPref("extensions.firetray.show_mail_notification")==0;
// this._disableGroup(targetNode,disable_notify);
},
updateMailAccountsExcluded: function(parentId) {
let targetNode = document.getElementById(parentId);
let prefValue = [];
for (let i=1; i < targetNode.childNodes.length; i++) {
if (targetNode.childNodes[i].checked)
prefValue.push(targetNode.childNodes[i].getAttribute('id'));
}
LOG("accounts_to_exclude:"+prefValue);
firetray.Utils.prefService.setCharPref('accounts_to_exclude', prefValue.toString());
/**
* needed for triggering actual preference change and saving
*/
_userChangeValueTreeAccounts: function(event) {
if (event.attrName == "label") LOG("label changed!");
if (event.attrName == "value") LOG("value changed!");
document.getElementById("pane1")
.userChangedValue(document.getElementById("ui_tree_mail_accounts"));
firetray.Messaging.updateUnreadMsgCount();
},
_disableGroup: function(group, disableval) {
try {
for (let i=0; i< group.childNodes.length; i++)
group.childNodes[i].disabled = disableval;
} catch(e) {
ERROR(e);
_userChangeValueTreeServerTypes: function(event) {
if (event.attrName === "value") { // checkbox
let checkboxCell = event.originalTarget;
let tree = document.getElementById("ui_tree_mail_accounts");
let subRows = firetray.Utils.XPath(
checkboxCell,
'ancestor::xul:treeitem[1]/descendant::xul:treechildren//xul:treerow');
LOG("subRows="+subRows);
for (let i=0; i<subRows.length; i++) {
firetray.UIOptions._disableTreeRow(
subRows[i], (checkboxCell.getAttribute("value") === "false"));
}
} else if (event.attrName == "label") { // text
// TODO: move row to new rank
}
this._userChangeValueTreeAccounts(event);
},
/**
* NOTE: account exceptions for unread messages count are *stored* in
* preferences as excluded, but *shown* as "not included"
*/
populateTreeAccountsOrServerTypes: function() {
let that = this;
let prefPane = document.getElementById("pane1");
let prefStr = firetray.Utils.prefService.getCharPref("mail_accounts");
LOG("PREF="+prefStr);
let mailAccounts = JSON.parse(prefStr);
let serverTypes = mailAccounts["serverTypes"];
let accountsExcluded = mailAccounts["excludedAccounts"];
let accountsByServerType = firetray.Messaging.accountsByServerType();
LOG(JSON.stringify(accountsByServerType));
// sort serverTypes according to order
let serverTypesSorted = Object.keys(serverTypes);
serverTypesSorted.sort(function(a,b) {
if (serverTypes[a].order
< serverTypes[b].order)
return -1;
if (serverTypes[a].order
> serverTypes[b].order)
return 1;
return 0; // no sorting
});
LOG("serverTypesSorted: "+serverTypesSorted);
let target = document.getElementById("ui_mail_accounts");
for (let i=0; i<serverTypesSorted.length; i++) {
let serverTypeName = serverTypesSorted[i];
let item = document.createElement('treeitem');
item.setAttribute("container",true);
item.setAttribute("open",true);
let row = document.createElement('treerow');
item.appendChild(row);
// account_or_server_type_name
let cellName = document.createElement('treecell');
cellName.setAttribute('label',serverTypeName);
cellName.setAttribute('editable',false);
row.appendChild(cellName);
// account_or_server_type_excluded => checkbox
let cellExcluded = document.createElement('treecell');
cellExcluded.setAttribute('value',!serverTypes[serverTypeName].excluded);
cellExcluded.addEventListener( // CAUTION: removeEventListener in onQuit()
'DOMAttrModified', that._userChangeValueTreeServerTypes, true);
row.appendChild(cellExcluded);
// account_or_server_type_order
let cellOrder = document.createElement('treecell');
cellOrder.setAttribute('label',serverTypes[serverTypeName].order);
cellOrder.addEventListener( // CAUTION: removeEventListener in onQuit()
'DOMAttrModified', that._userChangeValueTreeServerTypes, true);
row.appendChild(cellOrder);
target.appendChild(item);
// add actual accounts as children
let subChildren = document.createElement('treechildren');
let typeAccounts = accountsByServerType[serverTypeName];
LOG("type: "+serverTypeName+", Accounts: "+JSON.stringify(typeAccounts));
if (typeof(typeAccounts) == "undefined")
continue;
for (let i=0; i<typeAccounts.length; i++) {
let subItem = document.createElement('treeitem');
let subRow = document.createElement('treerow');
// account_or_server_type_name
cell = document.createElement('treecell');
cell.setAttribute('id', typeAccounts[i].key);
cell.setAttribute('label',typeAccounts[i].name);
cell.setAttribute('editable',false);
subRow.appendChild(cell);
// account_or_server_type_excluded => checkbox
let cell = document.createElement('treecell');
cell.setAttribute('value',(accountsExcluded.indexOf(typeAccounts[i].key) < 0));
cell.addEventListener( // CAUTION: removeEventListener in onQuit()
'DOMAttrModified', that._userChangeValueTreeAccounts, true);
subRow.appendChild(cell);
// account_or_server_type_order - UNUSED (added for consistency)
cell = document.createElement('treecell');
cell.setAttribute('editable',false);
subRow.appendChild(cell);
this._disableTreeRow(
subRow, (cellExcluded.getAttribute("value") === "false"));
subItem.appendChild(subRow);
subChildren.appendChild(subItem);
}
item.appendChild(subChildren);
}
let tree = document.getElementById("ui_tree_mail_accounts");
tree.addEventListener("keypress", that.onKeyPressTreeAccountsOrServerTypes, true);
},
/*
* Save the "mail_accounts" preference. This is called by the pref's system
* when the GUI element is altered.
*/
saveTreeAccountsOrServerTypes: function() {
let tree = document.getElementById("ui_tree_mail_accounts");
LOG("VIEW="+ tree.view + ", rowCount="+tree.view.rowCount);
let prefObj = {"serverTypes":{}, "excludedAccounts":[]};
for (let i=0; i < tree.view.rowCount; i++) {
let accountOrServerTypeName = tree.view.getCellText(
i, tree.columns.getNamedColumn("account_or_server_type_name"));
let accountOrServerTypeExcluded = (
tree.view.getCellValue(
i, tree.columns.getNamedColumn("account_or_server_type_excluded"))
!== 'true');
let accountOrServerTypeOrder = parseInt(
tree.view.getCellText(
i, tree.columns.getNamedColumn("account_or_server_type_order")));
LOG("account: "+accountOrServerTypeName+", "+accountOrServerTypeExcluded);
if (tree.view.getLevel(i) === 0) { // serverTypes
prefObj["serverTypes"][accountOrServerTypeName] =
{ order: accountOrServerTypeOrder, excluded: accountOrServerTypeExcluded };
} else if (tree.view.getLevel(i) === 1) { // excludedAccounts
if (!accountOrServerTypeExcluded)
continue;
let rowNode = tree.view.getItemAtIndex(i).firstChild; // treerow
let rowCells = rowNode.getElementsByTagName('treecell');
let serverKey = rowCells[0].id;
prefObj["excludedAccounts"].push(serverKey);
} else
continue;
}
let prefStr = JSON.stringify(prefObj);
LOG("prefStr"+prefStr);
/* return the new prefString to be stored by pref system */
return prefStr;
},
onKeyPressTreeAccountsOrServerTypes: function(event) {
LOG("TREE KEYPRESS: "+event.originalTarget);
let tree = document.getElementById("ui_tree_mail_accounts");
let col = tree.editingColumn; // col.index
// only int allowed
if (col == tree.columns.getNamedColumn("account_or_server_type_order")) {
let charCode = event.which || event.keyCode;
let charStr = String.fromCharCode(charCode);
if (!/\d/.test(charStr))
event.preventDefault();
}
}
};
window.addEventListener(
'load', function (e) {
removeEventListener('load', arguments.callee, true);
firetray.UIOptions.onLoad(); },
false);
window.addEventListener(
'unload', function (e) {
removeEventListener('unload', arguments.callee, true);
firetray.UIOptions.onQuit(); },
false);

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://firetray/skin/overlay.css" type="text/css"?>
<!DOCTYPE prefwindow SYSTEM "chrome://firetray/locale/options.dtd">
<prefwindow id="firetray-preferences"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&prefwindow.title;"
onload="firetray.UIOptions.onLoad()">
title="&prefwindow.title;" minwidth="360px">
<script type="application/x-javascript" src="options.js" />
@ -13,18 +13,66 @@
<preferences>
<preference id="pref_bool_close_hides"
name="extensions.firetray.close_hides" type="bool"/>
<preference id="pref_string_mail_accounts"
name="extensions.firetray.mail_accounts" type="string"/>
</preferences>
<groupbox>
<checkbox id="ui_close_hides" preference="pref_bool_close_hides"
label="&bool_close_hides.label;"
accesskey="&bool_close_hides.accesskey;"/>
</groupbox>
<groupbox id="accounts_box"> <!-- firetray.UIOptions.accountBoxId -->
<caption label="&mail_accounts_exclude;"/>
<!-- accounts are dynamically added here with insert_accounts_name() functions, called at the bottom of this file -->
</groupbox>
<tabbox>
<tabs>
<tab label="&general_options;"/>
<tab label="&input_options;"/>
<tab label="&mail_options;" id="mail_tab" />
</tabs>
<tabpanels>
<tabpanel id="general_tabpanel">
<groupbox>
<checkbox id="ui_close_hides" preference="pref_bool_close_hides"
label="&bool_close_hides.label;"
accesskey="&bool_close_hides.accesskey;"/>
</groupbox>
</tabpanel>
<tabpanel id="input_tabpanel">
</tabpanel>
<tabpanel id="mail_tabpanel">
<groupbox flex="1">
<caption label="&unread_count_account_exceptions;"
tooltiptext="&unread_count_account_exceptions.tooltip;" />
<tree id="ui_tree_mail_accounts" flex="1" rows="10"
seltype="single" editable="true"
preference-editable="true"
preference="pref_string_mail_accounts"
onsynctopreference="return firetray.UIOptions.saveTreeAccountsOrServerTypes();">
<treecols>
<treecol id="account_or_server_type_name" editable="false" flex="2"
persist="width" primary="true" label="&account_or_server_type_name;"
tooltiptext="&account_or_server_type_name.tooltip;"/>
<splitter class="tree-splitter" resizeafter="grow"/>
<treecol id="account_or_server_type_excluded" type="checkbox" editable="true"
label="&account_or_server_type_excluded;" flex="1" persist="width"
tooltiptext="&account_or_server_type_excluded.tooltip;"/>
<splitter class="tree-splitter" resizeafter="grow"/>
<treecol id="account_or_server_type_order" editable="true"
persist="width"
flex="1" hidden= "true" label="&account_or_server_type_order;"
tooltiptext="&account_or_server_type_order.tooltip;"/>
</treecols>
<treechildren id="ui_mail_accounts" flex="1" />
</tree>
</groupbox>
</tabpanel>
</tabpanels>
</tabbox>
</prefpane>

View File

@ -1,5 +1,19 @@
<!ENTITY prefwindow.title "FireTray preferences">
<!ENTITY pane1.title "FireTray preferences">
<!ENTITY general_options "General">
<!ENTITY input_options "Input">
<!ENTITY mail_options "Mail">
<!ENTITY bool_close_hides.label "Closing windows hides to tray">
<!ENTITY bool_close_hides.accesskey "C">
<!ENTITY mail_accounts_exclude "Mail accounts to exclude" >
<!ENTITY unread_count_account_exceptions "Included accounts">
<!ENTITY unread_count_account_exceptions.tooltip "Included accounts for unread message count">
<!ENTITY account_or_server_type_name "Account">
<!ENTITY account_or_server_type_name.tooltip "Account name or type">
<!ENTITY account_or_server_type_excluded "Included">
<!ENTITY account_or_server_type_excluded.tooltip "Includes accounts or types into unread messages count">
<!ENTITY account_or_server_type_order "Order">
<!ENTITY account_or_server_type_order.tooltip "Order in which mail server types are displayed. Double-clic to edit.">

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

View File

@ -1,22 +1,25 @@
/* This is just an example. You shouldn't do this. */
#firetray-hello
{
color: red ! important;
treechildren::-moz-tree-checkbox {
list-style-image: none;
-moz-box-align: center;
}
#firetray-toolbar-button
{
list-style-image: url("chrome://firetray/skin/toolbar-button.png");
-moz-image-region: rect(0px 24px 24px 0px);
treechildren::-moz-tree-checkbox(checked) {
/* css for checked cells */
list-style-image: url("chrome://firetray/skin/cbox-check.gif");
}
#firetray-toolbar-button:hover
{
-moz-image-region: rect(24px 24px 48px 0px);
treechildren::-moz-tree-checkbox(checked, disabled) {
/* css for disabled checkboxes */
list-style-image: url("chrome://firetray/skin/cbox-disabled.gif");
}
[iconsize="small"] #firetray-toolbar-button
{
-moz-image-region: rect( 0px 40px 16px 24px);
/* properties="disabled" */
treechildren::-moz-tree-cell-text(disabled) {
color: GrayText;
}
[iconsize="small"] #firetray-toolbar-button:hover
{
-moz-image-region: rect(24px 40px 40px 24px);
/*
treechildren::-moz-tree-cell(disabled) {
background-color: #eeeeee;
}
*/

View File

@ -6,4 +6,5 @@ pref("browser.tabs.warnOnClose", false);
// Extension prefs
pref("extensions.firetray.close_hides", true);
pref("extensions.firetray.accounts_to_exclude", "");
// exposed in 1 tree, hence 2 branches: serverTypes, excludedAccounts
pref("extensions.firetray.mail_accounts", '{ "serverTypes": {"pop3":{"order":1,"excluded":false}, "imap":{"order":1,"excluded":false}, "movemail":{"order":2,"excluded":true}, "none":{"order":3,"excluded":false}, "rss":{"order":4,"excluded":true}, "nntp":{"order":5,"excluded":true}}, "excludedAccounts": [] }'); // JSON

View File

@ -188,7 +188,7 @@ firetray.IconLinux = {
setText: function(text, color) { // TODO: split into smaller functions;
LOG("setText");
if (typeof(text) != "string" )
if (typeof(text) != "string")
throw new TypeError();
try {

View File

@ -30,19 +30,6 @@ if ("undefined" == typeof(firetray)) {
firetray.Messaging = {
// TODO: turn into pref.
/* NOTE: definition checks not implemented on purpose (performance mainly)
should be well defined in default prefs, and new types are unlikely to
appear soon. */
SERVER_TYPES: {
"pop3": { order: 1, excluded: false },
"imap": { order: 1, excluded: false },
"movemail": { order: 2, excluded: true },
"none": { order: 3, excluded: false },
"rss": { order: 4, excluded: true },
"nntp": { order: 5, excluded: true }
},
_unreadMsgCount: 0,
enable: function() {
@ -85,27 +72,22 @@ firetray.Messaging = {
}
},
/**
* gets the accounts_to_exclude preference which is a stringified Array
* containing the keys of the accounts to exclude
*/
getPrefAccountsExcluded: function() {
return firetray.Utils.prefService.getCharPref('accounts_to_exclude').split(',') || [];
},
/**
* computes total unread message count
* TODO: check news accounts shouldn't be considered
*/
updateUnreadMsgCount: function() {
LOG("unreadMsgCount");
let mailAccounts = firetray.Utils.getObjPref('mail_accounts');
let serverTypes = mailAccounts["serverTypes"];
let excludedAccounts = mailAccounts["excludedAccounts"];
this._unreadMsgCount = 0; // reset
try {
let accounts = new this.Accounts();
for (let accountServer in accounts) {
if ( (this.SERVER_TYPES[accountServer.type].excluded)
|| (this.getPrefAccountsExcluded().indexOf(accountServer.key) >= 0) )
if ( (serverTypes[accountServer.type].excluded)
|| (excludedAccounts.indexOf(accountServer.key) >= 0) )
continue;
let rootFolder = accountServer.rootFolder; // nsIMsgFolder
@ -172,13 +154,15 @@ firetray.Messaging.Accounts.prototype.__iterator__ = function() {
accountServers[i] = accountServer;
}
let mailAccounts = firetray.Utils.getObjPref('mail_accounts');
let serverTypes = mailAccounts["serverTypes"];
if (this.sortByTypeAndName) {
accountServers.sort(function(a,b) {
if (firetray.Messaging.SERVER_TYPES[a.type].order
< firetray.Messaging.SERVER_TYPES[b.type].order)
if (serverTypes[a.type].order
< serverTypes[b.type].order)
return -1;
if (firetray.Messaging.SERVER_TYPES[a.type].order
> firetray.Messaging.SERVER_TYPES[b.type].order)
if (serverTypes[a.type].order
> serverTypes[b.type].order)
return 1;
if (a.prettyName < b.prettyName)
return -1;
@ -193,3 +177,23 @@ firetray.Messaging.Accounts.prototype.__iterator__ = function() {
yield accountServers[i];
}
};
/**
* return accounts grouped by mail_accounts.
*
* ex: { movemail: {"server1", "server2"}, imap: {"server3"} }
*/
firetray.Messaging.accountsByServerType = function() {
let accountsByServerType = {};
let accounts = new firetray.Messaging.Accounts(false);
for (let accountServer in accounts) {
let accountServerKey = accountServer.key.toString();
let accountServerName = accountServer.prettyName;
let accountServerType = accountServer.type;
if (typeof(accountsByServerType[accountServerType]) == "undefined")
accountsByServerType[accountServerType] = [];
accountsByServerType[accountServerType].push(
{ key: accountServerKey, name: accountServerName });
}
return accountsByServerType;
};

View File

@ -2,7 +2,8 @@
var EXPORTED_SYMBOLS =
[ "firetray", "Cc", "Ci", "Cu", "LOG", "WARN", "ERROR",
"FIREFOX_ID", "THUNDERBIRD_ID", "SEAMONKEY_ID" ];
"FIREFOX_ID", "THUNDERBIRD_ID", "SEAMONKEY_ID",
"XPath", "isArray" ];
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -38,16 +39,32 @@ firetray.Utils = {
prefService: Services.prefs.getBranch("extensions.firetray."),
strings: Services.strings.createBundle("chrome://firetray/locale/overlay.properties"),
dumpObj: function(obj) {
let str = "";
for(i in obj) {
try {
str += "obj["+i+"]: " + obj[i] + "\n";
} catch(e) {
str += "obj["+i+"]: Unavailable\n";
}
getObjPref: function(prefStr) {
try {
var objPref = JSON.parse(
firetray.Utils.prefService.getCharPref(prefStr));
} catch (x) {
ERROR(x);
}
LOG(str);
return objPref;
},
setObjPref: function(prefStr, obj) {
LOG(obj);
try {
firetray.Utils.prefService.setCharPref(prefStr, JSON.stringify(obj));
} catch (x) {
ERROR(x);
}
},
getArrayPref: function(prefStr) {
let arrayPref = this.getObjPref(prefStr);
if (!isArray(arrayPref)) throw new TypeError();
return arrayPref;
},
setArrayPref: function(prefStr, aArray) {
if (!isArray(aArray)) throw new TypeError();
this.setObjPref(prefStr, aArray);
},
QueryInterfaces: function(obj) {
@ -84,6 +101,85 @@ firetray.Utils = {
let protocolHandler = Cc["@mozilla.org/network/protocol;1?name=file"]
.createInstance(Ci.nsIFileProtocolHandler);
return protocolHandler.getFileFromURLSpec(aPath).path;
},
dumpObj: function(obj) {
let str = "";
for(i in obj) {
try {
str += "obj["+i+"]: " + obj[i] + "\n";
} catch(e) {
str += "obj["+i+"]: Unavailable\n";
}
}
LOG(str);
},
_nsResolver: function(prefix) {
var ns = {
xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
};
return ns[prefix] || null;
},
// adapted from http://code.google.com/p/jslibs/wiki/InternalTipsAndTricks
XPath: function(ref, xpath) {
var doc = ref.ownerDocument || ref;
const XPathResult = Ci.nsIDOMXPathResult;
try {
let that = this;
var result = doc.evaluate(xpath, ref, that._nsResolver,
XPathResult.ANY_TYPE, null);
} catch (x) {
ERROR(x);
}
LOG("XPathResult="+result.resultType);
switch (result.resultType) {
case XPathResult.NUMBER_TYPE:
return result.numberValue;
case XPathResult.BOOLEAN_TYPE:
return result.booleanValue;
case XPathResult.STRING_TYPE:
return result.stringValue;
} // else XPathResult.UNORDERED_NODE_ITERATOR_TYPE
var list = [];
try {
for (let node = result.iterateNext(); node; node = result.iterateNext()) {
LOG("node="+node.nodeName);
switch (node.nodeType) {
case node.ATTRIBUTE_NODE:
list.push(node.value);
break;
case node.TEXT_NODE:
list.push(node.data);
break;
default:
list.push(node);
}
}
} catch (x) {
ERROR(x);
}
return list;
}
};
// http://stackoverflow.com/questions/767486/how-do-you-check-if-a-variable-is-an-array-in-javascript
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
// http://stackoverflow.com/questions/18912/how-to-find-keys-of-a-hash
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
if(!Object.keys) Object.keys = function(o){
if (o !== Object(o))
throw new TypeError('Object.keys called on non-object');
var ret=[],p;
for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
return ret;
};