|
|
$axure = function(query) { return $axure.query(query); }; // ******* AxQuery and Page metadata ******** //
(function() { var $ax = function() { var returnVal = $axure.apply(this, arguments); var axFn = $ax.fn; for (var key in axFn) { returnVal[key] = axFn[key]; }
return returnVal; };
$ax.public = $axure; $ax.fn = {};
$axure.internal = function(initFunction) { //Attach messagecenter to $ax object so that it can be used in viewer.js, etc in internal scope
if(!$ax.messageCenter) $ax.messageCenter = $axure.messageCenter;
return initFunction($ax); }; var _lastFiredResize = 0; var _resizeFunctions = []; var _lastTimeout; var _fireResize = function() { if (_lastTimeout) window.clearTimeout(_lastTimeout); _lastTimeout = undefined; _lastFiredResize = new Date().getTime(); for(var i = 0; i < _resizeFunctions.length; i++) _resizeFunctions[i](); }; $axure.resize = function(fn) { if(fn) _resizeFunctions[_resizeFunctions.length] = fn; else $(window).resize(); };
$(window).resize(function() { var THRESHOLD = 50; _updateWindowInfo(); var now = new Date().getTime(); if(now - _lastFiredResize > THRESHOLD) { _fireResize(); } else if(!_lastTimeout) { _lastTimeout = window.setTimeout(_fireResize, THRESHOLD); } });
$(window).scroll(function () { _updateWindowInfo(); });
var _windowInfo; var _updateWindowInfo = $axure.updateWindowInfo = function () { var win = {}; var jWin = $(window); var scrollWin = $('#ios-safari-html').length > 0 ? $('#ios-safari-html') : jWin; win.width = jWin.width(); win.height = jWin.height(); win.scrollx = scrollWin.scrollLeft(); win.scrolly = scrollWin.scrollTop(); _windowInfo = win; }; $ax.getWindowInfo = function () { if(!_windowInfo) _updateWindowInfo(); return _windowInfo; };
window.$obj = function(id) { return $ax.getObjectFromElementId(id); };
window.$id = function(obj) { return obj.scriptIds[0]; };
window.$jobj = function(id) { return $(document.getElementById(id)); };
window.$jobjAll = function(id) { return $addAll($jobj(id), id); };
window.$addAll = function(jobj, id) { return jobj.add($jobj(id + '_ann')).add($jobj(id + '_ref')); };
$ax.INPUT = function(id) { return id + "_input"; }; $ax.IsImageFocusable = function (type) { return $ax.public.fn.IsImageBox(type) || $ax.public.fn.IsVector(type) || $ax.public.fn.IsTreeNodeObject(type) || $ax.public.fn.IsTableCell(type); }; $ax.IsTreeNodeObject = function (type) { return $ax.public.fn.IsTreeNodeObject(type); }; $ax.IsSelectionButton = function (type) { return $ax.public.fn.IsCheckBox(type) || $ax.public.fn.IsRadioButton(type); };
var _fn = {}; $axure.fn = _fn; $axure.fn.jQuery = function() { var elements = this.getElements(); return $(elements); }; $axure.fn.$ = $axure.fn.jQuery;
var _query = function(query, queryArg) { var returnVal = {}; var _axQueryObject = returnVal.query = { }; _axQueryObject.filterFunctions = [];
if (query == '*') { _axQueryObject.filterFunctions[0] = function() { return true; }; } else if (typeof(query) === 'function') { _axQueryObject.filterFunctions[0] = query; } else { var firstString = $.trim(query.toString()); if (firstString.charAt(0) == '@') { _axQueryObject.filterFunctions[0] = function(diagramObject) { return diagramObject.label == firstString.substring(1); }; } else if (firstString.charAt(0) == '#') { _axQueryObject.elementId = firstString.substring(1); } else { if (firstString == 'label') { _axQueryObject.filterFunctions[0] = function(diagramObject) { return queryArg instanceof Array && queryArg.indexOf(diagramObject.label) > 0 || queryArg instanceof RegExp && queryArg.test(diagramObject.label) || diagramObject.label == queryArg; }; } else if(firstString == 'elementId') { _axQueryObject.filterFunctions[0] = function(diagramObject, elementId) { return queryArg instanceof Array && queryArg.indexOf(elementId) > 0 || elementId == queryArg; }; } } }
var axureFn = $axure.fn; for (var key in axureFn) { returnVal[key] = axureFn[key]; } return returnVal; }; $axure.query = _query;
var _getFilterFnFromQuery = function(query) { var filter = function(diagramObject, elementId) { // Non diagram objects are allowed to be queryed, such as text inputs.
if (diagramObject && !$ax.public.fn.IsReferenceDiagramObject(diagramObject.type) && !document.getElementById(elementId)) return false; var retVal = true; for(var i = 0; i < query.filterFunctions.length && retVal; i++) { retVal = query.filterFunctions[i](diagramObject, elementId); } return retVal; }; return filter; };
$ax.public.fn.filter = function(query, queryArg) { var returnVal = _query(query, queryArg); if(this.query.elementId) returnVal.query.elementId = this.query.elementId; //If there is already a function, offset by 1 when copying other functions over.
var offset = returnVal.query.filterFunctions[0] ? 1 : 0; //Copy all functions over to new array.
for(var i = 0; i < this.query.filterFunctions.length; i++) returnVal.query.filterFunctions[i+offset] = this.query.filterFunctions[i]; //Functions are in reverse order now
returnVal.query.filterFunctions.reverse();
return returnVal; };
$ax.public.fn.each = function(fn) { var filter = _getFilterFnFromQuery(this.query); var elementIds = this.query.elementId ? [this.query.elementId] : $ax.getAllElementIds(); for (var i = 0; i < elementIds.length; i++) { var elementId = elementIds[i]; var diagramObject = $ax.getObjectFromElementId(elementId); if (filter(diagramObject, elementId)) { fn.apply(diagramObject, [diagramObject, elementId]); } } };
$ax.public.fn.getElements = function() { var elements = []; this.each(function(dObj, elementId) { var elementById = document.getElementById(elementId); if(elementById) elements[elements.length] = elementById; }); return elements; }; $ax.public.fn.getElementIds = function() { var elementIds = []; this.each(function(dObj, elementId) { elementIds[elementIds.length] = elementId; }); return elementIds; };
// Deep means to keep getting parents parent until at the root parent. Parent is then an array instead of an id.
// Filter options: layer, rdo, repeater, item, dynamicPanel, state
$ax.public.fn.getParents = function (deep, filter) { if(filter == '*') filter = ['layer', 'rdo', 'repeater', 'item', 'dynamicPanel', 'state']; var elementIds = this.getElementIds(); var parentIds = [];
var getParent = function(elementId) { var containerIndex = elementId.indexOf('_container'); if(containerIndex !== -1) elementId = elementId.substring(0, containerIndex); if(elementId.indexOf('_text') !== -1) elementId = $ax.GetShapeIdFromText(elementId);
// Check repeater item before layer, because repeater item detects it's parent layer, but wants to go directly to it's repeater first.
// if repeater item, then just return repeater
var scriptId = $ax.repeater.getScriptIdFromElementId(elementId); var itemNum = $ax.repeater.getItemIdFromElementId(elementId); var parentRepeater = $ax.getParentRepeaterFromScriptId(scriptId);
// scriptId is item or repeater itself
if (parentRepeater == scriptId) { // If you are repeater item, return your repeater
if (itemNum) return filter.indexOf('repeater') != -1 ? scriptId : getParent(scriptId); // Otherwise you are actually at repeater, clean parentRepeater, or else you loop
parentRepeater = undefined; }
// Layer only references it if it is a direct layer to it
var parent = $ax.getLayerParentFromElementId(elementId); // If layer is allowed we found parent, otherwise ignore and keep climbing
if (parent) return filter.indexOf('layer') != -1 ? parent : getParent(parent); // if state, then just return panel
if(scriptId.indexOf('_state') != -1) { var panelId = $ax.repeater.createElementId(scriptId.split('_')[0], itemNum); // If dynamic panel is allowed we found parent, otherwise ignore and keep climbing
return filter.indexOf('dynamicPanel') != -1 ? panelId : getParent(panelId); }
var parentType = ''; if(parentRepeater) { parentType = 'item'; parent = $ax.repeater.createElementId(parentRepeater, itemNum); }
var masterPath = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(elementId)); masterPath.pop(); if(masterPath.length > 0) { var masterId = $ax.getElementIdFromPath(masterPath, { itemNum: itemNum }, true); if(!masterId) return undefined; var masterRepeater = $ax.getParentRepeaterFromElementId($ax.repeater.getScriptIdFromElementId(masterId)); if(!parentRepeater || masterRepeater) { parentType = 'rdo'; parent = masterId; } }
var obj = $obj(elementId); var parentDynamicPanel = obj.parentDynamicPanel; if(parentDynamicPanel) { // Make sure the parent if not parentRepeater, or dynamic panel is also in that repeater
// If there is a parent master, the dynamic panel must be in it, otherwise parentDynamicPanel would be undefined.
var panelPath = masterPath; panelPath[panelPath.length] = parentDynamicPanel; panelId = $ax.getElementIdFromPath(panelPath, { itemNum: itemNum }, true); if(!panelId) return undefined; var panelRepeater = $ax.getParentRepeaterFromElementId(panelId); if(!parentRepeater || panelRepeater) { parentType = 'state'; parent = panelId + '_state' + obj.panelIndex; } }
// If at top or parent type is desired, then return parent, otherwise keep climbing
return !parent || filter.indexOf(parentType) != -1 ? parent : getParent(parent); };
for(var i = 0; i < elementIds.length; i++) { var parent = getParent(elementIds[i]); if(deep) { var parents = []; while(parent) { parents[parents.length] = parent; // If id is not a valid object, you are either repeater item or dynamic panel state
//if(!$obj(parent)) parent = $ax.visibility.getWidgetFromContainer($jobj(parent).parent().attr('id'));
parent = getParent(parent); } parent = parents; } parentIds[parentIds.length] = parent; } return parentIds; };
// Get the path to the child, where non leaf nodes can be masters, layers, dynamic panels, and repeaters.
$ax.public.fn.getChildren = function(deep, ignoreUnplaced) { // ignoreUnplaced should probably be the default, but when that is done a full audit of usages should be done
var elementIds = this.getElementIds(); var children = [];
var getChildren = function (elementId) { var obj = $obj(elementId); //if(!obj) return undefined;
var isRepeater = obj && obj.type == $ax.constants.REPEATER_TYPE; if (isRepeater && $ax.repeater.getScriptIdFromElementId(elementId) != elementId) { //prevent repeater items from being marked as isRepeater
//TODO: evaluate changing the naming convention to be more like panel states which don't seem to have this problem
obj = undefined; isRepeater = false; } var isDynamicPanel = obj && obj.type == $ax.constants.DYNAMIC_PANEL_TYPE; //var isLayer = obj.type == $ax.constants.LAYER_TYPE;
//var isMaster = obj.type == $ax.constants.MASTER_TYPE || obj.type == $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE;
var isMenu = obj && obj.type == $ax.constants.MENU_OBJECT_TYPE; var isTreeNode = obj && obj.type == $ax.constants.TREE_NODE_OBJECT_TYPE; //var isTable = obj.type == $ax.constants.TABLE_TYPE;
//var isCompoundVector = obj.type == $ax.constants.VECTOR_SHAPE_TYPE && obj.generateCompound;
//if (isRepeater || isDynamicPanel || isLayer || isMaster || isMenu || isTreeNode || isTable) {// || isCompoundVector) {
// Find parent that children should be pulled from. Default is just the elementId query (used by table and master)
var parent = $jobj(elementId); if(isRepeater) { parent = $(); var itemIds = $ax.getItemIdsForRepeater(elementId); for(var itemIndex = 0; itemIndex < itemIds.length; itemIndex++) parent = parent.add($jobj($ax.repeater.createElementId(elementId, itemIds[itemIndex]))); } else if(isDynamicPanel) { // Really only need to do active state probably...
parent = $jobj(elementId).children(); // Get through all containers
while ($(parent[0]).attr('id').indexOf('container') != -1) parent = parent.children(); // Now at states, but want states content
parent = parent.children(); } else if(isTreeNode) parent = $jobj($ax.repeater.applySuffixToElementId(elementId, '_children'));
// Menu doesn't want all children, only tables and menus, so it must be handled specially
var children = isMenu ? parent.children('.ax_table').add(parent.children('.ax_menu')) : parent.children(); children = $ax.visibility.getRealChildren(_fixForBasicLinks(children)); // For tree nodes you want the the button shape contained by the elementQuery too
if(isTreeNode) { var treeNodeChildren = $jobj(elementId).children(); for(var treeNodeIndex = 0; treeNodeIndex < treeNodeChildren.length; treeNodeIndex++) { var treeNodeChild = $(treeNodeChildren[treeNodeIndex]); var childObj = $obj(treeNodeChild.attr('id')); if (childObj && $ax.public.fn.IsVector(childObj.type)) children = children.add(treeNodeChild); } }
var childrenIds = []; for(var childIndex = 0; childIndex < children.length; childIndex++) { var childObj = $(children[childIndex]); var id = childObj.attr('id'); if(typeof(id) == 'undefined' && childObj.is('a')) id = $(childObj.children()[0]).attr('id'); // Ignore annotations and any other children that are not elements
if (id.split('_').length > 1) continue; // Ignore Unplaced
if(ignoreUnplaced && $ax.visibility.isScriptIdLimbo($ax.repeater.getScriptIdFromElementId(id))) continue; childrenIds.push(id); } if(deep) { var childObjs = []; for(var i = 0; i < childrenIds.length; i++) { var childId = childrenIds[i]; childObjs[i] = { id: childId, children: getChildren(childId) }; } childrenIds = childObjs; } return childrenIds; //}
//return undefined;
};
for(var i = 0; i < elementIds.length; i++) { var elementId = elementIds[i]; //if the state is passed in, look for children in the content element
if (elementId.indexOf('_state') > -1 && elementId.indexOf('_content') < 0) elementId = elementId + '_content'; children[children.length] = { id: elementId, children: getChildren(elementId)}; } return children; };
var _fixForBasicLinks = function(query) { var hasBasicLinks = query.filter('.basiclink').length > 0; if(!hasBasicLinks) return query;
var retval = $(); for(var i = 0; i < query.length; i++) { var child = $(query[i]); if(child.hasClass('basiclink')) retval = retval.add(child.children()); else retval = retval.add(child); } return retval; };
})();
|