define([
|
'dojo/_base/lang',
|
'dojo/_base/array',
|
'dojo/_base/html',
|
'dojo/_base/sniff',
|
'dojo/_base/config',
|
'dojo/io-query',
|
'dojo/query',
|
'dojo/NodeList-traverse',
|
'dojo/Deferred',
|
'dojo/promise/all',
|
'dojo/on',
|
'dojo/json',
|
'dojo/cookie',
|
'dojo/number',
|
'dojo/date/locale',
|
'dojo/i18n!dojo/cldr/nls/number',
|
'dojox/encoding/base64',
|
'./shared/utils'
|
],
|
|
function(lang, array, html, has, config, ioQuery, query, nlt, Deferred, all, on, json, cookie,
|
dojoNumber, dateLocale, nlsBundle, base64,
|
sharedUtils
|
) {
|
/* global esriConfig, dojoConfig, ActiveXObject, testLoad */
|
var mo = {};
|
|
nlt = null;
|
|
lang.mixin(mo, sharedUtils);
|
|
if (!window.atob) {
|
window.atob = function(b64) {
|
var bytes = base64.decode(b64);
|
var str = "";
|
for (var i = 0, len = bytes.length; i < len; i++) {
|
str += String.fromCharCode(bytes[i]);
|
}
|
return str;
|
};
|
}
|
if (!window.btob) {
|
window.btob = function(str) {
|
var bytes = [];
|
for (var i = 0, len = str.length; i < len; i++) {
|
bytes.push(String.charCodeAt(str[i]));
|
}
|
|
return base64.encode(bytes);
|
};
|
}
|
|
var fileAPIJsStatus = 'unload'; // unload, loading, loaded
|
function _loadFileAPIJs(prePath, cb) {
|
prePath = prePath || "";
|
var loaded = 0,
|
completeCb = function() {
|
loaded++;
|
if (loaded === tests.length) {
|
cb();
|
}
|
},
|
tests = [{
|
test: window.File && window.FileReader && window.FileList && window.Blob ||
|
!mo.file.isEnabledFlash(),
|
failure: [
|
prePath + "libs/polyfills/fileAPI/FileAPI.js"
|
],
|
callback: function() {
|
completeCb();
|
}
|
}];
|
|
for (var i = 0; i < tests.length; i++) {
|
testLoad(tests[i]);
|
}
|
}
|
|
//if no beforeId, append to head tag, or insert before the id
|
function loadStyleLink(id, href, beforeId) {
|
var def = new Deferred(), styleNode, styleLinkNode;
|
|
var hrefPath = require(mo.getRequireConfig()).toUrl(href);
|
//the cache will use the baseUrl + module as the key
|
if(require.cache['url:' + hrefPath]){
|
//when load css file into index.html as <style>, we need to fix the
|
//relative path used in css file
|
var cssStr = require.cache['url:' + hrefPath];
|
var fileName = hrefPath.split('/').pop();
|
var rpath = hrefPath.substr(0, hrefPath.length - fileName.length);
|
cssStr = addRelativePathInCss(cssStr, rpath);
|
if (beforeId) {
|
styleNode = html.create('style', {
|
id: id,
|
type: "text/css"
|
}, html.byId(beforeId), 'before');
|
} else {
|
styleNode = html.create('style', {
|
id: id,
|
type: "text/css"
|
}, document.getElementsByTagName('head')[0]);
|
}
|
|
if(styleNode.styleSheet && !styleNode.sheet){
|
//for IE
|
styleNode.styleSheet.cssText = cssStr;
|
}else{
|
styleNode.appendChild(html.toDom(cssStr));
|
}
|
def.resolve('load');
|
return def;
|
}
|
|
if (beforeId) {
|
styleLinkNode = html.create('link', {
|
id: id,
|
rel: "stylesheet",
|
type: "text/css",
|
href: hrefPath + '?wab_dv=' + window.deployVersion
|
}, html.byId(beforeId), 'before');
|
} else {
|
styleLinkNode = html.create('link', {
|
id: id,
|
rel: "stylesheet",
|
type: "text/css",
|
href: hrefPath + '?wab_dv=' + window.deployVersion
|
}, document.getElementsByTagName('head')[0]);
|
}
|
|
on(styleLinkNode, 'load', function() {
|
def.resolve('load');
|
});
|
|
var ti = setInterval(function() {
|
var loadedSheet;
|
if (array.some(document.styleSheets, function(styleSheet) {
|
if (styleSheet.href && styleSheet.href.substr(styleSheet.href.indexOf(href),
|
styleSheet.href.length) === href) {
|
loadedSheet = styleSheet;
|
return true;
|
}
|
})) {
|
try{
|
if (!def.isFulfilled() && (loadedSheet.cssRules && loadedSheet.cssRules.length ||
|
loadedSheet.rules && loadedSheet.rules.length)) {
|
def.resolve('load');
|
}
|
clearInterval(ti);
|
}catch(err){
|
}
|
}
|
}, 50);
|
return def;
|
}
|
|
|
function addRelativePathInCss(css, rpath){
|
var m = css.match(/url\([^)]+\)/gi), i, m2;
|
|
if (m === null || rpath === '') {
|
return css;
|
}
|
for (i = 0; i < m.length; i++) {
|
m2 = m[i].match(/(url\(["|']?)(.*)((?:['|"]?)\))/i);
|
if(m2.length >= 4){
|
var path = m2[2];
|
if(/^data:image\/.*;/.test(path)){
|
continue;
|
}
|
if(!rpath.endWith('/')){
|
rpath = rpath + '/';
|
}
|
css = css.replace(m2[1] + path + m2[3], m2[1] + rpath + path + m2[3]);
|
}
|
}
|
return css;
|
}
|
|
var errorCheckLists = [];
|
require.on("error", function(err) {
|
array.forEach(errorCheckLists, function(o) {
|
if (err.info[0] && err.info[0].indexOf(o.resKey) > -1) {
|
o.def.reject(err);
|
}
|
for (var p in err.info) {
|
if (p.indexOf(o.resKey) > -1) {
|
o.def.reject(err);
|
}
|
}
|
});
|
});
|
|
mo.checkError = function(resKey, def) {
|
//when resKey match a error, def will be reject
|
errorCheckLists.push({
|
resKey: resKey,
|
def: def
|
});
|
};
|
|
mo.replacePlaceHolder = function(obj, props) {
|
var str = json.stringify(obj),
|
m = str.match(/\$\{(\w)+\}/g),
|
i;
|
|
if (m === null) {
|
return obj;
|
}
|
for (i = 0; i < m.length; i++) {
|
var p = m[i].match(/(\w)+/g)[0];
|
if (props[p]) {
|
str = str.replace(m[i], props[p]);
|
}
|
}
|
return json.parse(str);
|
};
|
|
mo.changeUnit = function(val) {
|
var abs = Math.abs(val),
|
text, d, m, s;
|
d = Math.floor(abs);
|
m = Math.floor((abs - d) * 60);
|
s = (((abs - d) * 60 - m) * 60).toFixed(2);
|
//00B0 id degree character
|
text = d + '\u00B0' + ((m < 10) ? ('0' + m) : m) + '\'' + ((s < 10) ? ('0' + s) : s) + '"';
|
return text;
|
};
|
|
mo.formatTime = function(time) {
|
var s = time / 1000,
|
m = Math.floor(s / 60),
|
s2 = Number(s - m * 60).toFixed(1),
|
text = ((m < 10) ? '0' + m : m) + ':' + ((s2 < 10) ? '0' + s2 : s2);
|
return text;
|
};
|
|
mo.parseTime = function(text) {
|
var p = /(\d{2,})\:(\d{2})\.(\d{1})/,
|
m, t;
|
if (!p.test(text)) {
|
console.log('wrong time format.');
|
return -1;
|
}
|
m = text.match(p);
|
t = (parseInt(m[1], 10) * 60 + parseInt(m[2], 10) + parseInt(m[3], 10) / 10) * 1000;
|
return t;
|
};
|
|
mo.preloadImg = function(imgs, rpath) {
|
var imgArray = [];
|
if (typeof imgs === 'string') {
|
imgArray = [imgs];
|
} else {
|
imgArray = imgs;
|
}
|
array.forEach(imgArray, function(imgUrl) {
|
var img = new Image();
|
if (rpath) {
|
img.src = rpath + imgUrl;
|
} else {
|
img.src = imgUrl;
|
}
|
});
|
};
|
|
var testImageDom = null;
|
mo.getImagesSize = function(imageUrl){
|
var def = new Deferred();
|
|
if (!imageUrl || imageUrl.indexOf("http") !== 0) {
|
def.reject();
|
return def;
|
}
|
|
if(testImageDom === null){
|
testImageDom = html.create('img', {
|
id: '__test-image-size',
|
style: {
|
position: 'absolute',
|
left: '-9999px',
|
top: '-9999px'
|
}
|
}, document.body);
|
}
|
var testImageHandler = on(testImageDom, "load", function(){
|
clearTimeout(timeoutHandler);
|
timeoutHandler = null;
|
testImageHandler.remove();
|
|
var box = html.getContentBox(testImageDom);
|
|
if ((box.w === 1 && box.h === 1) || box.w === 0 || box.h === 0) {
|
def.reject();
|
return;
|
}
|
|
def.resolve([box.w, box.h]);
|
}, {});
|
|
var timeoutHandler = setTimeout(function(){
|
clearTimeout(timeoutHandler);
|
timeoutHandler = null;
|
// image URL is invalid or takes too long; don't update it
|
def.reject();
|
}, 5000);
|
|
html.setAttr(testImageDom, 'src', imageUrl);
|
|
return def;
|
};
|
|
mo.getPositionStyle = function(_position) {
|
var style = {};
|
if(!_position){
|
return style;
|
}
|
var position = lang.clone(_position);
|
if(window.isRTL){
|
var temp;
|
if(typeof position.left !== 'undefined' && typeof position.right !== 'undefined'){
|
temp = position.left;
|
position.left = position.right;
|
position.right = temp;
|
}else if(typeof position.left !== 'undefined'){
|
position.right = position.left;
|
delete position.left;
|
}else if(typeof position.right !== 'undefined'){
|
position.left = position.right;
|
delete position.right;
|
}
|
|
if(typeof position.paddingLeft !== 'undefined' &&
|
typeof position.paddingRight !== 'undefined'){
|
temp = position.paddingLeft;
|
position.paddingLeft = position.paddingRight;
|
position.paddingRight = temp;
|
}else if(typeof position.paddingLeft !== 'undefined'){
|
position.paddingRight = position.paddingLeft;
|
delete position.paddingLeft;
|
}else if(typeof position.paddingRight !== 'undefined'){
|
position.paddingLeft = position.paddingRight;
|
delete position.paddingRight;
|
}
|
}
|
|
var ps = ['left', 'top', 'right', 'bottom', 'width', 'height',
|
'padding', 'paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom'];
|
for (var i = 0; i < ps.length; i++) {
|
var p = ps[i];
|
if (typeof position[p] === 'number') {
|
style[p] = position[p] + 'px';
|
} else if (typeof position[p] !== 'undefined') {
|
style[p] = position[p];
|
}else{
|
if(p.substr(0, 7) === 'padding'){
|
style[p] = 0;
|
}else{
|
style[p] = 'auto';
|
}
|
}
|
}
|
|
if(typeof position.zIndex === 'undefined'){
|
//set zindex=auto instead of 0, because inner dom of widget may need to overlay other widget
|
//that has the same zindex.
|
style.zIndex = 'auto';
|
}else{
|
style.zIndex = position.zIndex;
|
}
|
return style;
|
};
|
|
/**
|
* compare two object/array recursively
|
* Note: null === null, undefined === undefined
|
*/
|
function isEqual(o1, o2) {
|
var leftChain, rightChain;
|
|
function compare2Objects(x, y) {
|
var p;
|
if(x === null && y === null || typeof x === 'undefined' && typeof y === 'undefined'){
|
return true;
|
}
|
|
if(x === null && y !== null || y === null && x !== null ||
|
typeof x === 'undefined' && typeof y !== 'undefined' ||
|
typeof y === 'undefined' && typeof x !== 'undefined'){
|
return false;
|
}
|
|
// remember that NaN === NaN returns false
|
// and isNaN(undefined) returns true
|
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
|
return true;
|
}
|
// Compare primitives and functions.
|
// Check if both arguments link to the same object.
|
// Especially useful on step when comparing prototypes
|
if (x === y) {
|
return true;
|
}
|
// Works in case when functions are created in constructor.
|
// Comparing dates is a common scenario. Another built-ins?
|
// We can even handle functions passed across iframes
|
if ((typeof x === 'function' && typeof y === 'function') ||
|
(x instanceof Date && y instanceof Date) ||
|
(x instanceof RegExp && y instanceof RegExp) ||
|
(x instanceof String && y instanceof String) ||
|
(x instanceof Number && y instanceof Number)) {
|
return x.toString() === y.toString();
|
}
|
// check for infinitive linking loops
|
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
|
return false;
|
}
|
// Quick checking of one object beeing a subset of another.
|
// todo: cache the structure of arguments[0] for performance
|
if (y !== null) {
|
for (p in y) {
|
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
|
return false;
|
} else if (typeof y[p] !== typeof x[p]) {
|
return false;
|
}
|
}
|
for (p in x) {
|
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
|
return false;
|
} else if (typeof y[p] !== typeof x[p]) {
|
return false;
|
}
|
switch (typeof(x[p])) {
|
case 'object':
|
case 'function':
|
leftChain.push(x);
|
rightChain.push(y);
|
if (!compare2Objects(x[p], y[p])) {
|
return false;
|
}
|
leftChain.pop();
|
rightChain.pop();
|
break;
|
default:
|
// remember that NaN === NaN returns false
|
if (isNaN(x[p]) && isNaN(y[p]) && typeof x[p] === 'number' && typeof y[p] === 'number') {
|
continue;
|
}
|
if (x[p] !== y[p]) {
|
return false;
|
}
|
break;
|
}
|
}
|
}
|
|
return true;
|
}
|
|
leftChain = []; //todo: this can be cached
|
rightChain = [];
|
if (!compare2Objects(o1, o2)) {
|
return false;
|
}
|
return true;
|
}
|
|
mo.isEqual = isEqual;
|
|
//merge the target and src object/array, return the merged object/array.
|
function merge(target, src) {
|
var array = Array.isArray(src);
|
var dst = array && [] || {};
|
|
if (array) {
|
target = target || [];
|
dst = dst.concat(target);
|
src.forEach(function(e, i) {
|
if (typeof target[i] === 'undefined') {
|
dst[i] = e;
|
} else if (typeof e === 'object') {
|
dst[i] = merge(target[i], e);
|
} else {
|
if (target.indexOf(e) === -1) {
|
dst.push(e);
|
}
|
}
|
});
|
} else {
|
if (target && typeof target === 'object') {
|
Object.keys(target).forEach(function(key) {
|
dst[key] = target[key];
|
});
|
}
|
Object.keys(src).forEach(function(key) {
|
if (typeof src[key] !== 'object' || !src[key]) {
|
dst[key] = src[key];
|
} else {
|
if (!target[key]) {
|
dst[key] = src[key];
|
} else {
|
dst[key] = merge(target[key], src[key]);
|
}
|
}
|
});
|
}
|
|
return dst;
|
}
|
|
function setVerticalCenter(contextNode) {
|
function doSet() {
|
var nodes = query('.jimu-vcenter-text', contextNode),
|
h, ph;
|
array.forEach(nodes, function(node) {
|
h = html.getContentBox(node).h;
|
html.setStyle(node, {
|
lineHeight: h + 'px'
|
});
|
}, this);
|
|
nodes = query('.jimu-vcenter', contextNode);
|
array.forEach(nodes, function(node) {
|
h = html.getContentBox(node).h;
|
ph = html.getContentBox(query(node).parent()[0]).h;
|
html.setStyle(node, {
|
marginTop: (ph - h) / 2 + 'px'
|
});
|
}, this);
|
}
|
|
//delay sometime to let browser update dom
|
setTimeout(doSet, 10);
|
}
|
|
mo.file = {
|
loadFileAPI: function() {
|
var def = new Deferred();
|
if (fileAPIJsStatus === 'unload') {
|
var prePath = !!window.isBuilder ? 'stemapp/' : "";
|
window.FileAPI = {
|
debug: false,
|
flash: true,
|
staticPath: prePath + 'libs/polyfills/fileAPI/',
|
flashUrl: prePath + 'libs/polyfills/fileAPI/FileAPI.flash.swf',
|
flashImageUrl: prePath + 'libs/polyfills/fileAPI/FileAPI.flash.image.swf'
|
};
|
|
_loadFileAPIJs(prePath, lang.hitch(this, function() {
|
fileAPIJsStatus = 'loaded';
|
def.resolve();
|
}));
|
fileAPIJsStatus = 'loading';
|
} else if (fileAPIJsStatus === 'loaded'){
|
def.resolve();
|
}
|
|
return def;
|
},
|
supportHTML5: function() {
|
if (window.File && window.FileReader && window.FileList && window.Blob) {
|
return true;
|
} else {
|
return false;
|
}
|
},
|
supportFileAPI: function() {
|
if (has('safari') && has('safari') < 6) {
|
return false;
|
}
|
if (window.FileAPI && window.FileAPI.readAsDataURL) {
|
return true;
|
}
|
return false;
|
},
|
isEnabledFlash: function(){
|
var swf = null;
|
if (document.all) {
|
try{
|
swf = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
|
}catch(e) {
|
swf = null;
|
}
|
} else {
|
if (navigator.plugins && navigator.plugins.length > 0) {
|
swf = navigator.plugins["Shockwave Flash"];
|
}
|
}
|
return !!swf;
|
},
|
containSeparator: function(path) {
|
if (path.indexOf("/") >= 0) {
|
return true;
|
} else {
|
if (path.indexOf("\\") >= 0) {
|
return true;
|
} else {
|
return false;
|
}
|
}
|
},
|
getNameFromPath: function(path) {
|
var separator = "";
|
if (path.indexOf("/") >= 0) {
|
separator = "/";
|
} else {
|
separator = "\\";
|
}
|
var segment = path.split(separator);
|
if (segment.length > 0) {
|
return segment[segment.length - 1];
|
} else {
|
return null;
|
}
|
|
},
|
getFolderFromPath: function(path) {
|
return path.substr(0, path.length - mo.file.getNameFromPath(path).length);
|
},
|
/********
|
* read file by HTML5 API.
|
*
|
* parameters:
|
* file: the file will be read.
|
* filter: file type filter, files which don't match the filter will not be read and
|
return false.
|
* maxSize: file size which exceeds the size will return false;
|
* cb: the callback function when file is read completed, signature: (err, fileName, fileData)
|
*/
|
readFile: function(fileEvt, filter, maxSize, cb) {
|
if (this.supportHTML5()) {
|
var file = fileEvt.target.files[0];
|
if (!file) {
|
return;
|
}
|
// Only process image files.
|
if (!file.type.match(filter)) {
|
// cb("Invalid file type.");
|
cb({
|
errCode: "invalidType"
|
});
|
return;
|
}
|
|
if (file.size >= maxSize) {
|
// cb("File size cannot exceed " + Math.floor(maxSize / 1024) + "KB.");
|
cb({
|
errCode: "exceed"
|
});
|
return;
|
}
|
|
var reader = new FileReader();
|
// Closure to capture the file information.
|
reader.onload = function(e) {
|
cb(null, file.name, e.target.result);
|
};
|
// Read in the image file as a data URL.
|
reader.readAsDataURL(file);
|
} else if (this.supportFileAPI()) {
|
var files = window.FileAPI.getFiles(fileEvt);
|
|
// Only process image files.
|
if (!files[0].type.match(filter)) {
|
// cb("Invalid file type.");
|
cb({
|
errCode: "invalidType"
|
});
|
return;
|
}
|
|
if (files[0].size >= maxSize) {
|
// cb("File size cannot exceed " + Math.floor(maxSize / 1048576) + "M.");
|
cb({
|
errCode: "exceed"
|
});
|
return;
|
}
|
|
window.FileAPI.readAsDataURL(files[0], function(evt) {
|
if (evt && evt.result) {
|
cb(null, files[0].name, evt.result);
|
} else {
|
cb({
|
errCode: "readError"
|
});
|
}
|
});
|
}
|
}
|
};
|
|
///////////////////widget json(in app config json) processing
|
|
mo.getUriInfo = function getUriInfo(uri) {
|
var pos, firstSeg, info = {},
|
amdFolder;
|
|
pos = uri.indexOf('/');
|
firstSeg = uri.substring(0, pos);
|
|
//config using package
|
amdFolder = uri.substring(0, uri.lastIndexOf('/') + 1);
|
info.folderUrl = require(mo.getRequireConfig()).toUrl(amdFolder);
|
info.amdFolder = amdFolder;
|
|
info.url = info.folderUrl;//for backward compatibility
|
|
if(/^http(s)?:\/\//.test(uri) || /^\/\//.test(uri)){
|
info.isRemote = true;
|
}
|
|
return info;
|
};
|
|
mo.widgetJson = (function(){
|
var ret = {};
|
|
ret.addManifest2WidgetJson = function(widgetJson, manifest){
|
lang.mixin(widgetJson, manifest.properties);
|
widgetJson.name = manifest.name;
|
if(!widgetJson.label){
|
widgetJson.label = manifest.label;
|
}
|
widgetJson.manifest = manifest;
|
widgetJson.isRemote = manifest.isRemote;
|
if(widgetJson.isRemote){
|
widgetJson.itemId = manifest.itemId;
|
}
|
if(manifest.featureActions){
|
widgetJson.featureActions = manifest.featureActions;
|
}
|
|
if (!widgetJson.icon) {
|
widgetJson.icon = manifest.icon;
|
}
|
|
if (!widgetJson.thumbnail) {
|
widgetJson.thumbnail = manifest.thumbnail;
|
}
|
|
widgetJson.folderUrl = manifest.folderUrl;
|
widgetJson.amdFolder = manifest.amdFolder;
|
};
|
|
ret.removeManifestFromWidgetJson = function(widgetJson){
|
//we set property to undefined, instead of delete them.
|
//The reason is: configmanager can't hanle delete properties for now
|
if(!widgetJson.manifest){
|
return;
|
}
|
for(var p in widgetJson.manifest.properties){
|
widgetJson[p] = undefined;
|
}
|
widgetJson.name = undefined;
|
widgetJson.label = undefined;
|
widgetJson.featureActions = undefined;
|
widgetJson.manifest = undefined;
|
};
|
|
ret.getUriFromItem = function(item){
|
if(!item.url){
|
return null;
|
}
|
|
return ret.getFolderUrlFromItem(item) + 'Widget';
|
};
|
|
ret.getFolderUrlFromItem = function(item){
|
if(!item.url){
|
return null;
|
}
|
|
var url;
|
if(/manifest\.json$/.test(item.url)){
|
url = item.url.substring(0, item.url.length - 'manifest.json'.length);
|
}else if(/\/$/.test(item.url)){
|
url = item.url;
|
}else{
|
url = item.url + '/';
|
}
|
|
if(window.location.protocol === "https:"){
|
url = url.replace(/^http:\/\//, 'https://');
|
}
|
return url;
|
};
|
|
return ret;
|
})();
|
|
|
mo.getRequireConfig = function() {
|
/* global jimuConfig */
|
if (jimuConfig) {
|
var packages = [];
|
if (jimuConfig.widgetsPackage) {
|
packages = packages.concat(jimuConfig.widgetsPackage);
|
}
|
if (jimuConfig.themesPackage) {
|
packages = packages.concat(jimuConfig.themesPackage);
|
}
|
if (jimuConfig.configsPackage) {
|
packages = packages.concat(jimuConfig.configsPackage);
|
}
|
return {
|
packages: packages
|
};
|
} else {
|
return {};
|
}
|
};
|
|
mo.getServices = function() {
|
return servicesObj;
|
};
|
|
mo.getAncestorWindow = function() {
|
var w = window;
|
while (w && w.parent && w !== w.parent) {
|
w = w.parent;
|
}
|
return w;
|
};
|
|
mo.getAncestorDom = function(child, verifyFunc,
|
/*HTMLElement|Number optional */ maxLoopSizeOrDom) {
|
if (child && child.nodeType === 1) {
|
if (verifyFunc && typeof verifyFunc === 'function') {
|
var maxLoopSize = 100;
|
var maxLoopDom = document.body;
|
|
if (maxLoopSizeOrDom) {
|
if (typeof maxLoopSizeOrDom === 'number') {
|
//Number
|
maxLoopSizeOrDom = parseInt(maxLoopSizeOrDom, 10);
|
if (maxLoopSizeOrDom > 0) {
|
maxLoopSize = maxLoopSizeOrDom;
|
}
|
} else if (maxLoopSizeOrDom.nodeType === 1) {
|
//HTMLElement
|
maxLoopDom = maxLoopSizeOrDom;
|
}
|
}
|
|
var loop = 0;
|
while (child.parentNode && loop < maxLoopSize &&
|
html.isDescendant(child.parentNode, maxLoopDom)) {
|
if (verifyFunc(child.parentNode)) {
|
return child.parentNode;
|
}
|
child = child.parentNode;
|
loop++;
|
}
|
}
|
}
|
return null;
|
};
|
|
mo.bindClickAndDblclickEvents = function(dom, clickCallback, dblclickCallback,
|
/* optional */ _timeout) {
|
var handle = null;
|
var isValidDom = dom && dom.nodeType === 1;
|
var isValidClick = clickCallback && typeof clickCallback === 'function';
|
var isValidDblclick = dblclickCallback && typeof dblclickCallback === 'function';
|
var isValid = isValidDom && isValidClick && isValidDblclick;
|
if (isValid) {
|
var timeout = 200;
|
if (_timeout && typeof _timeout === 'number') {
|
var t = parseInt(_timeout, 10);
|
if (t > 0) {
|
timeout = t;
|
}
|
}
|
|
var clickCount = 0;
|
handle = on(dom, 'click', function(evt) {
|
clickCount++;
|
if (clickCount === 1) {
|
setTimeout(function() {
|
if (clickCount === 1) {
|
clickCount = 0;
|
clickCallback(evt);
|
}
|
}, timeout);
|
} else if (clickCount === 2) {
|
clickCount = 0;
|
dblclickCallback(evt);
|
}
|
});
|
}
|
return handle;
|
};
|
|
mo.isScrollToBottom = function(dom) {
|
var box = html.getContentBox(dom);
|
var a = dom.scrollTop + box.h;
|
var b = dom.scrollHeight - a;
|
return b < 1;
|
};
|
|
mo.getAllItemTypes = function() {
|
var allTypes = [];
|
//Web Content
|
var maps1 = ['Web Map', 'Web Scene', 'CityEngine Web Scene'];
|
var layers1 = ['Feature Service', 'Map Service', 'Image Service', 'KML', 'WMS',
|
'Feature Collection', 'Feature Collection Template', 'Geodata Service', 'Globe Service'];
|
var tools1 = ['Geometry Service', 'Geocoding Service', 'Network Analysis Service',
|
'Geoprocessing Service'];
|
var applications1 = ['Web Mapping Application', 'Mobile Application', 'Code Attachment',
|
'Operations Dashboard Add In', 'Operation View'];
|
var datafiles1 = ['Symbol Set', 'Color Set', 'Shapefile', 'CSV', 'Service Definition',
|
'Document Link', 'Microsoft Word', 'Microsoft PowerPoint', 'Microsoft Excel', 'PDF',
|
'Image', 'Visio Document'];
|
//Desktop Content
|
var maps2 = ['Map Document', 'Map Package', 'Tile Package', 'ArcPad Package',
|
'Explorer Map', 'Globe Document', 'Scene Document', 'Published Map', 'Map Template',
|
'Windows Mobile Package'];
|
var layers2 = ['Layer', 'Layer Package', 'Explorer Layer'];
|
var tools2 = ['Geoprocessing Package', 'Geoprocessing Sample', 'Locator Package',
|
'Rule Package'];
|
var applications2 = ['Workflow Manager Package', 'Desktop Application',
|
'Desktop Application Template', 'Code Sample', 'Desktop Add In', 'Explorer Add In'];
|
|
allTypes = allTypes.concat(maps1).concat(layers1).concat(tools1)
|
.concat(applications1).concat(datafiles1);
|
allTypes = allTypes.concat(maps2).concat(layers2).concat(tools2).concat(applications2);
|
return allTypes;
|
};
|
|
mo.getItemQueryStringByTypes = function(itemTypes) {
|
var queryStr = '';
|
var allTypes = mo.getAllItemTypes();
|
if (itemTypes && itemTypes.length > 0) {
|
if (itemTypes.length > 0) {
|
var validStr = '';
|
array.forEach(itemTypes, function(type, index) {
|
var s = ' type:"' + type + '" ';
|
validStr += s;
|
if (index !== itemTypes.length - 1) {
|
validStr += ' OR ';
|
}
|
});
|
queryStr = ' ( ' + validStr + ' ) ';
|
var sumAllTypes = itemTypes.concat(allTypes);
|
var removedTypes = array.filter(sumAllTypes, function(removedType){
|
return array.every(itemTypes, function(itemType){
|
return itemType.toLowerCase().indexOf(removedType.toLowerCase()) < 0;
|
});
|
});
|
|
array.forEach(removedTypes, function(type) {
|
var s = ' -type:"' + type + '" ';
|
queryStr += s;
|
});
|
}
|
}
|
return queryStr;
|
};
|
|
mo.getItemQueryStringByTypeKeywords = function(typeKeywords){
|
var queryStr = '';
|
//must use double quotation marks around typeKeywords
|
//typekeywords:"Web AppBuilder" or typekeywords:"Web AppBuilder,Web Map"
|
if(typeKeywords && typeKeywords.length > 0){
|
queryStr = ' typekeywords:"' + typeKeywords.join(',') + '" ';
|
}
|
return queryStr;
|
};
|
|
mo.isNotEmptyString = function(str, /* optional */ trim) {
|
var b = str && typeof str === 'string';
|
if (b) {
|
if (trim) {
|
return b && lang.trim(str);
|
} else {
|
return true;
|
}
|
} else {
|
return false;
|
}
|
};
|
|
mo.isNotEmptyStringArray = function(strArray, /* optional */ trim){
|
for(var key = 0; key < strArray.length; key++){
|
var str = strArray[key];
|
var strVal = str.value ? str.value : str;
|
var isNotEmpty = mo.isNotEmptyString(strVal, trim);
|
if(!isNotEmpty){
|
return false;
|
}
|
}
|
return true;
|
};
|
|
mo.isValidNumber = function(num){
|
return typeof num === 'number' && !isNaN(num);
|
};
|
|
mo.isValidNumberArray = function(numArray){
|
for(var key = 0; key < numArray.length; key++){
|
var num = numArray[key];
|
num = (num.value || num.value === 0) ? num.value : num;
|
var isValid = mo.isValidNumber(num);
|
if(!isValid){
|
return false;
|
}
|
}
|
return true;
|
};
|
|
mo.isValidDate = function(date){
|
if(date){ //null, '', undefined
|
try {
|
var d = new Date(date);
|
return !isNaN(d.getTime()); // d.toString() === 'Invalid Date'
|
}catch (err) {
|
console.error(err);
|
return false;
|
}
|
}else{
|
return false;
|
}
|
};
|
|
mo.isObject = function(o) {
|
return o && typeof o === 'object';
|
};
|
|
|
mo.getRandomString = function() {
|
var str = Math.random().toString();
|
str = str.slice(2, str.length);
|
return str;
|
};
|
|
mo._getDomainsByServerName = function(serverName){
|
var splits = serverName.split('.');
|
var length = splits.length;
|
var domains = array.map(splits, lang.hitch(this, function(v, index){
|
// jshint unused:false
|
var arr = splits.slice(index, length);
|
var str = "";
|
var lastIndex = arr.length - 1;
|
array.forEach(arr, lang.hitch(this, function(s, idx){
|
str += s;
|
if(idx !== lastIndex){
|
str += '.';
|
}
|
}));
|
return str;
|
}));
|
return domains;
|
};
|
|
mo.removeCookie = function(cookieName, path){
|
var domains = this._getDomainsByServerName(window.location.hostname);
|
|
array.forEach(domains, lang.hitch(this, function(domainName){
|
cookie(cookieName, null, {
|
expires: -1,
|
path: path
|
});
|
|
cookie(cookieName, null, {
|
expires: -1,
|
path: path,
|
domain: domainName
|
});
|
|
cookie(cookieName, null, {
|
expires: -1,
|
path: path,
|
domain: '.' + domainName
|
});
|
}));
|
};
|
|
mo.isLocaleChanged = function(oldLocale, newLocale){
|
return !oldLocale.startWith(newLocale);
|
};
|
|
mo.hashToObject = function(hashStr){
|
hashStr = hashStr.replace('#', '');
|
var hashObj = ioQuery.queryToObject(hashStr);
|
for (var p in hashObj) {
|
if (hashObj.hasOwnProperty(p)) {
|
try {
|
hashObj[p] = json.parse(hashObj[p]);
|
} catch (err) {
|
continue;
|
}
|
}
|
}
|
return hashObj;
|
};
|
|
mo.reCreateObject = function(obj) {
|
//summary:
|
// because of dojo's lang.isArray issue, we need re-create the array properties
|
var ret;
|
|
function copyArray(_array) {
|
var retArray = [];
|
_array.forEach(function(a) {
|
if (Array.isArray(a)) {
|
retArray.push(copyArray(a));
|
} else if (typeof a === 'object') {
|
retArray.push(copyObject(a));
|
} else {
|
retArray.push(a);
|
}
|
});
|
return retArray;
|
}
|
|
function copyObject(_obj) {
|
var ret = {};
|
for (var p in _obj) {
|
if (!_obj.hasOwnProperty(p)) {
|
continue;
|
}
|
if(_obj[p] === null){
|
ret[p] = null;
|
}else if (Array.isArray(_obj[p])) {
|
ret[p] = copyArray(_obj[p]);
|
} else if (typeof _obj[p] === 'object') {
|
ret[p] = copyObject(_obj[p]);
|
} else {
|
ret[p] = _obj[p];
|
}
|
}
|
return ret;
|
}
|
|
if (Array.isArray(obj)) {
|
ret = copyArray(obj);
|
} else {
|
ret = copyObject(obj);
|
}
|
return ret;
|
};
|
|
mo.setVerticalCenter = setVerticalCenter;
|
mo.merge = merge;
|
mo.loadStyleLink = loadStyleLink;
|
|
mo.changeLocation = function(newUrl){
|
// debugger;
|
if (window.history.pushState) {
|
window.history.pushState({path:newUrl}, '', encodeURI(newUrl));
|
}/*else{
|
window.location.href = newUrl;
|
}*/
|
};
|
|
/////////////widget and theme manifest processing/////////
|
mo.manifest = (function(){
|
var ret = {};
|
|
function addThemeManifestProperies(manifest) {
|
manifest.panels.forEach(function(panel) {
|
panel.uri = 'panels/' + panel.name + '/Panel.js';
|
});
|
|
manifest.styles.forEach(function(style) {
|
style.uri = 'styles/' + style.name + '/style.css';
|
});
|
|
manifest.layouts.forEach(function(layout) {
|
layout.uri = 'layouts/' + layout.name + '/config.json';
|
layout.icon = 'layouts/' + layout.name + '/icon.png';
|
layout.RTLIcon = 'layouts/' + layout.name + '/icon_rtl.png';
|
});
|
}
|
|
function addWidgetManifestProperties(manifest) {
|
//because tingo db engine doesn't support 2D, 3D property, so, change here
|
if (typeof manifest['2D'] !== 'undefined') {
|
manifest.support2D = manifest['2D'];
|
}
|
if (typeof manifest['3D'] !== 'undefined') {
|
manifest.support3D = manifest['3D'];
|
}
|
|
if (typeof manifest['2D'] === 'undefined' && typeof manifest['3D'] === 'undefined') {
|
manifest.support2D = true;
|
}
|
|
delete manifest['2D'];
|
delete manifest['3D'];
|
|
if (typeof manifest.properties === 'undefined') {
|
manifest.properties = {};
|
}
|
|
sharedUtils.processWidgetProperties(manifest);
|
}
|
|
ret.addManifestProperies = function(manifest) {
|
if(!manifest.icon){
|
manifest.icon = manifest.folderUrl + 'images/icon.png?wab_dv=' + window.deployVersion;
|
}
|
|
if (!manifest.thumbnail) {
|
manifest.thumbnail = manifest.folderUrl + 'images/thumbnail.png';
|
}
|
|
if(manifest.category === "theme") {
|
addThemeManifestProperies(manifest);
|
} else {
|
addWidgetManifestProperties(manifest);
|
}
|
};
|
|
ret.processManifestLabel = function(manifest, locale){
|
var langCode = locale.split('-')[0];
|
manifest.label = manifest.i18nLabels && (manifest.i18nLabels[locale] || manifest.i18nLabels[langCode] ||
|
manifest.i18nLabels.defaultLabel) ||
|
manifest.label ||
|
manifest.name;
|
if(manifest.layouts){
|
array.forEach(manifest.layouts, function(layout){
|
var key = 'i18nLabels_layout_' + layout.name;
|
layout.label = manifest[key] && (manifest[key][locale] ||
|
manifest[key].defaultLabel) ||
|
layout.label ||
|
layout.name;
|
});
|
}
|
if(manifest.styles){
|
array.forEach(manifest.styles, function(_style){
|
var key = 'i18nLabels_style_' + _style.name;
|
_style.label = manifest[key] && (manifest[key][locale] ||
|
manifest[key].defaultLabel) ||
|
_style.label ||
|
_style.name;
|
});
|
}
|
};
|
|
ret.addI18NLabel = function(manifest){
|
var def = new Deferred();
|
if(manifest.i18nLabels){
|
def.resolve(manifest);
|
return def;
|
}
|
manifest.i18nLabels = {};
|
|
if(manifest.properties && manifest.properties.hasLocale === false){
|
def.resolve(manifest);
|
return def;
|
}
|
|
//theme or widget label
|
var nlsFile;
|
if(manifest.isRemote){
|
nlsFile = manifest.amdFolder + 'nls/strings.js';
|
}else{
|
nlsFile = manifest.amdFolder + 'nls/strings';
|
}
|
require(mo.getRequireConfig(), ['dojo/i18n!' + nlsFile],
|
function(localeStrings){
|
var localesStrings = {};
|
localesStrings[dojoConfig.locale] = localeStrings;
|
sharedUtils.addI18NLabelToManifest(manifest, null, localesStrings);
|
def.resolve(manifest);
|
});
|
|
return def;
|
};
|
return ret;
|
})();
|
|
mo.isNumberField = function(fieldType){
|
var numberFieldTypes = [
|
'esriFieldTypeOID',
|
'esriFieldTypeSmallInteger',
|
'esriFieldTypeInteger',
|
'esriFieldTypeSingle',
|
'esriFieldTypeDouble'
|
];
|
return numberFieldTypes.indexOf(fieldType) >= 0;
|
};
|
|
mo.getTime = function (date) {
|
var _off = date.getTimezoneOffset();
|
var _offTimes = _off < 0 ? "+" + (Math.abs(_off) / 60) : "-" + (_off / 60);
|
return date.getTime() + _offTimes * 60 * 60 * 1000;
|
};
|
|
|
mo._getValues = function(layerDefinition, fieldPopupInfo, fieldName, values){
|
var valueLabels = [];
|
var fieldInfo = mo.getFieldInfoByFieldName(layerDefinition.fields, fieldName);
|
var codedValueObj = null;//{value:label}
|
var isNumberField = mo.isNumberField(fieldInfo.type);
|
var isDateField = fieldInfo.type === 'esriFieldTypeDate' ? true : false;
|
if(fieldInfo){
|
if(isNumberField){
|
values = array.map(values, function(v){
|
var r = parseFloat(v);
|
if(isNaN(r)){
|
r = null;
|
}
|
return r;
|
});
|
}else if(isDateField){
|
values = array.map(values, lang.hitch(this, function(v) {
|
if(mo.isValidDate(v)){
|
//convert it to num when server returns a purely numeric string
|
// var numExp = new RegExp("^[0-9]*$");
|
// if(typeof v === 'string' && numExp.test(v)){
|
// v = parseInt(v, 10);
|
// }
|
// var r = mo.localizeDateByFieldInfo(v, fieldPopupInfo);
|
//display locate time to user
|
var dFormat = fieldPopupInfo ? fieldPopupInfo.format.dateFormat : '';
|
var newV = dFormat.indexOf('Time') < 0? v: mo.getTime(new Date(v));
|
var r = mo.localizeDateByFieldInfo(new Date(newV), fieldPopupInfo);
|
return r;
|
// return v;
|
}else{
|
return v;
|
// return null;
|
}
|
}));
|
}
|
//coded values
|
var domainValLabels = mo.getCodedValueListForCodedValueOrSubTypes(layerDefinition, fieldName);//[{value,label}]
|
if(domainValLabels !== null){
|
codedValueObj = {};
|
for(var key = 0; key < domainValLabels.length; key ++){
|
codedValueObj[domainValLabels[key].value] = domainValLabels[key].label;
|
}
|
}
|
}
|
valueLabels = array.map(values, function(value){
|
var label = null;
|
if(value === null || value === undefined){
|
label = '<Null>';
|
}else{
|
if(codedValueObj && codedValueObj.hasOwnProperty(value)){
|
label = codedValueObj[value];
|
}else{
|
if(isNumberField){
|
if(fieldPopupInfo){
|
label = mo.localizeNumberByFieldInfo(value, fieldPopupInfo);
|
}else{
|
label = mo.localizeNumber(value);
|
}
|
// }else if(isDateField){
|
// var dFormat = fieldPopupInfo ? fieldPopupInfo.format.dateFormat : '';
|
// var newV = dFormat.indexOf('Time') < 0? value: mo.getTime(new Date(value));
|
// label = mo.localizeDateByFieldInfo(new Date(newV), fieldPopupInfo);
|
}else{
|
label = value;
|
}
|
}
|
}
|
return {
|
value: value,
|
label: label
|
};
|
});
|
return valueLabels;
|
};
|
|
|
|
//get codedValue or types count, return number
|
mo.getCodedValuesOrTypesCount = function(fieldInfo, layerDefinition){
|
if(fieldInfo){
|
if(layerDefinition.typeIdField && layerDefinition.typeIdField.toUpperCase() === fieldInfo.name.toUpperCase() &&
|
layerDefinition.types){
|
return layerDefinition.types.length;
|
}else{
|
var codedValues = mo._getAllCodedValue(layerDefinition, fieldInfo);
|
return codedValues ? codedValues.length : 0;
|
}
|
}
|
return 0;
|
};
|
|
mo.isCodedValuesSupportFilter = function(layerDefinition, codedValueLength){
|
var version = parseFloat(layerDefinition.currentVersion);
|
return codedValueLength <= parseFloat(layerDefinition.maxRecordCount) && version > 10.1;
|
};
|
|
mo.combineRadioCheckBoxWithLabel = function(inputDom, labelDom){
|
var isValidInput = false;
|
if(inputDom && inputDom.nodeType === 1 && inputDom.tagName.toLowerCase() === 'input'){
|
var inputType = inputDom.getAttribute('type') || '';
|
inputType = inputType.toLowerCase();
|
if(inputType === 'radio' || inputType === 'checkbox'){
|
isValidInput = true;
|
}
|
}
|
var isValidLabel = false;
|
if(labelDom && labelDom.nodeType === 1 && labelDom.tagName.toLowerCase() === 'label'){
|
isValidLabel = true;
|
}
|
if(isValidInput && isValidLabel){
|
var inputId = inputDom.getAttribute('id');
|
if(!inputId){
|
inputId = "input_" + mo.getRandomString();
|
inputDom.setAttribute('id', inputId);
|
}
|
labelDom.setAttribute('for', inputId);
|
html.setStyle(labelDom, 'cursor', 'pointer');
|
}
|
};
|
|
//return handle array, the handles can be owned by widget
|
mo.groupRadios = function(radios, /*optional*/ listener){
|
var handles = [];
|
var name = "radiogroup_" + mo.getRandomString();
|
array.forEach(radios, function(radio){
|
radio.name = name;
|
if(listener){
|
var handle = on(radio, 'change', listener);
|
handles.push(handle);
|
}
|
});
|
return handles;
|
};
|
|
mo.combineGeometriesByGraphics = function(graphics){
|
var geometry = null;
|
if(graphics && graphics.length > 0){
|
var geometries = array.map(graphics, function(graphic){
|
return graphic.geometry;
|
});
|
geometry = mo.combineGeometries(geometries);
|
}
|
return geometry;
|
};
|
|
mo.isFeaturelayerUrlSupportQuery = function(featureLayerUrl, capabilities){
|
var isSupportQuery = false;
|
var isFeatureService = (/\/featureserver\//gi).test(featureLayerUrl);
|
var isMapService = (/\/mapserver\//gi).test(featureLayerUrl);
|
capabilities = capabilities || '';
|
capabilities = capabilities.toLowerCase();
|
if (isFeatureService) {
|
isSupportQuery = capabilities.indexOf('query') >= 0;
|
} else if (isMapService) {
|
isSupportQuery = capabilities.indexOf('data') >= 0;
|
}
|
return isSupportQuery;
|
};
|
|
mo.isImageServiceSupportQuery = function(capabilities){
|
capabilities = capabilities || '';
|
return capabilities.toLowerCase().indexOf('catalog') >= 0;
|
};
|
|
mo.isStringEndWith = function(s, endS){
|
return (s.lastIndexOf(endS) + endS.length === s.length);
|
};
|
|
/*
|
*Optional
|
*An object with the following properties:
|
*pattern (String, optional):
|
*override formatting pattern with this string. Default value is based on locale.
|
Overriding this property will defeat localization. Literal characters in patterns
|
are not supported.
|
*type (String, optional):
|
*choose a format type based on the locale from the following: decimal, scientific
|
(not yet supported), percent, currency. decimal by default.
|
*places (Number, optional):
|
*fixed number of decimal places to show. This overrides any information in the provided pattern.
|
*round (Number, optional):
|
*5 rounds to nearest .5; 0 rounds to nearest whole (default). -1 means do not round.
|
*locale (String, optional):
|
*override the locale used to determine formatting rules
|
*fractional (Boolean, optional):
|
*If false, show no decimal places, overriding places and pattern settings.
|
*/
|
mo.localizeNumber = function(num, options){
|
var decimalStr = num.toString().split('.')[1] || "",
|
decimalLen = decimalStr.length;
|
var _pattern = "";
|
var places = options && isFinite(options.places) && options.places;
|
if (places > 0 || decimalLen > 0) {
|
var patchStr = Array.prototype.join.call({
|
length: places > 0 ? (places + 1) : decimalLen
|
}, '0');
|
_pattern = "#,###,###,##0.0" + patchStr;
|
}else {
|
_pattern = "#,###,###,##0";
|
}
|
|
var _options = {
|
locale: config.locale,
|
pattern: _pattern
|
};
|
lang.mixin(_options, options || {});
|
|
try {
|
var fn = dojoNumber.format(num, _options);
|
return fn;
|
} catch (err) {
|
console.error(err);
|
return num.toLocaleString();
|
}
|
};
|
|
/*
|
*Optional
|
*An object with the following properties:
|
*pattern (String, optional):
|
*override formatting pattern with this string. Default value is based on locale.
|
Overriding this property will defeat localization. Literal characters in patterns
|
are not supported.
|
*type (String, optional):
|
*choose a format type based on the locale from the following: decimal,
|
scientific (not yet supported), percent, currency. decimal by default.
|
*locale (String, optional):
|
*override the locale used to determine formatting rules
|
*strict (Boolean, optional):
|
*strict parsing, false by default. Strict parsing requires input as produced by the
|
format() method. Non-strict is more permissive, e.g. flexible on white space, omitting
|
thousands separators
|
*fractional (Boolean|Array, optional):
|
*Whether to include the fractional portion, where the number of decimal places are
|
implied by pattern or explicit 'places' parameter. The value [true,false] makes the
|
fractional portion optional.
|
*/
|
mo.parseNumber = function(numStr, options){
|
var _options = {
|
locale: config.locale
|
};
|
lang.mixin(_options, options || {});
|
try {
|
var dn = dojoNumber.parse(numStr, _options);
|
return dn;
|
} catch(err) {
|
console.error(err);
|
return numStr;
|
}
|
};
|
|
/*
|
*Optional
|
*An object with the following properties:
|
*selector (String):
|
*choice of 'time','date' (default: date and time)
|
*formatLength (String):
|
*choice of long, short, medium or full (plus any custom additions). Defaults to 'short'
|
*datePattern (String):
|
*override pattern with this string
|
*timePattern (String):
|
*override pattern with this string
|
*am (String):
|
*override strings for am in times
|
*pm (String):
|
*override strings for pm in times
|
*locale (String):
|
*override the locale used to determine formatting rules
|
*fullYear (Boolean):
|
*(format only) use 4 digit years whenever 2 digit years are called for
|
*strict (Boolean):
|
*(parse only) strict parsing, off by default
|
*/
|
mo.localizeDate = function(d, options){
|
var _options = {
|
locale: config.locale,
|
fullYear: true
|
};
|
lang.mixin(_options, options || {});
|
|
if(config.locale === 'ar' && _options.formatLength !== 'long' && _options.formatLength !== 'full') {
|
_options.formatLength = 'long';
|
}
|
|
try {
|
var ld = dateLocale.format(d, _options);
|
return ld;
|
} catch(err) {
|
console.error(err);
|
if (_options.selector === 'date') {
|
return d.toLocaleDateString();
|
} else if (_options.selector === 'time') {
|
return d.toLocaleTimeString();
|
} else {
|
return d.toLocaleString();
|
}
|
}
|
};
|
|
/*
|
*n: Number
|
*fieldInfo: https://developers.arcgis.com/javascript/jshelp/intro_popuptemplate.html
|
*/
|
mo.localizeNumberByFieldInfo = function(n, fieldInfo) {
|
var fn = null;
|
var p = lang.exists('format.places', fieldInfo) && fieldInfo.format.places;
|
fn = mo.localizeNumber(n, {
|
places: p
|
});
|
|
if (lang.exists('format.digitSeparator', fieldInfo) && !fieldInfo.format.digitSeparator) {
|
return fn.toString().replace(new RegExp('\\' + nlsBundle.group, "g"), "");
|
} else {
|
return fn;
|
}
|
};
|
|
mo.fieldFormatter = {
|
getFormattedUrl: function(str) {
|
if (str && typeof str === "string") {
|
var s = str.indexOf('http:');
|
if (s === -1) {
|
s = str.indexOf('https:');
|
}
|
if (s > -1) {
|
if (str.indexOf('href=') === -1) {
|
var e = str.indexOf(' ', s);
|
if (e === -1) {
|
e = str.length;
|
}
|
var nl = str.indexOf('\r\n', s) > -1 ? str.indexOf('\r\n', s) :
|
str.indexOf('\n', s) > -1 ? str.indexOf('\n', s) : e;
|
e = nl < e ? nl : e;
|
var link = str.substring(s, e);
|
str = str.substring(0, s) +
|
'<A href="' + link + '" target="_blank">' + link + '</A>' +
|
str.substring(e, str.length);
|
}
|
}
|
}
|
|
if(typeof str === undefined || str === null){
|
return '';
|
}
|
|
return str;
|
},
|
|
getFormattedNumber: function(num, format) {
|
if (typeof num === 'number') {
|
var decimalStr = num.toString().split('.')[1] || "",
|
decimalLen = decimalStr.length;
|
num = mo.localizeNumberByFieldInfo(num, {
|
format: {
|
places: (format && typeof format.places === 'number') ?
|
parseInt(format.places, 10) : decimalLen,
|
digitSeparator: format && format.digitSeparator
|
}
|
});
|
return '<span class="jimu-numeric-value">' + (num || "") + '</span>';
|
}
|
return num;
|
},
|
|
getFormattedDate: function(timeNumber, format) {
|
if (typeof timeNumber === 'number' || timeNumber instanceof Date) {
|
timeNumber = mo.localizeDateByFieldInfo(timeNumber, {
|
'format': format
|
});
|
}
|
return timeNumber || "";
|
},
|
|
|
getTypeName: function(value, types) {
|
var len = types.length;
|
for (var i = 0; i < len; i++) {
|
if (value === types[i].id) {
|
return types[i].name;
|
}
|
}
|
return value;
|
}
|
};
|
|
mo.addRelativePathInCss = addRelativePathInCss;
|
|
|
|
mo.processUrlInWidgetConfig = function(url, widgetFolderUrl){
|
if(!url){
|
return;
|
}
|
if(url.startWith('data:') || url.startWith('http') || url.startWith('/')){
|
return url;
|
}else if(url.startWith('${appPath}')){
|
return url.replace('${appPath}', window.appInfo.appPath);
|
}else{
|
return widgetFolderUrl + url;
|
}
|
};
|
|
mo.processUrlInAppConfig = function(url){
|
if(!url){
|
return;
|
}
|
if(url.startWith('data:') || url.startWith('http') || url.startWith('/')){
|
return url;
|
}else{
|
return window.appInfo.appPath + url;
|
}
|
};
|
|
mo.getDefaultWebMapThumbnail = function(){
|
return require.toUrl('jimu/images/webmap.png');
|
};
|
|
mo.invertColor = function(hexTripletColor) {
|
var color = hexTripletColor;
|
color = color.substring(1); // remove #
|
if (color.length === 3) {
|
color = color.slice(0, 1) +
|
color.slice(0, 1) +
|
color.slice(1, 1) +
|
color.slice(1, 1) +
|
color.slice(2, 1) +
|
color.slice(2, 1);
|
}
|
color = parseInt(color, 16); // convert to integer
|
if(color > 7829367) {
|
return "#000000";
|
} else {
|
return "#ffffff";
|
}
|
};
|
|
mo.isLightColor = function(colorHex){
|
var color = colorHex;
|
color = color.substring(1); // remove #
|
if (color.length === 3) {
|
color = color.slice(0, 1) +
|
color.slice(0, 1) +
|
color.slice(1, 1) +
|
color.slice(1, 1) +
|
color.slice(2, 1) +
|
color.slice(2, 1);
|
}
|
color = parseInt(color, 16); // convert to integer
|
if(color > 7829367) {
|
return true;
|
} else {
|
return false;
|
}
|
};
|
|
/*
|
Mixin config2 to config1, return the mixed object, but do not modify config1.
|
What to mixin:
|
replace widget's position, group's panel position, map's position.
|
*/
|
mo.mixinAppConfigPosition = function(config1, config2){
|
var mixinConfig = lang.clone(config1);
|
if(!config2){
|
return mixinConfig;
|
}
|
config2 = lang.clone(config2);
|
var os1 = mixinConfig.widgetOnScreen;
|
var os2 = config2.widgetOnScreen;
|
if(os2 && os2.widgets){
|
if(Object.prototype.toString.call(os2.widgets) ===
|
'[object Object]'){
|
|
array.forEach(os1.widgets, function(widget1, i){
|
var k;
|
if(widget1.uri){
|
k = widget1.uri;
|
}else{
|
k = 'ph_' + i;
|
}
|
|
if(os2.widgets[k] && os2.widgets[k].position){
|
if(!os2.widgets[k].position.relativeTo){
|
os2.widgets[k].position.relativeTo = 'map';
|
}
|
widget1.position = os2.widgets[k].position;
|
}
|
}, this);
|
}else{
|
array.forEach(os2.widgets, function(widget2, i){
|
if(widget2.position && !widget2.position.relativeTo){
|
widget2.position.relativeTo = 'map';
|
}
|
if(os1.widgets[i] && widget2.position){
|
os1.widgets[i].position = widget2.position;
|
}
|
});
|
}
|
}
|
|
if(os2 && os2.groups){
|
if(Object.prototype.toString.call(os2.groups) ===
|
'[object Object]'){
|
|
array.forEach(os1.groups, function(group1, i){
|
var k;
|
if(group1.label){
|
k = group1.label;
|
}else{
|
k = 'g_' + i;
|
}
|
|
if(os2.groups[k] && os2.groups[k].panel && os2.groups[k].panel.position){
|
if(!os2.groups[k].panel.position.relativeTo){
|
os2.groups[k].panel.position.relativeTo = 'map';
|
}
|
group1.panel.position = os2.groups[k].panel.position;
|
}
|
}, this);
|
}else{
|
var managerName;
|
if(config1.layoutDefinition){
|
managerName = config1.layoutDefinition.manager;
|
}else{
|
managerName = 'jimu/layoutManagers/AbsolutePositionLayoutManager';
|
}
|
|
if(managerName === 'jimu/layoutManagers/AbsolutePositionLayoutManager'){
|
array.forEach(os2.groups, function(group2, i){
|
if(group2.panel && group2.panel.position &&
|
!group2.panel.position.relativeTo){
|
group2.panel.position.relativeTo = 'map';
|
}
|
if(os1.groups[i] && group2.panel && group2.panel.position){
|
os1.groups[i].panel.position = group2.panel.position;
|
}
|
});
|
}else if(managerName === 'jimu/layoutManagers/GridLayoutManager'){
|
os1.groups = handleGridLayoutOnScreenGroupChange(os1.groups, os2.groups.map(function(g){
|
return g.id;
|
}));
|
}
|
}
|
}
|
|
if(config2.map && config2.map.position){
|
if(mixinConfig.map){
|
mixinConfig.map.position = config2.map.position;
|
}else{
|
mixinConfig.map = {position: config2.map.position};
|
}
|
}
|
|
if(config2.widgetPool && config2.widgetPool.panel){
|
if(config2.widgetPool.panel.position && !config2.widgetPool.panel.position.relativeTo){
|
config2.widgetPool.panel.position.relativeTo = 'map';
|
}
|
mixinConfig.widgetPool.panel.position = config2.widgetPool.panel.position;
|
}
|
|
//mobileLayout is used to override it's main config, so replace totally
|
if(config2.mobileLayout){
|
mixinConfig.mobileLayout = config2.mobileLayout;
|
}
|
return mixinConfig;
|
};
|
|
function handleGridLayoutOnScreenGroupChange(oldGroups, newGroupIds){
|
var oldGroupIds = oldGroups.map(function(g){
|
return g.id;
|
});
|
|
array.forEach(newGroupIds, function(gId){
|
if(oldGroupIds.indexOf(gId) < 0){// new add group
|
oldGroups.push({
|
id: gId,
|
widgets: []
|
});
|
}
|
}, this);
|
|
var removedGroups = [];
|
oldGroups = array.filter(oldGroups, function(g){
|
if(newGroupIds.indexOf(g.id) < 0){// group is removed
|
removedGroups.push(g);
|
return false;
|
}else{
|
return true;
|
}
|
}, this);
|
|
if(oldGroups.length === 0){
|
return [];
|
}
|
//put widgets in removed groups into the last group
|
var toAddGroup = oldGroups[oldGroups.length - 1];
|
array.forEach(removedGroups, function(removedGroup){
|
toAddGroup.widgets = toAddGroup.widgets.concat(removedGroup.widgets);
|
}, this);
|
|
oldGroups = oldGroups.sort(function(g1, g2){
|
return newGroupIds.indexOf(g1.id) - newGroupIds.indexOf(g2.id);
|
});
|
|
return oldGroups;
|
}
|
|
mo.handleGridLayoutOnScreenGroupChange = handleGridLayoutOnScreenGroupChange;
|
|
/**********************************
|
* About template
|
**********************************/
|
|
// reset some field of config by template config.
|
function getOrSetConfigByTemplate(config, key, value) {
|
//config: Object
|
// the destination config object
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--
|
//value: String
|
// value is undefined: get the value correspond to the key and save to 'value' param.
|
// value is not undefined: set the value of key.
|
var keyArray = convertToKeyArray(key);
|
|
var obj = config;
|
for (var i = 1; i < keyArray.length - 1; i++) {
|
obj = getSubObj(obj, keyArray[i]);
|
if (!obj) {
|
return;
|
}
|
}
|
|
if (keyArray[keyArray.length - 1].deleteFlag) {
|
if (value === true) {
|
if (lang.isArray(obj[keyArray[keyArray.length - 1].key])) {
|
delete obj[keyArray[keyArray.length - 1].key][keyArray[keyArray.length - 1].index];
|
} else {
|
delete obj[keyArray[keyArray.length - 1].key];
|
}
|
}
|
} else {
|
if (lang.isArray(obj[keyArray[keyArray.length - 1].key])) {
|
if(value === undefined) {
|
// get value to valueParam
|
return obj[keyArray[keyArray.length - 1].key][keyArray[keyArray.length - 1].index];
|
} else {
|
// set value to config
|
obj[keyArray[keyArray.length - 1].key][keyArray[keyArray.length - 1].index] = value;
|
}
|
} else {
|
if(value === undefined) {
|
return obj[keyArray[keyArray.length - 1].key];
|
} else {
|
obj[keyArray[keyArray.length - 1].key] = value;
|
}
|
}
|
}
|
|
function getSubObj(obj, keyInfo) {
|
if (lang.isArray(obj[keyInfo.key])) {
|
return obj[keyInfo.key][keyInfo.index];
|
} else {
|
return obj[keyInfo.key];
|
}
|
}
|
|
function convertToKeyArray(str) {
|
var arrayKey = [];
|
str.split('_').forEach(function(str) {
|
var deleteFlag = false;
|
var pos;
|
if (str.slice(str.length - 2) === "--") {//Builder will not export this kind of key.
|
deleteFlag = true;
|
str = str.slice(0, str.length - 2);
|
}
|
pos = str.search(/\[[0-9]+\]/);
|
if (pos === -1) {
|
(pos = str.length);
|
}
|
arrayKey.push({
|
"key": str.slice(0, pos),
|
"index": Number(str.slice(pos + 1, -1)),
|
"deleteFlag": deleteFlag
|
});
|
});
|
return arrayKey;
|
}
|
}
|
|
|
|
// reset some field of config by template config.
|
function getOrSetConfigByTemplateWithId(config, key, value) {
|
//config: Object
|
// the destination config object
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--;
|
// howover, if the key is a wiget element, the key like this: app_p1_p2[widgetId];
|
// does not set anything if the key is not valid.
|
//value: String
|
// value is undefined: get the value correspond to the key and return value.
|
// value is not undefined: set the value of key.
|
|
|
|
// section means widget or group
|
var groupSearchStr = "groups\\[.+\\]";
|
var widgetSearchStr = "widgets\\[.+\\]";
|
var sectionConfig = config;
|
|
key = key.replace(/\//g, '_');
|
var sectionKey = key;
|
|
// Do not merge fields that in the widget config,
|
// beacuse widgetConfig has not been loaded before open
|
// widget if the widget has not been edited yet.
|
// Merge it when first open widget(In Widgetmanager.js).
|
//
|
// if(key.search("widgets\\[.+\\]_config") >= 0) {
|
// return;
|
// }
|
// does not neet to "return null", regarde widget_config_key as invalid key.
|
|
// handle groups
|
var groupInfo = getSectionObject(groupSearchStr);
|
if (groupInfo.state === "deleted") {
|
return;
|
} else if (groupInfo.state === "isSection") {
|
sectionConfig = groupInfo.object;
|
sectionKey = groupInfo.key;
|
}
|
|
// handle widgets
|
var widgetInfo = getSectionObject(widgetSearchStr);
|
if (widgetInfo.state === "delete") {
|
return;
|
} else if (widgetInfo.state === "isSection") {
|
sectionConfig = widgetInfo.object;
|
sectionKey = widgetInfo.key;
|
}
|
|
return getOrSetConfigByTemplate(sectionConfig, sectionKey, value);
|
|
function getSectionObject(sectionSearchStr) {
|
var sectionRange = mo.template.getSearchRange(key, sectionSearchStr, "]");
|
var sectionStr = key.slice(sectionRange.firstPos, sectionRange.lastPos);// section[abcd]
|
// It's section node.
|
if (sectionRange.firstPos !== -1) {
|
var sectionId = key.slice(sectionRange.firstPos + sectionStr.indexOf('[') + 1,
|
sectionRange.lastPos - 1);
|
var subKey = key.slice(sectionRange.lastPos + 1);
|
var sectionObject = mo.getConfigElementById(config, sectionId);
|
if (sectionObject) {
|
return {
|
object: sectionObject,
|
key: "section_" + subKey,
|
state: "isSection"
|
};
|
} else {
|
// means the section had been deleted.
|
return {
|
state: "deleted"
|
};
|
}
|
} else {
|
//It is not a section node.
|
return {
|
state: "isNotSection"
|
};
|
}
|
}
|
}
|
|
|
mo.template = {
|
groupIdentification: "groups\\[.+\\]",
|
|
widgetIdentification: "widgets\\[.+\\]",
|
|
getSearchRange: function(srcStr, searchStr, lastString) {
|
// return value:{
|
// firstPos:
|
// lastPos:
|
//}
|
// if firstPos === -1: does not find searchStr from srcStr
|
var posResult = -1, regExp, pos1, pos2, tempStr;
|
regExp = new RegExp(searchStr);
|
pos1 = srcStr.search(regExp);
|
if (pos1 >= 0 ) {
|
tempStr = srcStr.slice(pos1, srcStr.length);
|
pos2 = tempStr.indexOf(lastString);
|
posResult = pos1 + pos2 + lastString.length;
|
}
|
return {
|
firstPos: pos1,
|
lastPos: posResult
|
};
|
},
|
|
setConfigValue: function(config, key, value) {
|
//config: Object
|
// the destination config object
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--
|
getOrSetConfigByTemplate(config, key, value);
|
},
|
|
getConfigValue: function(config, key) {
|
//config: Object
|
// the destination config object
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--
|
// return value:
|
// return value of key of config.
|
// return 'undefined' if the key is invalid.
|
return getOrSetConfigByTemplate(config, key);
|
},
|
|
setConfigValueWithId: function(config, key, value) {
|
//config: Object
|
// the destination config object
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--
|
// howover, if the key is a wiget element, the key like this: app_p1_p2[widgetId]
|
getOrSetConfigByTemplateWithId(config, key, value);
|
},
|
|
getConfigValueWithId: function(config, key) {
|
//config: Object
|
// the destination config object
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--
|
// howover, if the key is a wiget element, the key like this: app_p1_p2[widgetId]
|
// return value:
|
// return value of key of config.
|
// return 'undefined' if the key is invalid.
|
return getOrSetConfigByTemplateWithId(config, key);
|
},
|
|
getKeyInfo: function(key){
|
var widgetId = this.getWidgetIdByKey(key);
|
if(widgetId !== null){
|
return {
|
type: 'widget',
|
id: widgetId
|
};
|
}else{
|
var groupId = this.getGroupIdByKey(key);
|
if(groupId !== null){
|
return {
|
type: 'group',
|
id: groupId
|
};
|
}else{
|
return {
|
type: 'unknow', //TODO
|
id: null
|
};
|
}
|
}
|
},
|
|
getWidgetIdByKey: function(key) {
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--
|
// id: if its a widget.
|
// null: it is not a widget
|
var widgetId;
|
var widgetRange = mo.template.getSearchRange(key,
|
mo.template.widgetIdentification, "]");
|
if(widgetRange.firstPos === -1) {
|
widgetId = null;
|
} else {
|
// widget[widget_id]
|
var widgetStr = key.slice(widgetRange.firstPos, widgetRange.lastPos);
|
widgetId = key.slice(widgetRange.firstPos + widgetStr.indexOf('[') + 1,
|
widgetRange.lastPos - 1);
|
}
|
return widgetId;
|
|
},
|
|
getGroupIdByKey: function(key) {
|
//key: String
|
// the key value relative to the config object, like this: app_p1_p2[0], app_p1_p2[1]--
|
//return value:
|
// id: if its a group.
|
// null: it is not a group
|
|
//TODO widget in group should be widget
|
var groupId;
|
var groupRange = mo.template.getSearchRange(key,
|
mo.template.groupIdentification, "]");
|
if(groupRange.firstPos === -1) {
|
groupId = null;
|
} else {
|
// group[group_id]
|
var groupStr = key.slice(groupRange.firstPos, groupRange.lastPos);
|
groupId = key.slice(groupRange.firstPos + groupStr.indexOf('[') + 1,
|
groupRange.lastPos - 1);
|
}
|
return groupId;
|
},
|
|
|
getConfigedWidgetsByTemplateConfig: function(templateConfig) {
|
var widgetIds = [];
|
var widgetConfigIdentification = mo.template.widgetIdentification + "_config";
|
var widgetConfigRange;
|
|
array.forEach(templateConfig.configurationSettings, function(category) {
|
array.forEach(category.fields, function(field) {
|
if(field.fieldName) {
|
widgetConfigRange = mo.template.getSearchRange(field.fieldName,
|
widgetConfigIdentification, "]");
|
if(widgetConfigRange.firstPos >= 0) {
|
// the widget has config property.
|
pushWithoutRepeat(widgetIds, mo.template.getWidgetIdByKey(field.fieldName));
|
}
|
}
|
}, this);
|
}, this);
|
|
return widgetIds;
|
|
function pushWithoutRepeat(desArray, value) {
|
if(desArray.indexOf(value) === -1) {
|
desArray.push(value);
|
}
|
}
|
},
|
|
// getConfigedWidgetsByTemplateAppConfig: function(templateAppConfig) {
|
// // return value.
|
// // widget IDs arrary that contain all widgets which have been configed.
|
|
// var widgetIds = [];
|
// var widgetConfigIdentification = mo.template.widgetIdentification + "_config";
|
// var widgetConfigRange;
|
|
// for (var key in templateAppConfig.values) {
|
// if(templateAppConfig.values.hasOwnProperty(key) &&
|
// (typeof templateAppConfig.values[key] !== 'function')) {
|
// widgetConfigRange = mo.template.getSearchRange(key,
|
// widgetConfigIdentification, "]");
|
// if(widgetConfigRange.firstPos >= 0) {
|
// // the widget has config property.
|
// pushWithoutRepeat(widgetIds, mo.template.getWidgetIdByKey(key));
|
// }
|
// }
|
// }
|
|
// return widgetIds;
|
|
// function pushWithoutRepeat(desArray, value) {
|
// if(desArray.indexOf(value) === -1) {
|
// desArray.push(value);
|
// }
|
// }
|
// },
|
|
mergeTemplateAppConfigToAppConfig: function(appConfig, templateAppConfig, webmapInfo){
|
//webmapInfo != undefined means templateAppConfig is from AGOL,
|
//use this webmap info in appConfig
|
var i;
|
var screenSectionConfig = appConfig.widgetOnScreen;
|
var portalUrl = appConfig.portalUrl;
|
|
//Both WAB template app and AGOL template app have webmap value
|
if(templateAppConfig.values.webmap){
|
//app created from mycontent has no webmap
|
appConfig.map.itemId = templateAppConfig.values.webmap;
|
}
|
|
if(webmapInfo){
|
// use default mapOptions of current webmap.
|
if(appConfig.map.mapOptions){
|
mo.deleteMapOptions(appConfig.map.mapOptions);
|
}
|
appConfig.map.portalUrl = portalUrl;
|
|
if (!templateAppConfig.values.app_title) {
|
templateAppConfig.values.app_title = webmapInfo.title;
|
}
|
if (!templateAppConfig.values.app_subtitle) {
|
templateAppConfig.values.app_subtitle = webmapInfo.snippet;
|
}
|
}
|
|
//merge values
|
for (var key in templateAppConfig.values) {
|
if (key !== "webmap") {
|
mo.template.setConfigValueWithId(appConfig, key, templateAppConfig.values[key]);
|
}
|
}
|
|
reorder();
|
|
function reorder() {
|
//reorderWidgets
|
appConfig.widgetPool.widgets = reorderWidgets(appConfig.widgetPool.widgets);
|
screenSectionConfig.widgets = reorderWidgets(screenSectionConfig.widgets);
|
if (appConfig.widgetPool.groups) {
|
for (i = 0; i < appConfig.widgetPool.groups.length; i++) {
|
appConfig.widgetPool.groups[i].widgets =
|
reorderWidgets(appConfig.widgetPool.groups[i].widgets);
|
}
|
}
|
if (screenSectionConfig.groups) {
|
for (i = 0; i < screenSectionConfig.groups.length; i++) {
|
screenSectionConfig.groups[i].widgets =
|
reorderWidgets(screenSectionConfig.groups[i].widgets);
|
}
|
}
|
}
|
|
function reorderWidgets(widgetArray) {
|
var tempWidgets = [];
|
array.forEach(widgetArray, function(widget) {
|
if (widget) {
|
tempWidgets.push(widget);
|
}
|
}, this);
|
return tempWidgets;
|
}
|
|
return appConfig;
|
}
|
};
|
|
mo.sanitizeHTML = function(snippet){
|
/* global html_sanitize */
|
|
//https://code.google.com/p/google-caja/wiki/JsHtmlSanitizer
|
return html_sanitize(snippet, function(url){
|
return url;
|
}, function(v){
|
return v;
|
});
|
};
|
|
mo.stripHTML = function (str){
|
if (!str) {
|
return str;
|
}
|
if (str.indexOf("<") > -1 && str.indexOf(">") > -1) {
|
// this gets pretty slow if the string is long and has a < and no >
|
var matchTag = /<(?:.|\s)*?>/g;
|
return str.replace(matchTag, "");
|
} else {
|
return str;
|
}
|
};
|
|
mo.encodeHTML = function (source) {
|
return String(source)
|
.replace(/&/g, '&')
|
.replace(/</g, '<')
|
.replace(/>/g, '>')
|
.replace(/"/g, '"')
|
.replace(/'/g, ''');
|
};
|
|
mo.removeSuffixSlashes = function(url){
|
return url.replace(/\/*$/g, '');
|
};
|
|
mo.getBestDisplayAttributes = function(attributes, fieldInfos) {
|
var displayAttributes = {};
|
var displayValue = null;
|
for (var fieldName in attributes) {
|
displayValue = mo.getBestDisplayValue(fieldName, attributes, fieldInfos);
|
displayAttributes[fieldName] = displayValue;
|
}
|
return displayAttributes;
|
};
|
|
mo.getBestDisplayValue = function(fieldName, attributes, fieldInfoOrFieldInfos) {
|
var displayValue = "";
|
var fieldInfo = null;
|
if (lang.isArrayLike(fieldInfoOrFieldInfos)) {
|
var fieldInfos = fieldInfoOrFieldInfos;
|
fieldInfo = mo.getFieldInfoByFieldName(fieldInfos, fieldName);
|
} else if (typeof fieldInfoOrFieldInfos === 'object') {
|
if(fieldInfoOrFieldInfos.name === fieldName){
|
fieldInfo = fieldInfoOrFieldInfos;
|
}
|
}
|
|
if (fieldInfo) {
|
displayValue = attributes[fieldName];
|
if (fieldInfo.type === 'esriFieldTypeDate') {
|
if (displayValue) {
|
var date = new Date(parseInt(displayValue, 10));
|
displayValue = mo._tryLocaleDate(date);
|
}
|
} else {
|
if (typeof displayValue === 'number') {
|
if (fieldInfo.domain && fieldInfo.domain.type === 'codedValue') {
|
array.some(fieldInfo.domain.codedValues, function(codedValue) {
|
if (codedValue.code === displayValue) {
|
displayValue = codedValue.name;
|
return true;
|
}
|
});
|
} else {
|
displayValue = mo._tryLocaleNumber(displayValue);
|
}
|
}
|
}
|
}
|
|
if (displayValue === null || displayValue === undefined) {
|
displayValue = "";
|
}
|
|
return displayValue;
|
};
|
|
//only get codedValues in field domain
|
//return [{value,label}], return null means not coded value field
|
mo._getCodedValues = function(fieldInfo) {
|
var codedValues = null;
|
var domain = fieldInfo.domain;
|
if (domain && domain.type === 'codedValue') {
|
if (domain.codedValues && domain.codedValues.length > 0) {
|
codedValues = domain.codedValues;
|
//{code,name}=>{value,label}
|
//code is value and name is description
|
codedValues = array.map(codedValues, lang.hitch(this, function(item) {
|
return {
|
value: item.code,
|
label: item.name
|
};
|
}));
|
}
|
}
|
return codedValues;
|
};
|
|
//get subtypes list in subtypes property
|
//return [{value,label}], return null means no subtypes
|
mo._getSubTypes = function(layerDefinition) {
|
var subTypes = null;
|
if (layerDefinition.subtypeField && layerDefinition.subtypes && layerDefinition.subtypes.length > 0) {
|
//{id,name}=>{value,label}
|
subTypes = array.map(layerDefinition.subtypes, lang.hitch(this, function(item) {
|
return {
|
value: item.id,
|
label: item.name
|
};
|
}));
|
}
|
return subTypes;
|
};
|
|
//get renders list in types property
|
//return [{value,label}], return null means no render types
|
mo._getRenderTypes = function(layerDefinition) {
|
var subTypes = null;
|
if (layerDefinition.typeIdField && layerDefinition.types && layerDefinition.types.length > 0) {
|
//{id,name}=>{value,label}
|
subTypes = array.map(layerDefinition.types, lang.hitch(this, function(item) {
|
return {
|
value: item.id,
|
label: item.name
|
};
|
}));
|
//update labels by render
|
// subTypes = mo._updateCodedValueListFromRender(layerDefinition, subTypes);
|
}
|
return subTypes;
|
};
|
|
//return [{value,label}], maybe return null
|
mo._getCodedValueOrSubtypes = function(layerDefinition, fieldName, /*optional*/ typeIdFieldValue){
|
//http://servicesdev1.arcgis.com/5uh3wwYLNzBuU0Eu/arcgis/rest/services/CarsandLivingThings/FeatureServer/0?f=pjson
|
var fieldInfo = mo.getFieldInfoByFieldName(layerDefinition.fields, fieldName);
|
var codedValues;
|
//query codedvalue from types-domain
|
if(typeIdFieldValue !== undefined && typeIdFieldValue !== null){ //it can be 0(number)
|
codedValues = mo._getCodedValueBySubTypeId(layerDefinition, fieldName, typeIdFieldValue, /*optional*/fieldInfo);
|
}else{
|
codedValues = mo._getAllCodedValue(layerDefinition, fieldInfo);
|
}
|
return codedValues;
|
|
/*
|
//http://servicesdev1.arcgis.com/5uh3wwYLNzBuU0Eu/arcgis/rest/services/CarsandLivingThings/FeatureServer/0?f=pjson
|
var fieldInfo = mo.getFieldInfoByFieldName(layerDefinition.fields, fieldName);
|
//check normal coded values
|
var codedValues = mo._getCodedValues(fieldInfo);//[{value,label}]
|
|
if(!codedValues || codedValues.length === 0){
|
if (layerDefinition.typeIdField) {
|
var subTypes = mo._getRenderTypes(layerDefinition);//[{value,label}]
|
|
//typeIdField maybe doesn't match the real subtype field exactly
|
if (layerDefinition.typeIdField.toUpperCase() === fieldName.toUpperCase()) {
|
//check subtypes
|
codedValues = subTypes;
|
}else{
|
//check codedvalues related to subtype
|
if(typeIdFieldValue !== undefined && typeIdFieldValue !== null){
|
if(layerDefinition.types && layerDefinition.types.length > 0){
|
array.some(layerDefinition.types, lang.hitch(this, function(item){
|
if(item.name === typeIdFieldValue){
|
if(item.type === 'codedValue'){
|
codedValues = item.codedValues;
|
}
|
return true;
|
}else{
|
return false;
|
}
|
}));
|
}
|
}
|
}
|
}
|
}
|
return codedValues;
|
*/
|
};
|
|
//return {isCodedValueOrSubtype,displayValue}
|
mo._getDisplayValueForCodedValueOrSubtype = function(layerDefinition, fieldName, fieldValue,
|
/*optional*/ typeIdFieldValue){
|
var result = {
|
isCodedValueOrSubtype: false,
|
displayValue: fieldValue + ''//convert it to a string if it's a numberical value.
|
};
|
|
//[{value,label}]
|
var codedValues = mo._getCodedValueOrSubtypes(layerDefinition, fieldName, typeIdFieldValue);
|
|
if(codedValues && codedValues.length > 0){
|
array.some(codedValues, lang.hitch(this, function(item){
|
if(item.value === fieldValue){
|
result = {
|
isCodedValueOrSubtype: true,
|
displayValue: item.label
|
};
|
return true;
|
}else{
|
return false;
|
}
|
}));
|
}
|
return result;
|
};
|
|
|
// Delete subtype related properties for 6.3 ---temp function
|
// subtypeField(string fieldName), subtypes(array)
|
// These two properties are used to verify if a layer has subtype field,
|
// we can get subtype field name by subtypeField property, get subtype configuration by subtypes property.
|
// But right now, this is not yet supported with online or enterprise hosted feature services.
|
// Only enterprise gdb based feature survices have it(10.5 added).
|
// It's hard to prepare this condition to test it now, so leave it to next release.
|
mo._deleteSubtypePropertiesTemp = function(layerDefinition){
|
delete layerDefinition.subtypeField;
|
delete layerDefinition.subtypes;
|
};
|
|
//get display label by code from a feature attributes
|
//attributes is feature's attributes
|
//return {isCodedValueOrSubtype,displayValue}
|
mo.getDisplayValueForCodedValueOrSubtype = function(layerDefinition, fieldName, attributes){
|
mo._deleteSubtypePropertiesTemp(layerDefinition);
|
var fieldValue = attributes[fieldName];
|
var typeIdFieldValue;
|
var typeIdField = layerDefinition.typeIdField;
|
if(attributes.hasOwnProperty(typeIdField)){
|
typeIdFieldValue = attributes[typeIdField];
|
}
|
|
var subtypeField = layerDefinition.subtypeField;
|
if(subtypeField && layerDefinition.subtypes && layerDefinition.subtypes.length > 0){
|
if(attributes.hasOwnProperty(subtypeField)){
|
typeIdFieldValue = attributes[subtypeField];
|
}
|
}
|
|
var result = mo._getDisplayValueForCodedValueOrSubtype(layerDefinition, fieldName, fieldValue, typeIdFieldValue);
|
if(layerDefinition.typeIdField === fieldName){
|
var codedvalue = [{value: attributes[fieldName], label: result.displayValue}];
|
result.displayValue = mo._updateCodedValueListFromRender(layerDefinition, codedvalue)[0].label;
|
}
|
return result;
|
|
};
|
|
//get fieldValue's displayValue from a codedValues array
|
//return {isCodedValueOrSubtype,displayValue}
|
mo._getDisplayValueFromCodedValues = function(fieldValue, codedValues){
|
var result = {
|
isCodedValueOrSubtype: false,
|
displayValue: fieldValue + '' //convert it to a string if it's a numberical value.
|
};
|
if(codedValues && codedValues.length > 0){
|
array.some(codedValues, lang.hitch(this, function(item){
|
if(item.value === fieldValue){
|
result = {
|
isCodedValueOrSubtype: true,
|
displayValue: item.label
|
};
|
return true;
|
}else{
|
return false;
|
}
|
}));
|
}
|
result.value = fieldValue;
|
return result;
|
};
|
|
//get display label list by code from a feature attributes
|
//attributesList is a array of feature's attributes
|
//return [{isCodedValueOrSubtype,value,label}]
|
mo.getDisplayValueForCodedValueOrSubtypeBatch = function(layerDefinition, fieldName, attributesList){
|
mo._deleteSubtypePropertiesTemp(layerDefinition);
|
var codedValueHash = {};
|
var typeIdField = layerDefinition.typeIdField;
|
var subtypeField = layerDefinition.subtypeField;
|
var fieldInfo = mo.getFieldInfoByFieldName(layerDefinition.fields, fieldName);
|
if(subtypeField && layerDefinition.subtypes && layerDefinition.subtypes.length > 0){
|
codedValueHash.subType = mo._getSubTypes(layerDefinition);//subtype list
|
typeIdField = subtypeField;
|
codedValueHash.all = mo._getAllCodedValueNew(layerDefinition, fieldInfo); //all codedvalue list
|
}else{
|
codedValueHash.all = mo._getAllCodedValue(layerDefinition, fieldInfo); //all codedvalue list
|
codedValueHash.subType = mo._getRenderTypes(layerDefinition);//subtype list
|
}
|
if(codedValueHash.subType && codedValueHash.subType.length > 0){
|
var subTypeValues = codedValueHash.subType;
|
for(var index in subTypeValues){
|
var stValue = subTypeValues[index].value;
|
//codedvalue list by subtypeid
|
// codedValueHash[stValue] = mo._getCodedValueBySubTypeId(layerDefinition, fieldName, stValue, fieldInfo);
|
var list = mo._getCodedValueBySubTypeId(layerDefinition, fieldName, stValue, fieldInfo);
|
codedValueHash[stValue] = layerDefinition.typeIdField === fieldName ?
|
mo._updateCodedValueListFromRender(layerDefinition, list): list;
|
}
|
}
|
|
//get labels by render
|
if(layerDefinition.typeIdField === fieldName){
|
codedValueHash.subType = mo._updateCodedValueListFromRender(layerDefinition, codedValueHash.subType);
|
codedValueHash.all = mo._updateCodedValueListFromRender(layerDefinition, codedValueHash.all);
|
}
|
|
var codedValueList = [];
|
var resultList = [];
|
for(var key in attributesList){
|
var attrs = attributesList[key];
|
var fieldValue = attrs[fieldName];
|
var typeIdFieldValue;
|
if(typeIdField === fieldName){
|
codedValueList = codedValueHash.subType;
|
}else{
|
if(attrs.hasOwnProperty(typeIdField)){
|
typeIdFieldValue = attrs[typeIdField];
|
codedValueList = codedValueHash[typeIdFieldValue];
|
if(!codedValueList){//pass a error subtype, could get null from hash.
|
codedValueList = mo._getCodedValues(fieldInfo); //return field domain
|
if(layerDefinition.typeIdField === fieldName){
|
codedValueList = mo._updateCodedValueListFromRender(layerDefinition, codedValueList);
|
}
|
}
|
}else{
|
codedValueList = codedValueHash.all;
|
}
|
}
|
|
var result = mo._getDisplayValueFromCodedValues(fieldValue, codedValueList);
|
resultList.push(result);
|
}
|
return resultList;
|
|
/*
|
var codedValueHash = {};
|
var typeIdField = layerDefinition.typeIdField;
|
codedValueHash.subType = mo._getRenderTypes(layerDefinition);//subtype list
|
var fieldInfo = mo.getFieldInfoByFieldName(layerDefinition.fields, fieldName);
|
if(codedValueHash.subType && codedValueHash.subType.length > 0){
|
var subTypeValues = codedValueHash.subType;
|
for(var index in subTypeValues){
|
var stValue = subTypeValues[index].value;
|
//codedvalue list by subtypeid
|
codedValueHash[stValue] = mo._getCodedValueBySubTypeId(layerDefinition, fieldName, stValue, fieldInfo);
|
}
|
}
|
codedValueHash.all = mo._getAllCodedValue(layerDefinition, fieldInfo); //all codedvalue list
|
|
var codedValueList = [];
|
var resultList = [];
|
for(var key in attributesList){
|
var attrs = attributesList[key];
|
var fieldValue = attrs[fieldName];
|
var typeIdFieldValue;
|
if(typeIdField === fieldName){
|
codedValueList = codedValueHash.subType;
|
}else{
|
if(attrs.hasOwnProperty(typeIdField)){
|
typeIdFieldValue = attrs[typeIdField];
|
codedValueList = codedValueHash[typeIdFieldValue];
|
}else{
|
codedValueList = codedValueHash.all;
|
}
|
}
|
|
var result = mo._getDisplayValueFromCodedValues(fieldValue, codedValueList);
|
resultList.push(result);
|
}
|
return resultList;
|
*/
|
};
|
|
//three states: code is not in hash, same code and diff label, same sode and label
|
mo._getUniquCodedValue = function(hash, key, value){
|
if(hash[key]){
|
if(value === hash[key]){
|
}else{
|
hash[key] = hash[key] + ', ' + value;
|
}
|
}else{
|
hash[key] = value;
|
}
|
return hash;
|
};
|
|
//get all codedValues by types&field.domains
|
mo._getAllCodedValue = function(layerDefinition, fieldInfo){
|
// var domain = fieldInfo.domain;
|
var fieldName = fieldInfo.name;
|
var codedValsHash = {}; //for Removing the duplicate value by code
|
var codedValues = null;
|
var ifFirstInherited = true;
|
//a field could has codedvalue in types even its domain in fields is null
|
// if(domain && domain.type === 'codedValue'){
|
//get codeValues in types
|
if(layerDefinition.typeIdField && layerDefinition.types && layerDefinition.types.length > 0){
|
array.map(layerDefinition.types, lang.hitch(this, function(item){
|
if(item.domains && item.domains[fieldName]){
|
var fieldDomainInfo = item.domains[fieldName];
|
if(fieldDomainInfo.type === 'inherited'){
|
if(ifFirstInherited){
|
ifFirstInherited = false;
|
var valsArray = mo._getCodedValues(fieldInfo);
|
array.map(valsArray, lang.hitch(this, function(_item){
|
// codedValsHash[_item.value] = _item.label;
|
codedValsHash = mo._getUniquCodedValue(codedValsHash, _item.value, _item.label);
|
}));
|
}
|
}else{
|
if(fieldDomainInfo.codedValues && fieldDomainInfo.codedValues.length > 0){
|
array.map(fieldDomainInfo.codedValues, lang.hitch(this, function(_item){
|
// codedValsHash[_item.code] = _item.name;
|
codedValsHash = mo._getUniquCodedValue(codedValsHash, _item.code, _item.name);
|
}));
|
}
|
}
|
}
|
}));
|
if(!codedValues){//types array does not has this key.(maybe it's not the subtype field)
|
codedValues = mo._getCodedValues(fieldInfo);
|
}
|
}else{ //get codeValues in fields domain
|
return this._getCodedValues(fieldInfo);
|
}
|
var codedValuesArray = [];
|
var isNumberField = mo.isNumberField(fieldInfo.type);
|
for(var key in codedValsHash){
|
var newKey = isNumberField ? parseInt(key, 10) : key;
|
codedValuesArray.push({
|
value: newKey,
|
label: codedValsHash[key]
|
});
|
}
|
// }
|
if(codedValuesArray.length > 0){
|
codedValues = codedValuesArray;
|
}
|
return codedValues;
|
};
|
|
//get all codedValues by types&field.domains
|
mo._getAllCodedValueNew = function(layerDefinition, fieldInfo){
|
// var domain = fieldInfo.domain;
|
var fieldName = fieldInfo.name;
|
var codedValsHash = {}; //for Removing the duplicate value by code
|
var codedValues = null;
|
var ifFirstInherited = true;
|
//a field could has codedvalue in types even its domain in fields is null
|
// if(domain && domain.type === 'codedValue'){
|
//get codeValues in types
|
if(layerDefinition.subtypeField && layerDefinition.subtypes && layerDefinition.subtypes.length > 0){
|
array.map(layerDefinition.subtypes, lang.hitch(this, function(item){
|
if(item.domains && item.domains[fieldName]){
|
var fieldDomainInfo = item.domains[fieldName];
|
if(fieldDomainInfo.type === 'inherited'){
|
if(ifFirstInherited){
|
ifFirstInherited = false;
|
var valsArray = mo._getCodedValues(fieldInfo);
|
array.map(valsArray, lang.hitch(this, function(_item){
|
// codedValsHash[_item.value] = _item.label;
|
codedValsHash = mo._getUniquCodedValue(codedValsHash, _item.value, _item.label);
|
}));
|
}
|
}else{
|
if(fieldDomainInfo.codedValues && fieldDomainInfo.codedValues.length > 0){
|
array.map(fieldDomainInfo.codedValues, lang.hitch(this, function(_item){
|
// codedValsHash[_item.code] = _item.name;
|
codedValsHash = mo._getUniquCodedValue(codedValsHash, _item.code, _item.name);
|
}));
|
}
|
}
|
}
|
}));
|
if(!codedValues){//types array does not has this key.(maybe it's not the subtype field)
|
codedValues = mo._getCodedValues(fieldInfo);
|
}
|
}else{ //get codeValues in fields domain
|
return this._getCodedValues(fieldInfo);
|
}
|
var codedValuesArray = [];
|
var isNumberField = mo.isNumberField(fieldInfo.type);
|
for(var key in codedValsHash){
|
var newKey = isNumberField ? parseInt(key, 10) : key;
|
codedValuesArray.push({
|
value: newKey,
|
label: codedValsHash[key]
|
});
|
}
|
// }
|
if(codedValuesArray.length > 0){
|
codedValues = codedValuesArray;
|
}
|
return codedValues;
|
};
|
|
//get codedvalue list by sutType Id
|
//return [{value,label}]
|
mo._getCodedValueBySubTypeId = function(layerDefinition, fieldName, typeIdFieldValue, /*optional*/fieldInfo){
|
var type = 'typeIdField', arrayType = 'types';
|
if(layerDefinition.subtypeField && layerDefinition.subtypes && layerDefinition.subtypes.length > 0){
|
type = 'subtypeField';
|
arrayType = 'subtypes';
|
}
|
|
var codedValues = null ;
|
fieldInfo = fieldInfo ? fieldInfo : mo.getFieldInfoByFieldName(layerDefinition.fields, fieldName);
|
if(layerDefinition[type] && layerDefinition[arrayType] && layerDefinition[arrayType].length > 0){
|
array.map(layerDefinition[arrayType], lang.hitch(this, function(item){
|
if(item.id === typeIdFieldValue){
|
if(fieldName === layerDefinition[type]){//subtype field---in fact: render field
|
codedValues = [{
|
value: item.id,
|
label: item.name
|
}];
|
return true;
|
}
|
else if(item.domains && item.domains[fieldName]){//other fields
|
var fieldDomainInfo = item.domains[fieldName];
|
if(fieldDomainInfo.type === 'inherited'){
|
codedValues = mo._getCodedValues(fieldInfo);
|
}else{
|
if(fieldDomainInfo.codedValues && fieldDomainInfo.codedValues.length > 0){
|
codedValues = array.map(fieldDomainInfo.codedValues, lang.hitch(this, function(_item){
|
return {
|
value: _item.code,
|
label: _item.name
|
};
|
}));
|
}
|
}
|
}
|
//undefined in domains, when field is subtype field or some error data like#13631.
|
else if(item.domains){
|
codedValues = mo._getCodedValues(fieldInfo);
|
}
|
}
|
}));
|
if(!codedValues){//types array does not has this key.(maybe it's not the subtype field)
|
codedValues = mo._getCodedValues(fieldInfo);
|
}
|
}else{
|
codedValues = mo._getCodedValues(fieldInfo); //if the field isn't in types array but has its own domain codedvalue
|
}
|
return codedValues;
|
};
|
|
//get codedvalue list, return all or some by subtypeId from a feature attributes
|
//attributes:feature's attributes or a obj of same format(it may has a subtype field or not).
|
//return [{value,label}], return null means no subtypes or no coded value field
|
mo.getCodedValueListForCodedValueOrSubTypes = function(layerDefinition, fieldName, attributes){
|
mo._deleteSubtypePropertiesTemp(layerDefinition);
|
var codedValues = null ;
|
var fieldInfo = mo.getFieldInfoByFieldName(layerDefinition.fields, fieldName);
|
|
var typeIdFieldValue, subtypeFieldValue;
|
if(attributes){
|
typeIdFieldValue = attributes[layerDefinition.typeIdField]; //it can be 0(number)
|
subtypeFieldValue = attributes[layerDefinition.subtypeField]; //it can be 0(number)
|
}
|
|
if(layerDefinition.subtypeField && layerDefinition.subtypes && layerDefinition.subtypes.length > 0){
|
//current field is subtype field
|
if(fieldName === layerDefinition.subtypeField){
|
codedValues = mo._getSubTypes(layerDefinition); //get subtyps list
|
if(subtypeFieldValue !== undefined){
|
var _valueInfo = mo._getDisplayValueFromCodedValues(subtypeFieldValue, codedValues);
|
codedValues = [{
|
value:_valueInfo.value,
|
label:_valueInfo.displayValue
|
}];
|
}
|
}else{
|
if(subtypeFieldValue === undefined){//return all domains from subtype list
|
codedValues = mo._getAllCodedValueNew(layerDefinition, fieldInfo);
|
}else{//return one domain from current subtype value
|
//get codedvalues list, from layerDefinition.subtypes..domain.
|
codedValues = mo._getCodedValueBySubTypeId(layerDefinition, fieldName, subtypeFieldValue, fieldInfo);
|
}
|
}
|
//update labels from render(if render current field)
|
if(fieldName === layerDefinition.typeIdField){ //update labels from render
|
codedValues = mo._updateCodedValueListFromRender(layerDefinition, codedValues);
|
}
|
return codedValues;
|
}else{ //no subtype field
|
// if(layerDefinition.subtypeField === ''){ //no subtype field
|
layerDefinition.subtypeField = '';
|
layerDefinition.subtypes = [];
|
//continue old logic.
|
}
|
|
//current fieldName is typeIdField
|
if(layerDefinition.typeIdField && layerDefinition.typeIdField.toUpperCase() === fieldName.toUpperCase()){
|
codedValues = mo._getRenderTypes(layerDefinition);
|
if(attributes && typeIdFieldValue !== undefined && typeIdFieldValue !== null){ //attributes has subtype field, return one data
|
var valueInfo = mo._getDisplayValueFromCodedValues(typeIdFieldValue, codedValues);
|
codedValues = [{
|
value:valueInfo.value,
|
label:valueInfo.displayValue
|
}];
|
}
|
}else{ //other fields
|
if(attributes && typeIdFieldValue !== undefined && typeIdFieldValue !== null){ //attributes has subtype field, so filter it
|
codedValues = mo._getCodedValueBySubTypeId(layerDefinition, fieldName, typeIdFieldValue, fieldInfo);
|
}else{
|
codedValues = mo._getAllCodedValue(layerDefinition, fieldInfo);
|
}
|
}
|
if(fieldName === layerDefinition.typeIdField){ //update labels from render
|
codedValues = mo._updateCodedValueListFromRender(layerDefinition, codedValues);
|
}
|
return codedValues;
|
};
|
|
//check if current field is subtype field, and which field is subtype field from layerDefiniton
|
mo._verifyIfFieldIsSubtypeField = function(layerDefinition, fieldInfo){
|
var info = {
|
isSubtypeField: false, // if current field is subtype field.
|
subtypeField: '' //the name of the subtype field.
|
};
|
//version:10.5+, it's subtype 's fieldName if layer has a subtype field, not undefined or ''
|
//subtypeField is a layer property that is set to the name of the subtype field.
|
//If the layer does not have subtypes, it is set to empty string ("subtypeField": "").
|
if(layerDefinition.subtypeField){
|
info = {
|
isSubtypeField: layerDefinition.subtypeField === fieldInfo.name,
|
subtypeField: layerDefinition.subtypeField
|
};
|
return info;
|
}
|
|
//old versions need fieldInfo to verify
|
var isRenderBySubtype = false;
|
var subtypeFieldTypes = [
|
'esriFieldTypeSmallInteger',
|
'esriFieldTypeInteger'
|
];
|
//1. render by current field, it maybe the subtype field.
|
//2. checkout types.domain to verify
|
if(subtypeFieldTypes.indexOf(fieldInfo.type) && layerDefinition.typeIdField === fieldInfo.name &&
|
(layerDefinition.types && layerDefinition.types.length > 0)){
|
var domains = layerDefinition.types[0].domains;
|
//when layer has error data like: domain={}, then can't tell if it's subtype field.
|
if(domains[fieldInfo.name] === undefined){
|
info = {
|
isSubtypeField: true,
|
subtypeField: fieldInfo.name
|
};
|
}else{ // current field is existed in domains, so it can't be subtype field
|
info.isSubtypeField = false;
|
}
|
}
|
return isRenderBySubtype;
|
};
|
|
//no render https://sampleserver6.arcgisonline.com/arcgis/rest/services/911CallsHotspot/MapServer/2?f=json
|
mo._getRenderValueLabelsForUnique = function(layerDefinition){
|
var valueLabels = null;
|
if(layerDefinition.drawingInfo && layerDefinition.drawingInfo.renderer &&
|
layerDefinition.drawingInfo.renderer.type === 'uniqueValue'){
|
valueLabels = {};
|
var uniqueValueInfos = layerDefinition.drawingInfo.renderer.uniqueValueInfos;
|
for(var key = 0; key < uniqueValueInfos.length; key ++){
|
var info = uniqueValueInfos[key];
|
valueLabels[info.value] = info.label;
|
}
|
}
|
return valueLabels;
|
};
|
|
//update codedValues from render labels(call this function when fieldnName = typeIdField)
|
mo._updateCodedValueListFromRender = function(layerDefinition, codedValues){ //[{value,label}]
|
var renderCodedValues = mo._getRenderValueLabelsForUnique(layerDefinition);
|
if(renderCodedValues && codedValues){
|
for(var key = 0; key < codedValues.length; key ++){
|
var codeValue = codedValues[key];
|
if(renderCodedValues[codeValue.value]){
|
codeValue.label = renderCodedValues[codeValue.value];
|
}
|
}
|
}
|
return codedValues;
|
};
|
|
//return {fieldName,label,tooltip,visible,format,stringFieldOption}
|
mo.getDefaultPortalFieldInfo = function(serviceFieldInfo){
|
//serviceFieldInfo: {name,alias,type,...}
|
var fieldName = serviceFieldInfo.name;
|
var item = {
|
fieldName: fieldName,
|
label: serviceFieldInfo.alias || fieldName,
|
tooltip: '',
|
visible: false,
|
format: null,
|
stringFieldOption: 'textbox'
|
};
|
|
//https://developers.arcgis.com/javascript/jsapi/field-amd.html#type
|
var type = serviceFieldInfo.type;
|
switch (type) {
|
case 'esriFieldTypeSmallInteger':
|
case 'esriFieldTypeInteger':
|
item.format = {
|
places: 0,
|
digitSeparator: true
|
};
|
break;
|
case 'esriFieldTypeSingle':
|
case 'esriFieldTypeDouble':
|
item.format = {
|
places: 2,
|
digitSeparator: true
|
};
|
break;
|
case 'esriFieldTypeDate':
|
item.format = {
|
dateFormat: "longMonthDayYear"
|
};
|
break;
|
}
|
return item;
|
};
|
|
mo.getDefaultPopupInfo = function(object, title, fieldNames) {
|
// return popupInfo with all fieldInfos if the fieldName is null;
|
var popupInfo = null;
|
if(object && object.fields) {
|
popupInfo = {
|
title: title,
|
fieldInfos:[],
|
description: null,
|
showAttachments: true,
|
mediaInfos: []
|
};
|
array.forEach(object.fields, function(field){
|
var isValidField = false;
|
if(fieldNames) {
|
var isValidFieldName = array.some(fieldNames, lang.hitch(this, function(fieldName) {
|
return fieldName && (field.name.toLowerCase() === fieldName.toLowerCase());
|
}));
|
if(isValidFieldName) {
|
isValidField = true;
|
}
|
} else {
|
isValidField = true;
|
}
|
if(isValidField) {
|
var fieldInfo = this.getDefaultPortalFieldInfo(field);
|
fieldInfo.visible = true;
|
fieldInfo.isEditable = field.editable;
|
popupInfo.fieldInfos.push(fieldInfo);
|
}
|
}, this);
|
}
|
return popupInfo;
|
};
|
|
mo._tryLocaleNumber = function(value) {
|
var result = mo.localizeNumber(value);
|
if (result === null || result === undefined) {
|
result = value;
|
}
|
return result;
|
};
|
|
mo._tryLocaleDate = function(date) {
|
var result = mo.localizeDate(date);
|
if (!result) {
|
result = date.toLocaleDateString();
|
}
|
return result;
|
};
|
|
//fieldInfos: layerDefinition.fields
|
mo.getFieldInfoByFieldName = function(fieldInfos, fieldName) {
|
var fieldInfo = null;
|
if (fieldInfos && fieldInfos.length > 0) {
|
array.some(fieldInfos, lang.hitch(this, function(item) {
|
if (item.name === fieldName) {
|
fieldInfo = item;
|
return true;
|
} else {
|
return false;
|
}
|
}));
|
}
|
return fieldInfo;
|
};
|
|
//fieldInfos: popupFieldsInfo
|
mo.getDateFieldFormatByFieldName = function(fieldInfos, fieldName) {
|
if (fieldInfos && fieldInfos.length > 0) {
|
for(var key = 0; key < fieldInfos.length; key++){
|
var item = fieldInfos[key];
|
if (item.fieldName === fieldName) {
|
if(item.format && item.format.dateFormat){
|
return item.format.dateFormat;
|
}else{
|
return '';
|
}
|
}
|
}
|
return '';
|
}
|
return '';
|
};
|
|
//layerField: https://developers.arcgis.com/web-map-specification/objects/field/
|
//popupField: https://developers.arcgis.com/web-map-specification/objects/fieldInfo/
|
mo.completePopupFieldFromLayerField = function(layerFields, popupFields){
|
for(var layerKey in layerFields){
|
var layerFieldName = layerFields[layerKey].name;
|
var isExist = false;
|
for(var popupKey in popupFields){
|
if(popupFields[popupKey].fieldName === layerFieldName){
|
isExist = true;
|
break;
|
}
|
}
|
if(!isExist){
|
var _fieldInfo = mo.getPopupFieldFromLayerField(layerFields[layerKey]);
|
popupFields.push(_fieldInfo);
|
}
|
}
|
return popupFields;
|
};
|
|
mo.getPopupFieldFromLayerField = function(layerField){
|
var _fieldInfo = {
|
//pro publish (no edit by map viewer in some old versions)
|
'fieldName': layerField.name,
|
'isEditable': layerField.editable,
|
'label': layerField.alias,
|
'visible': layerField.visible ? layerField.visible : false,
|
|
//other ways(include attrs above)
|
//stringFieldOption is only for string field: textbox, textarea, richtext
|
'stringFieldOption': layerField.type === 'esriFieldTypeString' ? 'textbox': null,
|
'tooltips': '',
|
'domain': layerField.domain ? layerField.domain : null
|
};
|
return _fieldInfo;
|
};
|
|
mo.containsNonLatinCharacter = function(string) {
|
/*
|
console.log(string);
|
for (var k = 0; k < string.length; k++) {
|
console.log(string.charCodeAt(k));
|
}
|
*/
|
for (var i = 0; i < string.length; i++) {
|
if (string.charCodeAt(i) > 255) {
|
return true;
|
}
|
}
|
return false;
|
};
|
|
mo.has = function(browserName) {
|
function _isIE11() {
|
var iev = 0;
|
var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
|
var trident = !!navigator.userAgent.match(/Trident\/7.0/);
|
var rv = navigator.userAgent.indexOf("rv:11.0");
|
|
if (ieold) {
|
iev = Number(RegExp.$1);
|
}
|
if (navigator.appVersion.indexOf("MSIE 10") !== -1) {
|
iev = 10;
|
}
|
if (trident && rv !== -1) {
|
iev = 11;
|
}
|
|
return iev === 11;
|
}
|
function _isEdge() {
|
return navigator.userAgent.split('Edge/')[1];
|
}
|
var v = has(browserName);
|
if (!v) {
|
if (browserName.toLowerCase() === 'ie') {
|
return (_isIE11() && 11) || v;
|
} else if (browserName.toLowerCase() === 'edge') {
|
return _isEdge() || v;
|
}
|
} else {
|
return v;
|
}
|
};
|
|
mo.detectUserAgent = function() {
|
var os = {}, browser = {},
|
ua = navigator.userAgent, platform = navigator.platform,
|
webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/),
|
android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
|
osx = !!ua.match(/\(Macintosh\; Intel /),
|
ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
|
ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
|
iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
|
webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
|
win = /Win\d{2}|Windows/.test(platform),
|
wp = ua.match(/Windows Phone ([\d.]+)/),
|
touchpad = webos && ua.match(/TouchPad/),
|
kindle = ua.match(/Kindle\/([\d.]+)/),
|
silk = ua.match(/Silk\/([\d._]+)/),
|
blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
|
bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
|
rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
|
playbook = ua.match(/PlayBook/),
|
chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
|
firefox = ua.match(/Firefox\/([\d.]+)/),
|
firefoxos = ua.match(/\((?:Mobile|Tablet); rv:([\d.]+)\).*Firefox\/[\d.]+/),
|
ie = ua.match(/MSIE\s([\d.]+)/) || ua.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/),
|
webview = !chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
|
safari = webview || ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/);
|
|
browser.webkit = !!webkit;
|
if (browser.webkit) {
|
browser.version = webkit[1];
|
}
|
|
if (android) {
|
os.android = true;
|
os.version = android[2];
|
}
|
if (iphone && !ipod) {
|
os.ios = os.iphone = true;
|
os.version = iphone[2].replace(/_/g, '.');
|
}
|
if (ipad) {
|
os.ios = os.ipad = true;
|
os.version = ipad[2].replace(/_/g, '.');
|
}
|
if (ipod) {
|
os.ios = os.ipod = true;
|
os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
|
}
|
if (wp) {
|
os.wp = true;
|
os.version = wp[1];
|
}
|
if (webos) {
|
os.webos = true;
|
os.version = webos[2];
|
}
|
if (touchpad) {
|
os.touchpad = true;
|
}
|
if (blackberry) {
|
os.blackberry = true;
|
os.version = blackberry[2];
|
}
|
if (bb10) {
|
os.bb10 = true;
|
os.version = bb10[2];
|
}
|
if (rimtabletos) {
|
os.rimtabletos = true;
|
os.version = rimtabletos[2];
|
}
|
if (playbook) {
|
browser.playbook = true;
|
}
|
if (kindle) {
|
os.kindle = true;
|
os.version = kindle[1];
|
}
|
if (silk) {
|
browser.silk = true;
|
browser.version = silk[1];
|
}
|
if (!silk && os.android && ua.match(/Kindle Fire/)) {
|
browser.silk = true;
|
}
|
if (chrome) {
|
browser.chrome = true;
|
browser.version = chrome[1];
|
}
|
if (firefox) {
|
browser.firefox = true;
|
browser.version = firefox[1];
|
}
|
if (firefoxos) {
|
os.firefoxos = true;
|
os.version = firefoxos[1];
|
}
|
if (ie) {
|
browser.ie = true;
|
browser.version = ie[1];
|
}
|
if (safari && (osx || os.ios || win)) {
|
browser.safari = true;
|
if (!os.ios) {
|
browser.version = safari[1];
|
}
|
}
|
if (webview) {
|
browser.webview = true;
|
}
|
|
os.tablet = !!(ipad || playbook || (android && !ua.match(/Mobile/)) ||
|
(firefox && ua.match(/Tablet/)) || (ie && !ua.match(/Phone/) && ua.match(/Touch/)));
|
os.phone = !!(!os.tablet && !os.ipod && (android || iphone || webos || blackberry || bb10 ||
|
(chrome && ua.match(/Android/)) || (chrome && ua.match(/CriOS\/([\d.]+)/)) ||
|
(firefox && ua.match(/Mobile/)) || (ie && ua.match(/Touch/))));
|
|
return {
|
os: os,
|
browser: browser
|
};
|
};
|
mo.isMobileUa = function() {
|
var uaInfo = mo.detectUserAgent();
|
if (true === uaInfo.os.phone || true === uaInfo.os.tablet) {
|
return true;
|
} else {
|
return false;
|
}
|
};
|
|
mo.inMobileSize = function(){
|
var layoutBox = html.getMarginBox(document.body);
|
if (layoutBox.w <= window.jimuConfig.breakPoints[0] ||
|
layoutBox.h <= window.jimuConfig.breakPoints[0]) {
|
html.addClass(window.jimuConfig.layoutId, 'jimu-ismobile');
|
return true;
|
} else {
|
html.removeClass(window.jimuConfig.layoutId, 'jimu-ismobile');
|
return false;
|
}
|
};
|
|
mo.getObjectIdField = function(layerDefinition){
|
if(layerDefinition.objectIdField){
|
return layerDefinition.objectIdField;
|
}else{
|
var fieldInfos = layerDefinition.fields;
|
for(var i = 0; i < fieldInfos.length; i++){
|
var fieldInfo = fieldInfos[i];
|
if(fieldInfo.type === 'esriFieldTypeOID'){
|
return fieldInfo.name;
|
}
|
}
|
}
|
return null;
|
};
|
|
//if browser(such as Chrome50) have window.isSecureContext, and not in https origin, return true
|
//for example: if true===isNendHttpsButNot(), MyLocateButton should be disabled
|
mo.isNeedHttpsButNot = function() {
|
//copy from: https://devtopia.esri.com/WebGIS/arcgis-js-api/issues/6614
|
var hasGeolocation = navigator.geolocation;
|
var hasSecureContext = window.hasOwnProperty("isSecureContext");
|
var isSecureContext = (hasSecureContext && window.isSecureContext) ||
|
(!hasSecureContext && window.location.protocol === "https:");
|
if (!isSecureContext || !hasGeolocation) {
|
return true;
|
} else {
|
return false;
|
}
|
};
|
|
|
mo.showValidationErrorTipForFormDijit = function(_dijit){
|
try{
|
if (!_dijit.validate() && _dijit.domNode) {
|
if (_dijit.focusNode) {
|
_dijit.focusNode.focus();
|
setTimeout(lang.hitch(this, function() {
|
_dijit.focusNode.blur();
|
}), 100);
|
}
|
}
|
}catch(e){
|
console.error(e);
|
}
|
};
|
|
mo.getFeatureLayerDefinition = function(featureLayer){
|
var layerDefinition = null;
|
var features = featureLayer.graphics;
|
featureLayer.graphics = [];
|
var json = featureLayer.toJson();
|
featureLayer.graphics = features;
|
if(json){
|
layerDefinition = json.layerDefinition;
|
}
|
return layerDefinition;
|
};
|
|
mo.simulateClickEvent = function(dom){
|
if(has('safari')){
|
//create an event
|
var mouseEvent = document.createEvent("MouseEvents");
|
//initialize the event
|
mouseEvent.initEvent("click",/* bubble */ true, /* cancelable */ true);
|
//trigger the evevnt
|
dom.dispatchEvent(mouseEvent);
|
}else{
|
dom.click();
|
}
|
};
|
|
|
|
mo.isInConfigOrPreviewWindow = function(){
|
var b = false;
|
try{
|
b = !window.isBuilder && window.parent && window.parent !== window &&
|
window.parent.isBuilder;
|
}catch(e){
|
// console.log(e);
|
b = false;
|
}
|
return !!b;
|
};
|
|
//for cross-origin frame
|
mo.getAppHref = function(){
|
var href = "";
|
if (mo.isInConfigOrPreviewWindow()) {
|
href = window.parent.location.href;
|
} else {
|
href = window.location.href;
|
}
|
return href;
|
};
|
|
mo.getAppIdFromUrl = function() {
|
var isDeployedApp = true,
|
href = mo.getAppHref();// window.top.location.href;
|
if (href.indexOf("id=") !== -1 || href.indexOf("appid=") !== -1 ||
|
href.indexOf("apps") !== -1) {
|
isDeployedApp = false;
|
}
|
|
if (isDeployedApp === true) {
|
// deployed app use pathname as key
|
return href;
|
} else {
|
// xt or integration use id of app as key
|
var urlParams = this.urlToObject(window.location.href);
|
if (urlParams.query) {
|
if (urlParams.query.id || urlParams.query.appid) {
|
return urlParams.query.id || urlParams.query.appid;
|
}
|
}
|
|
// if there is no id/appid in url
|
if (window.appInfo) {
|
if (window.appInfo.id) {
|
//id in appInfo
|
return window.appInfo.id;
|
} else if (window.appInfo.appPath) {
|
//parse id from appPath
|
var list = window.appInfo.appPath.split("/");
|
if (list.length && list.length > 2) {
|
return list[list.length - 2];
|
}
|
} else {
|
console.error("CAN NOT getAppIdFromUrl");
|
}
|
}
|
}
|
};
|
|
mo.getEditorContentHeight = function(content, dom, domParam) {
|
var def = new Deferred();
|
this._content = content;
|
this._dom = dom;
|
this._domParam = domParam;
|
var timeoutHandler = setTimeout(lang.hitch(this, function() {
|
clearTimeout(timeoutHandler);
|
timeoutHandler = null;
|
|
var h = 0;
|
var scrollerWidth = 20;
|
var polyfill = 8;
|
var contentWidth = this._domParam.contentWidth;//defaultWidth - marginLeftRight;
|
try {
|
var fakeContent = document.createElement('div');
|
fakeContent.setAttribute('id', 'fakeContent');
|
html.setStyle(fakeContent, "background-size", "contain");
|
fakeContent.innerHTML = this._content;
|
this._dom.appendChild(fakeContent);
|
if (fakeContent) {
|
//to adjust images
|
var contentImgs = query('img', fakeContent);
|
if (contentImgs && contentImgs.length) {
|
contentImgs.style({
|
maxWidth: (contentWidth - scrollerWidth) + 'px'
|
});
|
}
|
|
html.setStyle(fakeContent, "position", "absolute");
|
html.setStyle(fakeContent, "width", contentWidth + "px");
|
html.setStyle(fakeContent, "left", "-99999px");
|
html.setStyle(fakeContent, "top", "-99999px");
|
html.setStyle(fakeContent, "visibility", "hidden");
|
|
var box = html.getContentBox(fakeContent);
|
if (box.h) {
|
//content height
|
h = box.h;
|
//+ content margin top + content margin bottom + polyfill
|
h += (this._domParam.contentMarginTop + this._domParam.footerHeight + polyfill);
|
}
|
//TODO delete
|
// if (h) {
|
// this._dom.removeChild(fakeContent);
|
// }
|
}
|
} catch (err) {
|
console.error("can't getEditorContentHeight" + err);
|
h = 200;
|
}
|
|
def.resolve(h);
|
}), 1500);
|
return def;
|
};
|
|
mo.getEditorTextColor = function(colorRecordID, forceAttr) {
|
return {
|
name: "dijit.editor.plugins.EditorTextColor",
|
custom: {
|
recordUID: mo.getColorRecordName(colorRecordID),
|
forceAttr: forceAttr
|
}
|
};
|
};
|
mo.getEditorBackgroundColor = function(colorRecordID) {
|
return {
|
name: "dijit.editor.plugins.EditorBackgroundColor",
|
custom: {
|
recordUID: mo.getColorRecordName(colorRecordID)
|
}
|
};
|
};
|
mo.getColorRecordName = function(id){
|
return "wab_cr_" + (id || "");
|
};
|
mo.b64toBlob = function(b64Data, contentType, sliceSize) {
|
contentType = contentType || '';
|
sliceSize = sliceSize || 512;
|
var byteCharacters = window.atob(b64Data.replace(/^data:image\/(png|jpg|jpeg|gif);base64,/, ''));
|
var byteArrays = [];
|
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
var slice = byteCharacters.slice(offset, offset + sliceSize);
|
var byteNumbers = new Array(slice.length);
|
for (var i = 0; i < slice.length; i++) {
|
byteNumbers[i] = slice.charCodeAt(i);
|
}
|
var byteArray = new Uint8Array(byteNumbers);
|
byteArrays.push(byteArray);
|
}
|
var blob = new Blob(byteArrays, {
|
type: contentType
|
});
|
return blob;
|
};
|
mo.subtractionArray = function(arr1, arr2) {
|
//return arr1 = arr1 - arr2
|
for (var i = arr1.length - 1; i >= 0; i--) {
|
var a = arr1[i];
|
for (var j = arr2.length - 1; j >= 0; j--) {
|
var b = arr2[j];
|
if (a === b) {
|
arr1.splice(i, 1);
|
arr2.splice(j, 1);
|
break;
|
}
|
}
|
}
|
return arr1;
|
};
|
|
mo.processItemResourceOfAppConfig = function(appConfig, cb){
|
//Traverse appConfig and get all the data that matches the cb.test,
|
//along with its direct parent object, passed to the callback function(cb.func)
|
|
//cb:{test,func}
|
//args:all parameters that need to be passed to the callback function(cb.func)
|
//
|
//Return: if cb.func return a promise(defs.length > 0),this function will return a deferred
|
// else return {appConfig,normalReturnValues}
|
var normalReturnValues = [];
|
var defs = [];
|
var callbackReturn;
|
|
function _formatPendingObj(pendingObj){
|
var obj = pendingObj.obj;
|
var key = pendingObj.key;
|
var formatObj = {
|
obj:obj,
|
key:key
|
};
|
if(typeof pendingObj.i === 'number'){
|
formatObj.i = pendingObj.i;
|
formatObj.value = obj[key][pendingObj.i];
|
}else{
|
formatObj.value = obj[key];
|
}
|
return formatObj;
|
}
|
|
function processObject(obj) {
|
for (var key in obj) {
|
if (typeof obj[key] === 'object') {
|
if (Array.isArray(obj[key])) {
|
processArray(obj, key);
|
} else {
|
processObject(obj[key]);
|
}
|
} else if (typeof obj[key] === 'string') {
|
processString(obj, key);
|
}
|
}
|
}
|
|
function processString(obj, key, i){
|
if(typeof i === 'number'){
|
if (cb.test(obj[key][i])) {
|
callbackReturn = cb.func(_formatPendingObj({
|
obj: obj,
|
key: key,
|
i:i
|
}));
|
if(typeof callbackReturn.then === 'function'){
|
defs.push(callbackReturn);
|
}else{
|
normalReturnValues.push(callbackReturn);
|
}
|
}
|
}else{
|
if (cb.test(obj[key])) {
|
callbackReturn = cb.func(_formatPendingObj({
|
obj: obj,
|
key: key
|
}));
|
if(typeof callbackReturn.then === 'function'){
|
defs.push(callbackReturn);
|
}else{
|
normalReturnValues.push(callbackReturn);
|
}
|
}
|
}
|
}
|
|
function processArray(obj, key){
|
for (var i = 0; i < obj[key].length; i++) {
|
if (typeof obj[key][i] === 'string') {
|
processString(obj, key, i);
|
}else if (typeof obj[key][i] === 'object') {
|
processObject(obj[key][i]);
|
}
|
}
|
}
|
|
processObject(appConfig);
|
|
if(defs.length > 0){
|
return all(defs).then(function(result){
|
if(normalReturnValues.length > 0){
|
result = result.concat(normalReturnValues);
|
}
|
return {
|
appConfig: appConfig,
|
result: result
|
};
|
});
|
}else{
|
return {
|
appConfig: appConfig,
|
result: normalReturnValues
|
};
|
}
|
};
|
mo.isEsriDomain = function(url){
|
return /^https?:\/\/(?:[\w\-\_]+\.)+(?:esri|arcgis)\.com/.test(url);
|
};
|
mo.uniqueArray = function(array) {
|
var n = [];
|
for (var i = 0; i < array.length; i++) {
|
if (n.indexOf(array[i]) === -1) {
|
n.push(array[i]);
|
}
|
}
|
return n;
|
};
|
|
mo.isNotEmptyObject = function(obj, includeArray) {
|
if(!!includeArray){
|
return mo.isObject(obj) && Object.keys(obj).length > 0 && Array.isArray(obj);
|
}else{
|
return mo.isObject(obj) && Object.keys(obj).length > 0;
|
}
|
};
|
mo.getMinOfArray = function(array) {
|
return Number(Math.min.apply(Math, array));
|
};
|
mo.getDataSchemaFromLayerDefinition = function(layerDefinition){
|
var oIdField = layerDefinition.fields.filter(function(f){
|
return f.type === 'esriFieldTypeOID';
|
});
|
if(oIdField.length > 0){
|
oIdField = oIdField[0];
|
}else{
|
oIdField = null;
|
}
|
|
return {
|
geometryType: layerDefinition.geometryType,
|
fields: layerDefinition.fields,
|
displayField: layerDefinition.displayField,
|
objectIdField: oIdField,
|
typeIdField: layerDefinition.typeIdField
|
};
|
};
|
|
mo.isValidPointGeometry = function(geometry) {
|
return geometry && geometry.type === 'point' && mo.isTrueOrZero(geometry.x) &&
|
mo.isTrueOrZero(geometry.y);
|
};
|
|
// Incorrect function name, keep it here for back compatibility.
|
mo.isVaildPointGeometry = mo.isValidPointGeometry;
|
|
mo.isNumberOrNumberString = function(value) {
|
return /^-?[1-9]\d*$/.test(value) ||
|
/^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$/.test(value);
|
};
|
|
//0.1234 --> 12.34% or %12.34(locale=ar or tr)
|
mo.convertNumberToPercentage = function(number, /*optional*/ decimalDigits) {
|
if (!mo.isNumberOrNumberString(number)) {
|
return number;
|
}
|
if (typeof decimalDigits === 'undefined') {
|
decimalDigits = 2;
|
}
|
var locale = config.locale;
|
var shouldPercentSignLeft = locale === 'ar' || locale === 'tr';
|
number = Number(number);
|
var isNegative = false;
|
if (number < 0) {
|
isNegative = true;
|
number = Math.abs(number);
|
}
|
number = number * 100;
|
number = number.toFixed(decimalDigits);
|
number = mo.localizeNumber(number);
|
|
if (!shouldPercentSignLeft) {
|
number += '%';
|
} else {
|
number = '%' + number;
|
}
|
|
if (isNegative) {
|
number = '-' + number;
|
}
|
|
return number;
|
};
|
|
|
|
|
mo.upperCaseString = function(temp) {
|
if (temp && typeof temp === 'string') {
|
return temp.toUpperCase();
|
}
|
return temp;
|
};
|
|
mo.lowerCaseString = function(temp) {
|
if (temp && typeof temp === 'string') {
|
return temp.toLowerCase();
|
}
|
return temp;
|
};
|
|
return mo;
|
});
|