{"version":3,"sources":["_layouts/core/cart/cart.js","_layouts/core/cart/cartitem.js","_layouts/core/cart/cartlist.js","_layouts/core/cart/cartwindow.js"],"names":["Librarian","Cart","Class","Binds","onUpdateFn","cartItems","displayMode","requests","expansions","sections","downloadWindow","initialize","defaultDisplayMode","onUpdate","this","displayModes","MIXED_VIEW","SLIDE_VIEW","List","save","cart","saveCartToServer","saveCart","close","pageHeader","updateCartButton","getCount","slideCount","includeDeleted","includeDuplicates","showDuplicates","count","i","length","getSize","item","items","deleted","getCartFiles","getItems","addTypes","FILE","getCartSlides","SLIDE","getCartItems","getSectionItems","index","forceMixed","getDisplayItems","sectionItems","section","push","getSectionSlides","getSectionsList","sectionList","Object","clone","getItem","getItemFromData","data","ignoreGroup","getItemIndex","indexOf","getTriggerItems","ruleGroup","getRuleItems","getDependentItems","getIntegrityItems","getGroupingItems","getOrderingItems","getMandatoryItems","ruleType","filter","toCapitalCase","getRuleGroupItems","getPositionedItems","position","cartPosition","canAddToCart","notify","contentRule","parentfields","Utils","isSourceNotAvailable","maxItems","showSlideCount","slideid","slidecount","blockAddWhenFull","error","Lang","getString","notification","isFull","isInCart","checkSubItems","isPassworded","flags","fileFlags","passwordProtected","tileList","expandGroupItemsToSlides","itemcount","slidenumber","slides","childCount","isChildOf","enableGroupRules","doesItemHaveGroupRules","groupid","presid","fileid","addType","allowDuplicates","duplicate","equals","contains","parentItem","getParentOrItemItself","subItems","isInSlideView","isInMixedView","hasItemWithExtension","ext","checkChildren","trim","toLowerCase","hasItem","getExtensionFromData","hasPowerPointItem","extensions","isPowerPointFile","hasRuleGroupItem","cartItem","predicate","some","child","hasSlides","original","type","originalAddType","hasEditedItems","editsXML","editFileName","hasItemWithMetaValue","metaName","value","extraFields","extrafields","addSection","name","description","allowDuplicateSections","sectionIndex","len","updateSection","removeSection","removeSlides","remove","removeFromCart","prevIndex","Math","max","swapSections","from","to","fromSection","fromItems","toSection","toItems","indexOfSection","setItemSection","splitFileAndAddInPlace","getLastSectionIndex","addToCart","fromCart","update","fromRules","onComplete","addToCartEx","expand","itemnumber","isslideshow","expandGroupRuleItems","Item","removeItemChildren","addItem","expandItem","addRules","onChange","openCartOnAdd","cartWindow","isVisible","Library","openCartWindow","insertBefore","targetData","onInsert","itemIndex","$empty","parent","makeParent","indexOfParent","itemSize","isNaN","setAddType","doInsertBefore","pass","canInsert","insertItemAt","onRemove","onRemoveFail","canRemove","doRemoveFromCart","removeAutomaticallyAddedItemsOnly","setItemDeleted","removeItem","updateDuplicateState","updateAllCheckboxes","removeAllDeleted","fileInGroup","features","fastlane","load","FastLane","isEnabled","hasFakeSlides","insert","onRulesLoaded","onAdd","request","getItemRules","expandVirtualToSlides","expandGroupToSlides","expandFileToSlides","url","path","getMethodUrl","search","viewNameByType","Search","outputTypes","SLIDES","expandToSlides","FILES","self","Request","JSON","onSuccess","json","expandLoadComplete","onFailure","send","clearRequest","childItem","parentext","duplicates","setParentFields","showMyFavoriteName","showGlobalFavoriteName","sourceext","isDependent","isTrigger","isIntegrity","isOrdering","isGrouping","orderindex","rules","userCart","clear","cancel","changeView","view","previewWindows","disableNavButtons","moveItem","firstItem","secondItem","oldLoc","canMove","onMove","printRulesDebug","window","console","log","isMandatory","extend","CATEGORY","openCart","onVPCreatedFn","onVPCatCreatedFn","mainPanel","loaded","isMinimized","restore","Window","show","closeCart","openCartFunction","method","param1","param2","param3","param4","param5","downloadCart","saveAsFavorite","sendCart","clearCart","onClear","confirm","ConfirmWindow","id","title","question","onFirstButtonClicked","doClear","textReplaces","eventType","oneOff","openSendWindow","EventSendWindow","clearCartOnSend","bind","canCombineShares","newsletter","CreatePackage","showNotification","clearOnSave","catid","Date","format","create","canSend","event","canShare","canSendItems","canSendItem","cartList","getUpdateUrl","fcont","encode","loadCart","reload","updateCreateWindow","parentContentId","contentType","file","contentId","slide","getRules","ruleItems","isdependent","istrigger","isintegrity","isordering","isgrouping","addFileGroupRulesFromSlide","contentid","contenttype","linkid","pagecount","filesize","fromWizard","filename","thumbnailid","fileUrl","catType","catId","prestype","virtPresType","undefined","isshared","hasedits","editable","hashData","filetypeextension","getHash","parseQueryString","cattype","updateIsMandatory","updatePosition","destroy","fields","size","isDataEqual","isRelatedTo","isParentOf","isLocNextToRuleGroupItem","targetItem","prevItem","hasMandatoryRuleChildren","undelete","doPositioning","thisItem","unshift","doPositionedRules","sortByOrder","insertAfter","getRulesLists","afterItems","list","thisIndex","sort","a","b","insertItemsAt","beforeList","afterList","beforeItems","doOrdering","doGrouping","nextItem","endItems","itemPositionMetaName","groupItems","lastSection","added","getItemPosition","getPluralArgString","destLoc","prev","found","isRuleItem","indexItem","hasRules","checkPosition","start","end","idx","destItem","currLoc","doCheck","forward","thisLoc","checkLoc","moved","previousItems","nextItems","offset","beforeIndex","afterIndex","abortRemoval","prompt","itemType","triggerSlides","doRemove","bypassPostRulesCheck","runRules","getItemType","message","getArgString","height","width","resize","defaultButton","onSecondButtonClicked","useThirdButton","useFourthButton","firstButtonText","secondButtonText","thirdButtonText","fourthButtonText","onThirdButtonClicked","onFourthButtonClicked","removeSlideList","itemValue","parentValue","mandatoryItemMetaName","currentItem","parentFile","parentIndex","childItems","append","j","setItem","removeItemByIndex","splice","includeSubItems","subLength","subItem","lastIndexOfChild","firstIndexOfChild","containsDeleted","dataItem","flag","func","hasDeleted","fromParent","toParent","Implements","Events","Extends","options","cartContainer","wrapperClass","toolbar","padding","top","right","bottom","left","maximizable","resizable","toolbarLoaded","toolbarInfo","collapsed","leftWidth","rightWidth","hasSections","createPackage","saveFavorite","onVPCreated","onVPCatCreated","dataOverride","setOptions","openAsModalWindow","updateTitle","getLayoutsPath","contentURL","toolbarURL","getLibraryPath","onResize","onMaximize","onRestore","setWindowPosition","toolbarWidth","buttonEls","menuLabelEls","enableLabelSquishing","toolbarEl","getWidth","leftBarEl","getElement","rightBarEl","getElements","hideButtonLabels","forEach","buttonEl","hasClass","addClass","label","removeClass","onToolbarLoaded","libraryPath","iconsPath","imageEl","parentEl","convertButtonsToMenu","buildCartMenu","getDefaultThemePath","$","src","addOnClick","updateCart","isUserMemberOfGroup","disableShareUserGroups","tagName","allowDisplaySwitch","alt","getParent","doRefresh","refreshSlideShowTree","slideshow","refreshSharedFavTree","sharedFavorite","refreshSharedSlideShowTree","sharedSlideshow","getCartViews","createViewDropdown","updateSendButtons","translateElements","windowEl","toolboxEl","menuWrapperEl","Element","class","inject","ulEl","liEl","linkEl","menuEl","text","createInMenu","itemEl","get","textEl","firstElementChild","bindSDDMMenus","menu","onWindowLoaded","useMinimizeAsReset","removeEvents","hasTouchSupport","onClose","doUpdate","closeWindow","cleanCartList","menuContainerEl","views","viewContainerEl","injectInside","viewListEl","triggerEl","selected","viewIndex","appendChild","document","createTextNode","set","onViewClick","e","setTileListSize","updateCheckboxes","getItemStyle","$$","setElementValue","hideText","className","evt","Event","target","endsWith","cancelOnUpdateCall","getUnCheckedElements","reloadThumbnails","contEl","empty","initCartList","reset","loadFromArray","SectionList","container","sectionClassPrefix","tileListStyle","allowDrag","allowEdit","allowHeaderDrag","targetList","TileList","itemStyle","onBeforeCreatePackage","windowOptions","createOptions","merge","showWindow","getWindow","MUI","centerWindow","updateOutputButtons","onBeforeSaveFavorite","defaultName","saveEmpty","MyFavorite","SaveWindow","presType","onCreated","onCatCreated","mode","windowDimensions","calcHeight","percent","defaultPosition","positions","center","getCoordinates","extraHeight","toolbarHeight","toolbar2","toolbar2Height","headerHeight","footerHeight","shadowBlur","y","parseInt","x","centered","showCountInTitle","getFittedTitle","sendEl","toggle","newsletterEl","style","visibility","setTextReplace","clearExisting","setExtraFields","setCreateOptions"],"mappings":"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","file":"_layouts\\core\\cart\\cart.bundle.min.js","sourcesContent":["Librarian.Cart = new Class({\r\n Binds: [\"onUpdate\", \"insertBefore\", \"doInsertBefore\"],\r\n\r\n // Fired when the cart is updated. Takes no arguments\r\n onUpdateFn: null,\r\n // List of items in the cart\r\n cartItems: null,\r\n // Current display mode. Defaults to MIXED_VIEW\r\n displayMode: 0,\r\n // Currently running expand requests\r\n requests: [],\r\n // IDs being expanded right now\r\n expansions: [],\r\n // User-defined sections in the cart\r\n sections: [],\r\n // The custom download window assigned to this cart\r\n downloadWindow: null,\r\n\r\n /*\r\n * Initializes an instance of the Cart object with the default display mode and onUpdate function provided\r\n *\r\n * defaultDisplayMode - The default view the cart will display its items in - Optional, defaults to MIXED_VIEW\r\n * onUpdate - A function to call when the cart is updated - Optional\r\n */\r\n initialize: function(defaultDisplayMode, onUpdate) {\r\n // If we're given a function as an onUpdate (as we should)\r\n // store it to be called later.\r\n if (typeof onUpdate == \"function\")\r\n this.onUpdateFn = onUpdate;\r\n\r\n // If we aren't given a default, use \"MIXED_VIEW\"\r\n if ((typeof defaultDisplayMode == \"undefined\") || (defaultDisplayMode == null))\r\n defaultDisplayMode = Librarian.Cart.displayModes.MIXED_VIEW;\r\n\r\n // Set up the default view\r\n if (defaultDisplayMode == Librarian.Cart.displayModes.SLIDE_VIEW)\r\n this.displayMode = Librarian.Cart.displayModes.SLIDE_VIEW;\r\n else\r\n this.displayMode = Librarian.Cart.displayModes.MIXED_VIEW;\r\n\r\n // Initialize the item lists\r\n this.cartItems = new Librarian.Cart.List();\r\n },\r\n\r\n /*\r\n * Called when any change happens in the cart with updates not explicitly disabled\r\n *\r\n * save - Whether to save the cart to the server (if that setting is enabled) - Optional, defaults to true\r\n */\r\n onUpdate: function(save) {\r\n // If saving isn't explicitly refused and we normally save cart changes to the server,\r\n // send the save request to the server\r\n if ((save !== false) && Librarian.cart.saveCartToServer)\r\n Librarian.Cart.saveCart();\r\n\r\n // If the cart changed, close the CreatePackage window\r\n // Doing this forces the window to be re-opened so all download rules can be reprocessed\r\n if (this.downloadWindow) {\r\n this.downloadWindow.close();\r\n this.downloadWindow = null;\r\n }\r\n\r\n // If a custom onUpdate was set, run that as well\r\n if (typeof this.onUpdateFn == \"function\")\r\n this.onUpdateFn();\r\n\r\n // Update the cart buttons in the PageHeader\r\n if (Librarian.pageHeader != null)\r\n Librarian.pageHeader.updateCartButton();\r\n },\r\n\r\n //#region Get Methods\r\n\r\n /*\r\n * Gets the count of the current number of items in the cart, based on the options provided\r\n *\r\n * slideCount - Gets the count of all the items in the cart expanded down to the slide level - Optional, defaults to false\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to the 'showDuplicates' setting value in Librarian.cart\r\n */\r\n getCount: function(slideCount, includeDeleted, includeDuplicates) {\r\n // If we aren't told Whether to do a slideCount, assume not.\r\n if ((typeof slideCount == \"undefined\") || (slideCount == null))\r\n slideCount = false;\r\n // If we aren't told Whether to include deleted items, assume not.\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n // If we aren't told Whether to include duplicate items, assume not.\r\n if ((typeof includeDuplicates == \"undefined\") || (includeDuplicates == null))\r\n includeDuplicates = Librarian.cart.showDuplicates;\r\n\r\n var count = 0;\r\n // Count each non-deleted item inline\r\n // This is slightly faster than using the cartItems.getSize method with its various options\r\n for (var i = 0, length = this.cartItems.getSize(); i < length; i++) {\r\n var item = this.cartItems.items[i];\r\n\r\n // Skip deleted items\r\n if ((includeDeleted === false) && item.deleted)\r\n continue;\r\n\r\n // Get the count of each item if we are being asked for slide count\r\n if (slideCount)\r\n count += item.getCount(includeDeleted, includeDuplicates);\r\n else\r\n count++;\r\n }\r\n\r\n return count;\r\n },\r\n\r\n /*\r\n * Gets the list of items in the cart in a forced-file view\r\n * This forces any slide that is added to the cart to be added to a fake parent File object\r\n *\r\n * This is currently not used as it is very unintuitive - Showing a File object which isn't the full file confuses pretty much everyone\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getCartFiles: function(includeDeleted, includeDuplicates) {\r\n return this.cartItems.getItems(includeDeleted, Librarian.Cart.addTypes.FILE, includeDuplicates);\r\n },\r\n\r\n /*\r\n * Gets the list of items in the cart in a forced-slide view.\r\n * This forces any group or file that is added to the cart to be expanded and show its individual slides\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getCartSlides: function(includeDeleted, includeDuplicates) {\r\n return this.cartItems.getItems(includeDeleted, Librarian.Cart.addTypes.SLIDE, includeDuplicates);\r\n },\r\n\r\n /*\r\n * Gets the list of items in the cart in a view that shows exactly how they were added\r\n * Files added to the cart are shown as File objects, Groups as Group objects, Slides as Slide objects, etc\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getCartItems: function(includeDeleted, includeDuplicates) {\r\n return this.cartItems.getItems(includeDeleted, null, includeDuplicates);\r\n },\r\n\r\n /*\r\n * Gets the list of items in the section as specified by the given index\r\n *\r\n * index - The index of the section for which to get the list of items\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * forceMixed - Whether to force the items in the section in to MIXED display mode - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getSectionItems: function(index, includeDeleted, forceMixed, includeDuplicates) {\r\n var items;\r\n // Only get mixed items if we're told to\r\n // This is used by CreatePackage to get what was added to the cart, exactly\r\n if (forceMixed === true)\r\n items = this.getCartItems(includeDeleted, includeDuplicates);\r\n else\r\n items = this.getDisplayItems(includeDeleted, includeDuplicates);\r\n\r\n var sectionItems = [];\r\n // Get every item whose set index matches the given index\r\n for (var i = 0; i < items.length; i++) {\r\n if (items[i].section == index)\r\n sectionItems.push(items[i]);\r\n }\r\n\r\n return sectionItems;\r\n },\r\n\r\n /*\r\n * Gets the list of slides in the section as specified by the given index\r\n *\r\n * index - The index of the section for which to get the list of items\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getSectionSlides: function (index, includeDeleted, includeDuplicates) {\r\n var items = this.getCartSlides(includeDeleted, includeDuplicates);\r\n\r\n var sectionItems = [];\r\n // Get every item whose set index matches the given index\r\n for (var i = 0; i < items.length; i++) {\r\n if (items[i].section == index)\r\n sectionItems.push(items[i]);\r\n }\r\n\r\n return sectionItems;\r\n },\r\n\r\n /*\r\n * Gets the list of sections in the cart with their list of items included\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getSectionsList: function(includeDeleted, includeDuplicates) {\r\n var sectionList = [];\r\n for (var i = 0; i < this.sections.length; i++) {\r\n var section = Object.clone(this.sections[i]);\r\n section.items = this.getSectionItems(i, includeDeleted, includeDuplicates);\r\n sectionList.push(section);\r\n }\r\n\r\n return sectionList;\r\n },\r\n\r\n /*\r\n * Gets the list of items in the cart in the currently set display mode\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getDisplayItems: function(includeDeleted, includeDuplicates) {\r\n // Return the current list of items based on how the cart is displaying.\r\n if (this.displayMode == Librarian.Cart.displayModes.SLIDE_VIEW)\r\n return this.getCartSlides(includeDeleted, includeDuplicates);\r\n else if (this.displayMode == Librarian.Cart.displayModes.MIXED_VIEW)\r\n return this.getCartItems(includeDeleted, includeDuplicates);\r\n else\r\n return this.getCartFiles(includeDeleted, includeDuplicates);\r\n },\r\n\r\n /*\r\n * Gets the data stored at the given index within the cart\r\n *\r\n * index - The location from which to get data\r\n */\r\n getItem: function(index) {\r\n return this.cartItems.getItem(index);\r\n },\r\n\r\n /*\r\n * Gets the cart item that represents the given data\r\n *\r\n * data - The data to find the representational cart item for\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n getItemFromData: function(data, includeDeleted, ignoreGroup) {\r\n var index = this.getItemIndex(data, includeDeleted, ignoreGroup);\r\n if (index < 0)\r\n return null;\r\n return this.getItem(index);\r\n },\r\n\r\n /*\r\n * Gets the index of the given item in the cart\r\n *\r\n * item - Item for which to find the current location within the cart\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n getItemIndex: function(item, includeDeleted, ignoreGroup) {\r\n return this.cartItems.indexOf(item, includeDeleted, ignoreGroup);\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group and are a trigger\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getTriggerItems: function(ruleGroup, includeDeleted) {\r\n return this.getRuleItems(ruleGroup, \"trigger\", includeDeleted);\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group and are a dependent\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getDependentItems: function(ruleGroup, includeDeleted) {\r\n return this.getRuleItems(ruleGroup, \"dependent\", includeDeleted);\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group and are an integrity item\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getIntegrityItems: function(ruleGroup, includeDeleted) {\r\n return this.getRuleItems(ruleGroup, \"integrity\", includeDeleted);\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group and are a grouping item\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getGroupingItems: function(ruleGroup, includeDeleted) {\r\n return this.getRuleItems(ruleGroup, \"grouping\", includeDeleted);\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group and are an ordering item\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getOrderingItems: function(ruleGroup, includeDeleted) {\r\n return this.getRuleItems(ruleGroup, \"ordering\", includeDeleted);\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group and are a mandatory item\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getMandatoryItems: function(ruleGroup, includeDeleted) {\r\n return this.getRuleItems(ruleGroup, \"mandatory\", includeDeleted);\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group and are an item of the given Rule type\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * ruleType - The type of Rule item that should be found\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getRuleItems: function(ruleGroup, ruleType, includeDeleted) {\r\n return this.cartItems.filter(function(item) {\r\n return ((item.ruleGroup == ruleGroup) && item[\"is\" + ruleType.toCapitalCase()] && ((includeDeleted === true) || !item.deleted));\r\n });\r\n },\r\n\r\n /*\r\n * Gets all items in the cart that are in the given Rule Group\r\n *\r\n * ruleGroup - ID of the Rule Group to which the found items should belong\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getRuleGroupItems: function(ruleGroup, includeDeleted) {\r\n return this.cartItems.filter(function(item) {\r\n return ((item.ruleGroup == ruleGroup) && ((includeDeleted === true) || !item.deleted));\r\n });\r\n },\r\n\r\n /*\r\n * Gets all items in the cart with the given fixed position setting\r\n *\r\n * position - The fixed position setting value that should be found, if null then all fixed position items will be found\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n getPositionedItems: function(position, includeDeleted) {\r\n return this.cartItems.filter(function(item) {\r\n return ((!position && (item.cartPosition != null)) || (item.cartPosition == position)) && ((includeDeleted === true) || !item.deleted);\r\n });\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Boolean Methods\r\n\r\n /*\r\n * Determines whether the data provided is able to be added to the cart\r\n *\r\n * data - Data to be added to the cart\r\n * notify - Whether to display the \"Cart is Full\" message when it is applicable - Optional, defaults to true\r\n */\r\n canAddToCart: function(data, notify) {\r\n if (!data)\r\n return false;\r\n\r\n // If InternalUseOnly is enabled and should prevent these items from going in the cart, check to make sure this item is not IUO\r\n if (!Librarian.contentRule.canAddToCart(data, null, null, null, null, data.parentfields)) {\r\n return false;\r\n }\r\n\r\n // If this is an invalid item, it's not allowed in the cart\r\n if (Librarian.Utils.isSourceNotAvailable(data))\r\n return false;\r\n\r\n // If the cart limit is disabled, we're done checking if the data can go in the cart\r\n if (Librarian.cart.maxItems <= 0)\r\n return true;\r\n\r\n // Check the cart count against the cart size limit\r\n var count = this.getCount(Librarian.cart.showSlideCount, true);\r\n count += (data.slideid > 0) ? 1 : (Librarian.cart.showSlideCount) ? (data.slidecount || 1) : 1;\r\n\r\n if (count <= Librarian.cart.maxItems)\r\n return true;\r\n\r\n // Only block adding to the cart when the setting is enabled\r\n if (Librarian.cart.blockAddWhenFull) {\r\n if (notify !== false)\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_full\"));\r\n return false;\r\n }\r\n // Otherwise, just notify the user\r\n else {\r\n if (notify !== false)\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_full_warning\"));\r\n return true;\r\n }\r\n },\r\n\r\n /*\r\n * Determines whether the cart count is currently at or past the cart limit\r\n */\r\n isFull: function() {\r\n if (Librarian.cart.maxItems <= 0)\r\n return false;\r\n\r\n return this.getCount(Librarian.cart.showSlideCount, true) >= Librarian.cart.maxItems;\r\n },\r\n\r\n /*\r\n * Determines whether the given data is already in the cart\r\n *\r\n * data - Data to check for presence in the cart\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, determines automatically based on file presence in groups\r\n */\r\n isInCart: function(data, includeDeleted, includeDuplicates, ignoreGroup, checkSubItems) {\r\n if (!data)\r\n return false;\r\n\r\n // If this is an invalid item, it's not allowed in the cart\r\n if (Librarian.Utils.isSourceNotAvailable(data))\r\n return false;\r\n\r\n var isPassworded = ((data.flags & Librarian.fileFlags.passwordProtected) == Librarian.fileFlags.passwordProtected),\r\n slideCount = data.slidecount;\r\n // Use the item count if it has one and we're not expanding groups\r\n if (!Librarian.tileList.expandGroupItemsToSlides && (data.itemcount > 0))\r\n slideCount = data.itemcount;\r\n\r\n // If this is a non-passworded file being checked and it has slides (IE, it's not a video)\r\n if (!isPassworded && (slideCount > 0) && (data.slidenumber <= 0)) {\r\n var slides = this.getCartSlides(includeDeleted),\r\n childCount = 0;\r\n\r\n // Check to see if all of its child slides are in the cart\r\n for (var i = slides.length; i--;) {\r\n if (slides[i].isChildOf(data))\r\n childCount++;\r\n }\r\n\r\n // If they are, this file is in the cart\r\n if ((childCount > 0) && (childCount >= slideCount))\r\n return true;\r\n }\r\n\r\n // If ignoreGroup isn't provided, calculate it based on some complicated conditions\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null)) {\r\n // If we have group rules enabled try to find if this item exists in the cart as part of a rule group\r\n // If it does, ignore the group information when checking if it's in the cart so that\r\n // the file and the group both show the items as checked\r\n if (Librarian.cart.enableGroupRules)\r\n ignoreGroup = this.doesItemHaveGroupRules(data);\r\n // If this is a file inside a group, don't add it to the parent group if there is one\r\n // Fixes a case where adding a file from inside a group would mark each subsequent file in the group as already in the cart\r\n else\r\n ignoreGroup = ((data.groupid > 0) || (data.presid > 0)) && (data.slideid <= 0) && (data.fileid > 0);\r\n }\r\n\r\n // Get the index of this item\r\n var index = this.cartItems.indexOf(data, includeDeleted, ignoreGroup);\r\n\r\n // If this item is in the cart, check if it is full\r\n if (index >= 0) {\r\n var item = this.cartItems.items[index];\r\n\r\n // If this item is a slide, this is it\r\n if (item.addType == Librarian.Cart.addTypes.SLIDE)\r\n return true;\r\n // If item is a file and the file is in the cart, this is it\r\n if (data.slideid <= 0 && item.slideid <= 0)\r\n return true;\r\n // Otherwise, if this item has every slide or it is password protected, it is marked as being in the cart\r\n else if ((item.slidecount == item.getSize(includeDeleted)) || isPassworded)\r\n return true;\r\n }\r\n\r\n // If we don't allow duplicates, check this item vs. every item and every item's children\r\n if (!Librarian.cart.allowDuplicates) {\r\n var items = this.getCartItems(includeDeleted);\r\n for (var i = items.length; i--;) {\r\n if (((!items[i].duplicate || (includeDuplicates !== false)) && items[i].equals(data, ignoreGroup)) || items[i].contains(data, null, ignoreGroup, includeDuplicates))\r\n return true;\r\n }\r\n }\r\n\r\n // If it isn't, try to get the parent item.\r\n var parentItem = this.cartItems.getParentOrItemItself(data);\r\n\r\n // If there is a parent item\r\n if (parentItem) {\r\n // Check if it has this item as a child slide.\r\n // Only allow deleted if we are supposed to.\r\n return parentItem.contains(data, includeDeleted);\r\n }\r\n\r\n if (checkSubItems) {\r\n return this.checkSubItems(this.cartItems.items, data);\r\n }\r\n\r\n // If there isn't a parent, or it doesn't have this child,\r\n // it's obviously not in the cart.\r\n return false;\r\n },\r\n /*\r\n check if sub items, ex items inside a GF, are in cart \r\n */\r\n checkSubItems: function(subItems, data) {\r\n var contains = false;\r\n for (var i = subItems.length; i--;) {\r\n if (subItems[i].contains(data, null, true))\r\n contains = true;\r\n }\r\n return contains;\r\n },\r\n\r\n /*\r\n * Determines whether the cart is currently in SLIDE display mode\r\n */\r\n isInSlideView: function() {\r\n return this.displayMode == Librarian.Cart.displayModes.SLIDE_VIEW;\r\n },\r\n\r\n /*\r\n * Determines whether the cart is currently in MIXED display mode\r\n */\r\n isInMixedView: function() {\r\n return this.displayMode == Librarian.Cart.displayModes.MIXED_VIEW;\r\n },\r\n\r\n /*\r\n * Determines whether the cart has an item in it with the given extension\r\n *\r\n * ext - The extension to search for in the cart\r\n * checkChildren - Whether to check the child items inside each cart item - Optional, defualts to false\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n */\r\n hasItemWithExtension: function(ext, checkChildren, includeDeleted) {\r\n ext = (ext || '').trim().toLowerCase();\r\n if (ext.length == 0)\r\n return false;\r\n\r\n return this.hasItem(checkChildren, includeDeleted, function(item) {\r\n return Librarian.Utils.getExtensionFromData(item, true) == ext;\r\n });\r\n },\r\n\r\n /*\r\n * Determines whether the cart has a PowerPoint item in it\r\n *\r\n * checkChildren - Whether to check the child items inside each cart item - Optional, defualts to false\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n */\r\n hasPowerPointItem: function(checkChildren, includeDeleted) {\r\n return this.hasItem(checkChildren, includeDeleted, function(item) {\r\n return Librarian.extensions.isPowerPointFile(Librarian.Utils.getExtensionFromData(item, true));\r\n });\r\n },\r\n\r\n /*\r\n * Determines whether the cart has an item within the given Cart Rules group\r\n *\r\n * cartItem - The cart item for which other items in the same Cart Rules group are being sought\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n */\r\n hasRuleGroupItem: function(cartItem, includeDeleted) {\r\n return this.hasItem(false, includeDeleted, function(item) {\r\n return !item.equals(cartItem) && (item.ruleGroup == cartItem.ruleGroup);\r\n });\r\n },\r\n\r\n /*\r\n * Determines if the data given has a representation cart item that is in a Cart Rules group\r\n *\r\n * data - The data for which a the representational cart item will be founed and checked for the presence of a Cart Rules group\r\n */\r\n doesItemHaveGroupRules: function(data) {\r\n if (Librarian.cart.enableGroupRules) {\r\n var cartItem = this.getItemFromData(data, true, true);\r\n if (cartItem && (cartItem.ruleGroup > 0))\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n /*\r\n * Determines whether the cart has an item in it that matches the given predicate\r\n *\r\n * checkChildren - Whether to check the child items inside each cart item - Optional, defualts to false\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n * predicate - Boolean function which checks whether the given item matches a set of search criteria\r\n */\r\n hasItem: function(checkChildren, includeDeleted, predicate) {\r\n // If there is no predicate, nothing can match it\r\n if (typeof predicate != \"function\")\r\n return false;\r\n\r\n if ((typeof checkChildren == \"undefined\") || (checkChildren == null))\r\n checkChildren = false;\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = true;\r\n\r\n return this.cartItems.some(function(item) {\r\n // Don't bother checking an item or its children if it's delted and eleted items are not allowed\r\n if ((includeDeleted === false) && item.deleted)\r\n return false;\r\n\r\n // Check this item or its children (if that option is enabled) against the given predicate\r\n return predicate(item) ||\r\n checkChildren && item.getItems(includeDeleted).some(function(child) {\r\n return predicate(child);\r\n });\r\n });\r\n },\r\n\r\n /*\r\n * Determines whether the cart has any Slide items in it\r\n *\r\n * original - Whether to check the original Add Type vs. the current Add Type (This applies when an item is added as File and then split into Slides during a move operation)\r\n * predicate - Boolean function which checks whether the given item matches a set of search criteria - Optional and used in addition to the Slide type check\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n */\r\n hasSlides: function(original, predicate, includeDeleted) {\r\n return this.hasItem(false, includeDeleted, function(item) {\r\n var type = item.addType;\r\n if ((original === true) && (item.originalAddType != null))\r\n type = item.originalAddType;\r\n return (type === Librarian.Cart.addTypes.SLIDE) && ((typeof predicate != \"function\") || predicate(item));\r\n });\r\n },\r\n\r\n /*\r\n * Determines whether the cart has any edited items in it\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n */\r\n hasEditedItems: function(includeDeleted) {\r\n return this.hasItem(false, includeDeleted, function(item) {\r\n // An \"edited\" item requires both edit XML and an edited thumbnail\r\n return ((typeof item.editsXML == \"string\") && (item.editsXML.length > 0) &&\r\n (typeof item.editFileName == \"string\") && (item.editFileName.length > 0));\r\n });\r\n },\r\n\r\n /*\r\n * Determines whether the cart has any items in it with meta values that match the given name and value\r\n *\r\n * metaName - The name of the attribute to check the value of\r\n * value - The value of the attribute to check against\r\n * checkChildren - Whether to check the child items inside each cart item - Optional, defualts to false\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n */\r\n hasItemWithMetaValue: function(metaName, value, checkChildren, includeDeleted) {\r\n var value = (value || '').trim().toLowerCase();\r\n return this.hasItem(checkChildren, includeDeleted, function(item) {\r\n var extraFields = item.extrafields;\r\n if (!extraFields || !extraFields[metaName])\r\n extraFields = item.parentfields;\r\n\r\n return extraFields && extraFields[metaName] && ((extraFields[metaName] || '').trim().toLowerCase() == value);\r\n });\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Sections\r\n\r\n /*\r\n * Adds a new section to the list of sections in the cart\r\n *\r\n * name - Name of the new section to be added - Optional, defaults to a translateable value named 'section_defaultname'\r\n * description - Description of the new section to be added - Optional\r\n */\r\n addSection: function(name, description) {\r\n if ((typeof name == \"undefined\") || (name == null))\r\n name = Librarian.Lang.getString(\"section_defaultname\");\r\n\r\n // If adding duplicate sections is disabled, return the duplicate section index\r\n if (!Librarian.cart.allowDuplicateSections) {\r\n var sectionIndex = -1;\r\n for (var i = 0, len = this.sections.length; i < len; i++) {\r\n if (this.sections[i].name == name) {\r\n sectionIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (sectionIndex >= 0) {\r\n return sectionIndex;\r\n }\r\n }\r\n\r\n return this.sections.push({ name: name, description: description || ''}) - 1;\r\n },\r\n\r\n /*\r\n * Updates the name and description of the section represented by the given index\r\n *\r\n * index - The index of the section to update\r\n * name - Name to be set on the existing section - Optional, defaults to a translateable value named 'section_defaultname'\r\n * description - Description to be set on the existing section - Optional\r\n */\r\n updateSection: function(index, name, description) {\r\n if ((index < 0) || (index >= this.sections.length))\r\n return;\r\n\r\n if ((typeof name == \"undefined\") || (name == null))\r\n name = Librarian.Lang.getString(\"section_defaultname\");\r\n\r\n this.sections[index] = { name: name, description: description };\r\n },\r\n\r\n /*\r\n * Removes a section by index\r\n *\r\n * index - The index of the section to remove\r\n * removeSlides - Whether to remove the section content - Optional, defaults to false\r\n */\r\n removeSection: function(index, removeSlides) {\r\n if ((index < 0) || (index >= this.sections.length))\r\n return;\r\n\r\n // Save the section so we can handle its slides\r\n var section = this.sections[index];\r\n // Remove it from the sections list\r\n this.sections.remove(index);\r\n\r\n // Find all items with section = index\r\n var items = this.getSectionItems(index, true);\r\n if (removeSlides == true) {\r\n // Remove each one from the cart\r\n for (var i = items.length; i--;)\r\n this.removeFromCart(items[i], false, false, true);\r\n }\r\n // If this is a valid section and there are other sections\r\n else if (section && (this.sections.length > 0)) {\r\n // Get the previous section and it's items\r\n var prevIndex = Math.max(0, index - 1);\r\n if (prevIndex != index) {\r\n // Reset the section for all the found items to prevIndex\r\n for (var i = items.length; i--;)\r\n items[i].section = prevIndex;\r\n }\r\n }\r\n\r\n // Go through each remaining section and decrease their indeces by one\r\n // to fill the gap left by the section we just removed\r\n while (++index < (this.sections.length + 1)) {\r\n items = this.getSectionItems(index, true);\r\n var prevIndex = Math.max(0, index - 1);\r\n\r\n for (var i = items.length; i--;)\r\n items[i].section = prevIndex;\r\n }\r\n },\r\n\r\n /*\r\n * Swaps sections at the given indeces\r\n *\r\n * from - The index of the section being moved\r\n * to - The index of the destination of the section being moved\r\n */\r\n swapSections: function(from, to) {\r\n if ((from < 0) || (from >= this.sections.length))\r\n return false;\r\n if ((to < 0) || (to >= this.sections.length))\r\n return false;\r\n\r\n // Get the sections and their items\r\n var fromSection = Object.clone(this.sections[from]),\r\n fromItems = this.getSectionItems(from, true),\r\n toSection = Object.clone(this.sections[to]),\r\n toItems = this.getSectionItems(to, true);\r\n\r\n // Swap the sections\r\n this.sections[from] = toSection;\r\n this.sections[to] = fromSection;\r\n\r\n // Swap their items\r\n for (var i = fromItems.length; i--;)\r\n fromItems[i].section = to;\r\n for (var i = toItems.length; i--;)\r\n toItems[i].section = from;\r\n\r\n return true;\r\n },\r\n\r\n /*\r\n * Finds the index of a section in the cart by name\r\n *\r\n * name - The name of the section to find the index of\r\n */\r\n indexOfSection: function(name) {\r\n for (var i = 0; i < this.sections.length; i++) {\r\n if (this.sections[i].name == name)\r\n return i;\r\n }\r\n\r\n return -1;\r\n },\r\n\r\n /*\r\n * Sets the section number of the cart item represented by the given data\r\n *\r\n * data - The data whose representitive cart item's section number is being set\r\n * section - The index of the section to set on the data's cart item\r\n */\r\n setItemSection: function(data, section) {\r\n if (!data)\r\n return;\r\n\r\n var index = this.cartItems.indexOf(data);\r\n\r\n // If the item wasn't found, see if we have it's parent instead\r\n if (index < 0) {\r\n var parentItem = this.cartItems.getParentOrItemItself(data);\r\n // If we do, split the parent into its slides and get the index of the item\r\n if (parentItem) {\r\n this.cartItems.splitFileAndAddInPlace(parentItem);\r\n index = this.cartItems.indexOf(data);\r\n }\r\n else\r\n return;\r\n }\r\n\r\n // If we still don't have a valid index, stop trying\r\n if (index < 0)\r\n return;\r\n\r\n // Get the item and its children\r\n var item = this.cartItems.getItem(index),\r\n items = item.getItems(true);\r\n\r\n // Set the section on everything\r\n item.section = section;\r\n for (var i = items.length; i--;)\r\n items[i].section = section;\r\n },\r\n\r\n /*\r\n * Gets the index of the last section in the cart\r\n * Used when trying to automatically add things to the end of the cart\r\n */\r\n getLastSectionIndex: function() {\r\n return this.sections.length - 1;\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Add/Remove\r\n\r\n /*\r\n * Adds the provided data to the cart\r\n *\r\n * data - Data to be added to the cart\r\n * fromCart - Whether the request to add this item is coming from within the cart. Controls whether the cart window's contents are updated automatically - Optional, defaults to false\r\n * update - Whether to run the update function after this operation is complete - Optional, defaults to true\r\n * section - The index of the section to add this new item to - Optional, defaults to 0\r\n * fromRules - Whether to bypass the \"allowed\" checks because this is from group rules - Optional, defaults to false\r\n * onComplete - Callback to call once the item has been added - Optional\r\n *\r\n * Returns whether the item was added to the cart successfully\r\n */\r\n addToCart: function(data, fromCart, update, section, fromRules, onComplete) {\r\n return this.addToCartEx(data, fromCart, update, section, fromRules, onComplete) != null;\r\n },\r\n\r\n /*\r\n * Adds the provided data to the cart\r\n *\r\n * data - Data to be added to the cart\r\n * fromCart - Whether the request to add this item is coming from within the cart. Controls whether the cart window's contents are updated automatically - Optional, defaults to false\r\n * update - Whether to run the update function after this operation is complete - Optional, defaults to true\r\n * section - The index of the section to add this new item to - Optional, defaults to 0\r\n * fromRules - Whether to bypass the \"allowed\" checks because this is from group rules - Optional, defaults to false\r\n * onComplete - Callback to call once the item has been added - Optional\r\n *\r\n * Returns the item that was added to the cart successfully or null if it wasn't\r\n */\r\n addToCartEx: function(data, fromCart, update, section, fromRules, onComplete) {\r\n if ((typeof fromRules == \"undefined\") || (fromRules == null))\r\n fromRules = false;\r\n\r\n // Don't allow this item to be added to the cart if it violates Librarian rules\r\n if (!fromRules && !Librarian.cart.canAddToCart(data))\r\n return null;\r\n\r\n // Don't allow more items to be added to the cart if it is full.\r\n if (!fromRules && !this.canAddToCart(data))\r\n return null;\r\n\r\n if ((typeof fromCart == \"undefined\") || (fromCart == null))\r\n fromCart = false;\r\n if ((typeof update == \"undefined\") || (update == null))\r\n update = true;\r\n // Default to the first section if we're not given another one\r\n if ((typeof section == \"undefined\") || (section == null))\r\n section = 0;\r\n\r\n var expand = false;\r\n // If this is an item, add it straight to the cart and expand\r\n if (((data.slidenumber == null) || (data.slidenumber <= 0)) && (Librarian.tileList.expandGroupItemsToSlides || (data.itemnumber == null))) {\r\n if (data.addType == null)\r\n data.addType = Librarian.Cart.addTypes.FILE;\r\n\r\n expand = (data.isslideshow !== true) && ((data.flags & Librarian.fileFlags.passwordProtected) != Librarian.fileFlags.passwordProtected);\r\n }\r\n // Otherwise mark this is a a slide if it doesn't have an addType already\r\n else if (data.addType == null)\r\n data.addType = Librarian.Cart.addTypes.SLIDE;\r\n\r\n // Make sure we reset the deleted flag so this can actually be added\r\n data.deleted = false;\r\n\r\n // Don't expand items added from group rules\r\n if (fromRules && !Librarian.cart.expandGroupRuleItems)\r\n expand = false;\r\n\r\n // Create an item out of the data\r\n var item = new Librarian.Cart.Item(data);\r\n // If this is a file or group, remove the slides that are already in the cart\r\n if (expand)\r\n this.cartItems.removeItemChildren(item);\r\n\r\n // Add this item to the section\r\n item.section = section;\r\n\r\n // If this is a file inside a group, don't add it to the parent group if there is one\r\n // Fixes a case where adding a file from inside a group would mark each subsequent file in the group as already in the cart\r\n var ignoreGroup = ((data.groupid > 0) || (data.presid > 0)) && (data.slideid <= 0) && (data.fileid > 0);\r\n\r\n // Add this item to the cart\r\n // The list's method automatically searches for a parent item\r\n this.cartItems.addItem(item, null, ignoreGroup);\r\n if (expand)\r\n this.expandItem(item, update);\r\n // Add rules to this item if it isn't from rules already\r\n if (!fromRules)\r\n this.addRules(item, null, onComplete, update);\r\n else if (typeof onComplete == \"function\")\r\n onComplete();\r\n\r\n // Only run these functions if we're supposed to be updating\r\n if (update) {\r\n // Fire onUpdate if it exists\r\n this.onUpdate(expand === false);\r\n\r\n Librarian.Cart.onChange();\r\n }\r\n\r\n // If we don't have a cart window already open, but we are supposed to open it when something is added, try to open the window\r\n if (Librarian.cart.openCartOnAdd && (!Librarian.cartWindow || !Librarian.cartWindow.isVisible()) && (typeof Library.openCartWindow == \"function\"))\r\n Library.openCartWindow();\r\n\r\n return item;\r\n },\r\n\r\n /*\r\n * Checks whether an item can be inserted before calling doInsertBefore which actually does the inserting\r\n *\r\n * data - Data to be added to the cart\r\n * targetData - Data that represents the item before which the given data will be inserted\r\n * onInsert - Callback which is called after the insert has completed - Optional\r\n */\r\n insertBefore: function(data, targetData, onInsert) {\r\n onInsert = onInsert || $empty;\r\n\r\n // If we're not given good data, stop\r\n if ((typeof data == \"undefined\") || (data == null) ||\r\n (typeof targetData == \"undefined\") || (targetData == null)) {\r\n onInsert(data, false);\r\n return;\r\n }\r\n\r\n // Don't allow this item to be added to the cart if it violates Librarian rules\r\n if (!Librarian.cart.canAddToCart(data)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_cantadd\"));\r\n onInsert(data, false);\r\n return;\r\n }\r\n\r\n // Don't allow more items to be added to the cart if it is full\r\n if (!this.canAddToCart(data)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_full\"));\r\n onInsert(data, false);\r\n return;\r\n }\r\n\r\n // Don't allow adding something that's already in there\r\n if (this.isInCart(data)) {\r\n onInsert(data, false);\r\n return;\r\n }\r\n\r\n // Keep track of whether to use the parent index\r\n var parent = false;\r\n if (this.isInSlideView()) {\r\n // If the target was added as a file\r\n if (targetData.addType == Librarian.Cart.addTypes.FILE) {\r\n // And we're not dropping it on the first slide,\r\n // split it into its individual slides\r\n if (targetData.slidenumber > 1)\r\n this.cartItems.splitFileAndAddInPlace(Librarian.Cart.Item.makeParent(targetData));\r\n // Otherwise, remember to get the parent index instead\r\n else\r\n parent = true;\r\n }\r\n }\r\n\r\n var itemIndex;\r\n // Get the index of the parent, if we're told to\r\n if (parent)\r\n itemIndex = this.cartItems.indexOfParent(targetData, true);\r\n // Otherwise just get the index of this item\r\n else\r\n itemIndex = this.cartItems.indexOf(targetData, true);\r\n\r\n // Get the sizes of the current cart lists\r\n var itemSize = this.cartItems.getSize();\r\n\r\n // If the calculated index is -1, just add it to the end\r\n if (itemIndex < 0)\r\n itemIndex = itemSize;\r\n\r\n // Create a cart item from the parent data\r\n var item = new Librarian.Cart.Item(data),\r\n // Whether to expand an item\r\n expand = false;\r\n\r\n // Put this item in the same section that the target had\r\n item.section = targetData.section;\r\n\r\n // If this is a file, mark it as a file and expand\r\n if (isNaN(item.slideid) || (item.slideid <= 0)) {\r\n if (item.addType == null)\r\n item.setAddType(Librarian.Cart.addTypes.FILE);\r\n expand = true;\r\n }\r\n // Otherwise mark this is a a slide if it doesn't have an addType already\r\n else if (item.addType == null)\r\n item.setAddType(Librarian.Cart.addTypes.SLIDE);\r\n\r\n this.addRules(item, true, this.doInsertBefore.pass([item, itemIndex, expand, onInsert]));\r\n },\r\n\r\n /*\r\n * Inserts the given data before the item represented by the given `targetData`\r\n *\r\n * item - Data to be added to the cart\r\n * itemIndex - Location that the given data will be inserted to\r\n * expand - Whether or not to expand the inserted item to its slides\r\n * onInsert - Callback which is called after the insert has completed - Optional\r\n */\r\n doInsertBefore: function(item, itemIndex, expand, onInsert) {\r\n onInsert = onInsert || $empty;\r\n\r\n // If we're not given good data, stop\r\n if ((typeof item == \"undefined\") || (item == null)) {\r\n onInsert(item, false);\r\n return;\r\n }\r\n\r\n // Make sure this item can be inserted here\r\n if (Librarian.cart.enableGroupRules && !item.canInsert(itemIndex)) {\r\n onInsert(item, false);\r\n return;\r\n }\r\n\r\n this.cartItems.insertItemAt(item, itemIndex);\r\n if (expand)\r\n this.expandItem(item);\r\n\r\n // Call the post-rules check\r\n if (Librarian.cart.enableGroupRules)\r\n item.onInsert();\r\n\r\n // Fire onUpdate\r\n this.onUpdate();\r\n\r\n Librarian.Cart.onChange();\r\n\r\n onInsert(item);\r\n },\r\n\r\n /*\r\n * Checks whether an item can be removed before calling doRemoveFromCart which actually does the removing\r\n *\r\n * data - The data to be removed from the cart\r\n * fromCart - Whether this request is coming from within the cart itself. If true, the item is marked as deleted, otherwise the item is removed - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item to remove from the cart - Optional, defaults to false\r\n * update - Whether to run the update function after this operation is complete - Optional, defaults to true\r\n * fromRules - Whether to bypass the \"allowed\" checks because this is from group rules - Optional, defaults to false\r\n * onRemove - Callback which is called after the remove has completed - Optional\r\n * onRemoveFail - Callback which is called if remove failed - Optional\r\n */\r\n removeFromCart: function(data, fromCart, ignoreGroup, update, fromRules, onRemove, onRemoveFail) {\r\n // If we aren't told to ignore groups, assume not\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null)) {\r\n if (Librarian.cart.enableGroupRules)\r\n ignoreGroup = this.doesItemHaveGroupRules(data);\r\n else\r\n ignoreGroup = false;\r\n }\r\n if ((typeof fromRules == \"undefined\") || (fromRules == null))\r\n fromRules = false;\r\n\r\n // Make sure this item can be removed first\r\n if (Librarian.cart.enableGroupRules) {\r\n var cartItem = this.cartItems.getParentOrItemItself(data, ignoreGroup);\r\n if (cartItem != null) {\r\n cartItem.canRemove(fromCart, ignoreGroup, update, fromRules, onRemove, onRemoveFail);\r\n return;\r\n }\r\n }\r\n\r\n this.doRemoveFromCart(data, fromCart, ignoreGroup, update, fromRules, onRemove);\r\n },\r\n\r\n /*\r\n * Removes the item that represents the given data from the cart or marks it as deleted\r\n *\r\n * data - The data to be removed from the cart\r\n * fromCart - Whether this request is coming from within the cart itself. If true, the item is marked as deleted, otherwise the item is removed - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item to remove from the cart - Optional, defaults to false\r\n * update - Whether to run the update function after this operation is complete - Optional, defaults to true\r\n * fromRules - Whether to bypass the \"allowed\" checks because this is from group rules - Optional, defaults to false\r\n * onRemove - Callback which is called after the remove has completed - Optional\r\n * removeAutomaticallyAddedItemsOnly - Used by the post remove rules to determine whether or not to only remove items that were added automatically\r\n */\r\n doRemoveFromCart: function(data, fromCart, ignoreGroup, update, fromRules, onRemove, removeAutomaticallyAddedItemsOnly) {\r\n if (!data)\r\n return;\r\n\r\n var cartItem = this.cartItems.getParentOrItemItself(data, ignoreGroup);\r\n // If we aren't told to ignore groups, assume not\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null))\r\n ignoreGroup = false;\r\n if ((typeof fromRules == \"undefined\") || (fromRules == null))\r\n fromRules = false;\r\n // If we aren't told this is happening from within the cart, assume not\r\n if ((typeof fromCart == \"undefined\") || (fromCart == null))\r\n fromCart = false;\r\n // If we aren't told to update, assume yes\r\n if ((typeof update == \"undefined\") || (update == null))\r\n update = true;\r\n\r\n // If this is from within the cart, just set the item deleted for now, don't actually remove it\r\n if (fromCart)\r\n this.cartItems.setItemDeleted(data);\r\n else {\r\n // If we're not in the cart, actually remove the items.\r\n this.cartItems.removeItemChildren(data, ignoreGroup);\r\n this.cartItems.removeItem(data, ignoreGroup);\r\n\r\n // Get this item's parent\r\n var parentItem = this.cartItems.getParentOrItemItself(data);\r\n\r\n // Make sure it isn't itself\r\n // and then remove this child from the parent\r\n if (parentItem && !parentItem.equals(data, ignoreGroup)) {\r\n parentItem.removeItemChildren(data, ignoreGroup);\r\n parentItem.removeItem(data, ignoreGroup);\r\n\r\n // If this parent is empty, get rid of it.\r\n if (parentItem.getSize(false) == 0)\r\n this.cartItems.removeItem(parentItem);\r\n }\r\n\r\n // If we don't allow duplicates, go through and unset the duplicate slides if they aren't duplicate anymore\r\n if (!Librarian.cart.allowDuplicates)\r\n this.cartItems.updateDuplicateState();\r\n }\r\n\r\n // Run the post-rules checks\r\n if (!fromRules) {\r\n if (cartItem != null)\r\n cartItem.onRemove(fromCart, removeAutomaticallyAddedItemsOnly);\r\n }\r\n if (typeof onRemove == \"function\")\r\n onRemove(cartItem);\r\n\r\n // Fire onUpdate\r\n if (update) {\r\n this.onUpdate();\r\n\r\n // Update the checkboxes on the main page\r\n Librarian.Utils.updateAllCheckboxes();\r\n }\r\n },\r\n\r\n /*\r\n * Removes all items marked as deleted from the cart\r\n */\r\n removeAllDeleted: function() {\r\n var item;\r\n\r\n // For every item in the cart\r\n for (var i = 0; i < this.cartItems.items.length; i++) {\r\n item = this.cartItems.items[i];\r\n\r\n // If this is a file inside a group, don't add it to the parent group if there is one\r\n // Fixes a case where adding a file from inside a group would mark each subsequent file in the group as already in the cart\r\n var fileInGroup = ((item.groupid > 0) || (item.presid > 0)) && (item.slideid <= 0) && (item.fileid > 0);\r\n\r\n\r\n if(Librarian.features.fastlane.load === true && Librarian.FastLane.isEnabled) {\r\n \r\n if (item.deleted) {\r\n // Set fromRules = true to bypass the post-rules checks\r\n this.doRemoveFromCart(item, null, null, null, true);\r\n i--;\r\n }\r\n\r\n } else {\r\n \r\n // If it's deleted or it's a file that is empty, remove it\r\n // Add a special check for files pretending to have slides and slideshows, because they are always \"empty\"\r\n if (item.deleted || ((item.slidenumber <= 0) && !item.isslideshow && !Librarian.extensions.hasFakeSlides(Librarian.Utils.getExtensionFromData(item, true)) && (item.getSize(false, true) == 0) && !fileInGroup && !item.fromRules)) {\r\n // Set fromRules = true to bypass the post-rules checks\r\n this.doRemoveFromCart(item, null, null, null, true);\r\n i--;\r\n }\r\n\r\n }\r\n\r\n \r\n }\r\n\r\n // If we don't allow duplicates, go through and unset the duplicate slides if they aren't duplicate anymore\r\n if (!Librarian.cart.allowDuplicates)\r\n this.cartItems.updateDuplicateState();\r\n\r\n // Update the checkboxes on the main page\r\n Librarian.Utils.updateAllCheckboxes();\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Expand\r\n\r\n /*\r\n * Loads information about content rules from the server and stores it in this item\r\n *\r\n * item - The cart item for which content rules are being retrieved from the server\r\n * insert - Whether or not this is an insert operation - Optional, defaults to false\r\n * onComplete - Callback to call once rules have been loaded - Optional\r\n * update - Whether or not to run the update rules after completing this operation - Optional\r\n */\r\n addRules: function(item, insert, onComplete, update) {\r\n var onRulesLoaded = function(cartItem) {\r\n // If this isn't an insert then call the normal onAdd callback\r\n // Inserts need the rule data before they can be processed so the callback below will be used to check those\r\n if (cartItem && (insert !== true) && (typeof cartItem.onAdd == \"function\"))\r\n cartItem.onAdd(null, update);\r\n\r\n if (typeof onComplete == \"function\")\r\n onComplete();\r\n };\r\n\r\n // If this already has rules, don't bother loading more\r\n if (item.ruleGroup > 0) {\r\n onRulesLoaded(item);\r\n return;\r\n }\r\n\r\n var request = Librarian.Cart.getItemRules(item, insert, onRulesLoaded);\r\n if (request != null)\r\n this.requests.push(request);\r\n },\r\n\r\n /*\r\n * Expands the given cart item into its smallest components\r\n *\r\n * item - The cart item to expand\r\n * update - Whether to run the onUpdate function after this operation completes\r\n */\r\n expandItem: function(item, update) {\r\n // Expand this item to its slides\r\n // Files and groups are handled differently\r\n if (item.presid > 0) {\r\n // Make sure this presentation isn't already expanding\r\n if (!this.expansions.contains('P' + item.presid))\r\n this.expandVirtualToSlides(item, update);\r\n }\r\n else if (item.groupid > 0) {\r\n // Make sure this group isn't already expanding\r\n if (!this.expansions.contains('G' + item.groupid))\r\n this.expandGroupToSlides(item, update);\r\n }\r\n else {\r\n // Make sure this file isn't already expanding\r\n if (!this.expansions.contains('F' + item.fileid))\r\n this.expandFileToSlides(item, update);\r\n }\r\n },\r\n\r\n /*\r\n * Expands a file item in the cart to slides\r\n *\r\n * parentItem - The file being expanded to slides\r\n * update - Whether to run the onUpdate function after this operation completes\r\n */\r\n expandFileToSlides: function(parentItem, update) {\r\n // Add this file to the list of currently expanding items\r\n this.expansions.push('F' + parentItem.fileid);\r\n // Build the URL used to fetch group data for this virtual\r\n var url = Librarian.path.getMethodUrl(\"getslides\") + \"&fid=\" + parentItem.fileid + \"&out=dgrid\";\r\n\r\n if (Librarian.search.viewNameByType && Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES])\r\n url += \"&vname=\" + Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES];\r\n\r\n this.expandToSlides(url, parentItem, update);\r\n },\r\n\r\n /*\r\n * Expands a virtual presentation item in the cart to slides\r\n *\r\n * parentItem - The virtual presentation being expanded to slides\r\n * update - Whether to run the onUpdate function after this operation completes\r\n */\r\n expandVirtualToSlides: function(parentItem, update) {\r\n // Add this presentation to the list of currently expanding items\r\n this.expansions.push('P' + parentItem.presid);\r\n // Build the URL used to fetch group data for this virtual\r\n var url = Librarian.path.getMethodUrl(\"getvp\") + \"&pid=\" + parentItem.presid + \"&comp=1&out=dgrid&expand=\" + (Librarian.tileList.expandGroupItemsToSlides ? '1' : '0');\r\n\r\n if (Librarian.search.viewNameByType && Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES])\r\n url += \"&vname=\" + Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES];\r\n\r\n this.expandToSlides(url, parentItem, update);\r\n },\r\n\r\n /*\r\n * Expands a group item in the cart to slides\r\n *\r\n * parentItem - The group being expanded to slides\r\n * update - Whether to run the onUpdate function after this operation completes\r\n */\r\n expandGroupToSlides: function(parentItem, update) {\r\n // Add this group to the list of currently expanding items\r\n this.expansions.push('G' + parentItem.groupid);\r\n // Build the URL used to fetch group data for this group\r\n var url = Librarian.path.getMethodUrl(\"getgslides\") + \"&gid=\" + parentItem.groupid + \"&out=dgrid&expand=\" + (Librarian.tileList.expandGroupItemsToSlides ? '1' : '0');\r\n\r\n if (Librarian.search.viewNameByType && Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES])\r\n url += \"&vname=\" + Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES];\r\n\r\n if (Librarian.search.viewNameByType && Librarian.search.viewNameByType[Librarian.Search.outputTypes.FILES])\r\n url += \"&fvname=\" + Librarian.search.viewNameByType[Librarian.Search.outputTypes.FILES];\r\n\r\n this.expandToSlides(url, parentItem, update);\r\n },\r\n\r\n /*\r\n * Expands a given item to slides using the provided API URL\r\n *\r\n * url - The URL to the API being used to expand this item\r\n * parentItem - The item being expanded\r\n * update - Whether to run the onUpdate function after this operation completes\r\n */\r\n expandToSlides: function(url, parentItem, update) {\r\n var self = this,\r\n request = new Librarian.Request.JSON({\r\n url: url,\r\n onSuccess: function(json) {\r\n // Pass the parentItem and update flag to the handler\r\n self.expandLoadComplete(json, parentItem, update, this.index);\r\n },\r\n onFailure: Librarian.Utils.onFailure\r\n });\r\n\r\n // Store the request\r\n var index = this.requests.push(request) - 1;\r\n // and the request's index\r\n this.requests[index].index = index;\r\n\r\n // Send the request to be processed\r\n this.requests[index].send();\r\n },\r\n\r\n /*\r\n * Processes the data loaded from the server during expansion of a cart item\r\n *\r\n * json - The expanded data from the server\r\n * parentItem - The item being expanded\r\n * update - Whether to run the onUpdate function after this operation completes\r\n * index - The index of the request that just completed\r\n */\r\n expandLoadComplete: function(json, parentItem, update, index) {\r\n this.clearRequest(index);\r\n\r\n // Remove this item from the expanding list now that it's done\r\n if (parentItem.presid > 0)\r\n this.expansions.remove(this.expansions.indexOf('P' + parentItem.presid));\r\n else if (parentItem.groupid > 0)\r\n this.expansions.remove(this.expansions.indexOf('G' + parentItem.groupid));\r\n else\r\n this.expansions.remove(this.expansions.indexOf('F' + parentItem.fileid));\r\n\r\n // If we didn't get a valid response, don't continue.\r\n if (!json || !json.data || !json.data.length)\r\n return;\r\n\r\n var items;\r\n // File / Global Favorite\r\n if (json.data[0].slides)\r\n items = json.data[0].slides;\r\n // Virtual Presentation\r\n else if (json.data[0].items)\r\n items = json.data[0].items;\r\n // Error\r\n else\r\n return;\r\n\r\n // If there are no items in this file, check if it's one of those files that pretends to have slides\r\n if (items.length == 0) {\r\n var ext = Librarian.Utils.getExtensionFromData(parentItem);\r\n\r\n // If it is, turn the parent item into a \"child\" and add that to the list\r\n if (Librarian.extensions.hasFakeSlides(ext)) {\r\n var childItem = Object.clone(parentItem);\r\n childItem.slidenumber = 1;\r\n items.push(childItem);\r\n }\r\n }\r\n\r\n var item,\r\n duplicates = false;\r\n // Create a new item for every slide in this group\r\n for (var i = 0; i < items.length; i++) {\r\n // If this is a presentation with a -1 slide id and an invalid file type,\r\n // the source isn't available and we should not add it to the cart\r\n if (Librarian.Utils.isSourceNotAvailable(items[i]))\r\n continue;\r\n\r\n item = new Librarian.Cart.Item(items[i]);\r\n // Save the slide count as the number of items we have here\r\n item.slidecount = items.length;\r\n // Save the extrafields from the parent\r\n item.setParentFields(parentItem.extrafields);\r\n // If the parent item has file flags, save those as well\r\n if (parentItem.flags > item.flags)\r\n item.flags = parentItem.flags;\r\n item.setAddType(Librarian.Cart.addTypes.FILE);\r\n\r\n // The children fetched from the server don't have all the information\r\n // from their parent group, so assign it here instead.\r\n if (parentItem.presid > 0) {\r\n if (Librarian.cart.showMyFavoriteName)\r\n item.name = parentItem.name;\r\n }\r\n else if (parentItem.groupid > 0) {\r\n if (Librarian.cart.showGlobalFavoriteName)\r\n item.name = parentItem.name;\r\n }\r\n else\r\n item.name = parentItem.name;\r\n\r\n // If this is the member of a group...\r\n if ((parentItem.presid > 0) || (parentItem.groupid > 0)) {\r\n var parentext = Librarian.Utils.getExtensionFromData(parentItem),\r\n ext = Librarian.Utils.getExtensionFromData(item);\r\n\r\n // Set the child's extension to the extension of the group,\r\n // but also save the source file extension\r\n if (ext != parentext) {\r\n item.sourceext = ext;\r\n item.ext = parentext;\r\n }\r\n }\r\n item.groupid = parentItem.groupid;\r\n item.presid = parentItem.presid;\r\n item.section = parentItem.section;\r\n\r\n // Group rules\r\n item.isDependent = parentItem.isDependent;\r\n item.isTrigger = parentItem.isTrigger;\r\n item.isIntegrity = parentItem.isIntegrity;\r\n item.isOrdering = parentItem.isOrdering;\r\n item.isGrouping = parentItem.isGrouping;\r\n item.ruleGroup = parentItem.ruleGroup;\r\n item.orderindex = parentItem.orderindex;\r\n item.fromRules = parentItem.fromRules;\r\n item.rules = parentItem.rules;\r\n\r\n // If we've expanded a group to its slides, make sure the item number is correct for display\r\n if ((item.groupid > 0) || (item.presid > 0))\r\n item.itemnumber = i + 1;\r\n\r\n // Mark duplicates added to the cart as such\r\n if (!Librarian.cart.allowDuplicates && Librarian.userCart && Librarian.userCart.isInCart(item, true)) {\r\n item.duplicate = true;\r\n duplicates = true;\r\n }\r\n\r\n // If this slide isn't in the parent's \"items\" list, add it\r\n // Use \"push\" instead of \"addItem\" because at this point we just want to add each \"item\" to its parent, nothing else\r\n if (!parentItem.contains(item, null, true))\r\n parentItem.items.push(item);\r\n }\r\n\r\n if (Librarian.userCart) {\r\n // If this parent doesn't have any items, why keep it in the cart?\r\n if (parentItem.getSize() == 0)\r\n Librarian.userCart.removeFromCart(parentItem, false, false, false);\r\n }\r\n\r\n // Wait until all the expansions are done before we run the updates\r\n if (this.expansions.length == 0) {\r\n // Fire onUpdate\r\n if (update !== false)\r\n this.onUpdate();\r\n\r\n if (duplicates)\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_duplicate\"));\r\n\r\n Librarian.Cart.onChange();\r\n\r\n // Update the checkboxes on the main page\r\n Librarian.Utils.updateAllCheckboxes();\r\n }\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Helper Methods\r\n\r\n /*\r\n * Clears all content and pending requests from the cart\r\n */\r\n clear: function() {\r\n // Remove the items\r\n this.cartItems.clear();\r\n\r\n // Stop each request\r\n for (var i = 0; i < this.requests.length; i++)\r\n this.clearRequest(i);\r\n\r\n // Remove each section\r\n for (var i = 0; i < this.sections.length; i++) {\r\n if (this.sections[i])\r\n this.sections[i] = null;\r\n }\r\n\r\n // Truncate the lists\r\n this.requests.length = 0;\r\n this.expansions.length = 0;\r\n this.sections.length = 0;\r\n\r\n // Fire onUpdate\r\n this.onUpdate();\r\n },\r\n\r\n /*\r\n * Cancels the request represented by the given index within the list of pending requests\r\n *\r\n * index - The index which represents the request to be cancelled\r\n */\r\n clearRequest: function(index) {\r\n if (this.requests[index]) {\r\n this.requests[index].cancel();\r\n this.requests[index] = null;\r\n }\r\n },\r\n\r\n /*\r\n * Changes the view of the cart to the given view mode\r\n * Disables the navigation buttons for preview windows also due to an issue with them not behaving correctly after the cart view is changed\r\n *\r\n * view - View type to change the cart to\r\n */\r\n changeView: function(view) {\r\n // Make sure the view we are changing to is valid.\r\n if ((view >= Librarian.Cart.displayModes.MIXED_VIEW) &&\r\n (view <= Librarian.Cart.displayModes.SLIDE_VIEW)) {\r\n this.displayMode = view;\r\n // Force an update to make sure we're\r\n // displaying the most up-to-date information.\r\n Librarian.Cart.onChange();\r\n\r\n // Disable the nav buttons for all existing preview windows\r\n // so that the \"next/previous\" item buttons don't screw up\r\n if (previewWindows) {\r\n for (var i = 0; i < previewWindows.length; i++)\r\n previewWindows[i].disableNavButtons();\r\n }\r\n }\r\n },\r\n\r\n /*\r\n * Moves an item in the cart from one location to another\r\n *\r\n * firstItem - The item to be moved\r\n * secondItem - The item in front of which the first item will be moved\r\n * update - Whether to run the update function after this operation is complete - Optional, defaults to false\r\n * fromRules - Whether to bypass the \"allowed\" checks because this is from group rules - Optional, defaults to false\r\n */\r\n moveItem: function(firstItem, secondItem, update, fromRules) {\r\n if ((typeof update == \"undefined\") || (update == null))\r\n update = false;\r\n if ((typeof fromRules == \"undefined\") || (fromRules == null))\r\n fromRules = false;\r\n\r\n // Make sure this item can be moved first\r\n var oldLoc = -1;\r\n if (!fromRules && Librarian.cart.enableGroupRules && firstItem) {\r\n oldLoc = this.getItemIndex(firstItem);\r\n if ((typeof firstItem.canMove == \"function\") && !firstItem.canMove(secondItem))\r\n return;\r\n }\r\n\r\n this.cartItems.moveItem(firstItem, secondItem, fromRules);\r\n\r\n // always fire onUpdate if fastlane is enabled\r\n if (update !== false || (Librarian.features.fastlane.load && Librarian.FastLane.isEnabled) ) {\r\n // Fire onUpdate if it exists\r\n this.onUpdate();\r\n\r\n Librarian.Cart.onChange();\r\n }\r\n\r\n // Run the post-rules checks\r\n if (!fromRules && (typeof firstItem.onMove == \"function\"))\r\n firstItem.onMove(oldLoc);\r\n },\r\n\r\n /*\r\n * Prints the cart rules for each item in the cart to help with debugging any rules issues\r\n */\r\n printRulesDebug: function() {\r\n if (!window.console)\r\n return;\r\n\r\n for (var i = 0, length = this.cartItems.items.length; i < length; i++) {\r\n var cartItem = this.cartItems.items[i];\r\n console.log(\"Cart Index: \" + i);\r\n console.log(\" Order Index: \" + cartItem.orderindex);\r\n console.log(\" isGrouping: \" + cartItem.isGrouping);\r\n console.log(\" isOrdering: \" + cartItem.isOrdering);\r\n console.log(\" isIntegrity: \" + cartItem.isIntegrity);\r\n console.log(\" isTrigger: \" + cartItem.isTrigger);\r\n console.log(\" isDependent: \" + cartItem.isDependent);\r\n console.log(\" isMandatory: \" + cartItem.isMandatory);\r\n console.log(\" cartPosition: \" + cartItem.cartPosition);\r\n console.log(cartItem);\r\n }\r\n }\r\n\r\n //#endregion\r\n});\r\n\r\nLibrarian.Cart.extend({\r\n // MIXED_VIEW - Display items as they were added to the cart, files as files and slides as slides\r\n // SLIDE_VIEW - Display each item as a list of its child slides.\r\n displayModes: {\r\n MIXED_VIEW: 0,\r\n SLIDE_VIEW: 1\r\n },\r\n\r\n addTypes: {\r\n FILE: 0,\r\n SLIDE: 1,\r\n CATEGORY: 2\r\n },\r\n\r\n //#region Open/Close Window\r\n\r\n /*\r\n * Opens the cart window\r\n *\r\n * onVPCreatedFn - A function run when a My Favorite is created\r\n * onVPCatCreatedFn - A function run when a My Favorite category is created\r\n */\r\n openCart: function(onVPCreatedFn, onVPCatCreatedFn) {\r\n if (!mainPanel || !mainPanel.loaded)\r\n return false;\r\n\r\n // If the cart window doesn't exist or it's hidden, create a new one\r\n if (!Librarian.cartWindow || !Librarian.cartWindow.isVisible()) {\r\n Librarian.cartWindow = new Librarian.Cart.Window({}, onVPCreatedFn, onVPCatCreatedFn);\r\n Librarian.cartWindow.show();\r\n }\r\n // If it's just minimized, show it\r\n else if (Librarian.cartWindow.isMinimized)\r\n Librarian.cartWindow.restore();\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Closes the cart window\r\n */\r\n closeCart: function() {\r\n if (Librarian.cartWindow) {\r\n Librarian.cartWindow.close();\r\n Librarian.cartWindow = null;\r\n }\r\n },\r\n\r\n /*\r\n * Opens the cart window to a particular function such as \"create\" or \"save\"\r\n *\r\n * method - The method to open once the cart window opens\r\n * param1 - The first parameter for the specified function - Optional\r\n * param2 - The second parameter for the specified function - Optional\r\n * param3 - The third parameter for the specified function - Optional\r\n * param4 - The fourth parameter for the specified function - Optional\r\n * param5 - The fifth parameter for the specified function - Optional\r\n *\r\n * Returns false\r\n */\r\n openCartFunction: function(method, param1, param2, param3, param4, param5) {\r\n if (!mainPanel || !mainPanel.loaded)\r\n return false;\r\n\r\n // If the cart window hasn't been created,\r\n // create one and then immediately close it\r\n // so the it doesn't get in the user's way\r\n if (!Librarian.cartWindow) {\r\n Librarian.cartWindow = new Librarian.Cart.Window({}, method == \"save\" ? param1 : null, method == \"save\" ? param2 : null);\r\n Librarian.cartWindow.close();\r\n }\r\n\r\n if (method == \"create\")\r\n Librarian.cartWindow.downloadCart(null, param1, param2);\r\n else if (method == \"save\")\r\n Librarian.cartWindow.saveAsFavorite(param1, param2, param3, param4, param5);\r\n else if (method == \"send\")\r\n Librarian.Cart.sendCart();\r\n\r\n return false;\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Clear\r\n\r\n /*\r\n * Clears the cart after prompting the user\r\n *\r\n * onClear - Function to run after the user has accepted the clear prompt\r\n *\r\n * Returns false\r\n */\r\n clearCart: function(onClear) {\r\n // If there is no cart or the cart is empty, there is nothing to clear.\r\n if (!Librarian.userCart || ((Librarian.userCart.sections.length == 0) && (Librarian.userCart.cartItems.getSize() == 0)))\r\n return false;\r\n\r\n // Make sure the user wants to do this first\r\n var confirm = new Librarian.ConfirmWindow({\r\n id: \"clearCartConfirmWindow\",\r\n title: Librarian.Lang.getString(\"cart_clear\"),\r\n question: Librarian.Lang.getString(\"cart_clear?\")\r\n });\r\n confirm.onFirstButtonClicked = Librarian.Cart.doClear;\r\n confirm.show();\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Performs the clear operation on the cart\r\n *\r\n * notify - Whether to notify the user that the cart has been cleared - Optional, defaults to true\r\n */\r\n doClear: function(notify) {\r\n // If we aren't told Whether to notify, assume yes.\r\n if ((typeof notify == \"undefined\") || (notify == null))\r\n notify = true;\r\n // If there is no cart or the cart is empty, there is nothing to clear.\r\n if (!Librarian.userCart || ((Librarian.userCart.sections.length == 0) && (Librarian.userCart.getCount(false, true) == 0)))\r\n return;\r\n\r\n // Clear the entire cart\r\n Librarian.userCart.clear();\r\n\r\n // Tell the user\r\n if (notify && !(Librarian.features.fastlane.load && Librarian.FastLane.isEnabled)) {\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_cleared\"));\r\n }\r\n\r\n // Update the checkboxes on the main page\r\n Librarian.Utils.updateAllCheckboxes();\r\n\r\n Librarian.Cart.onChange();\r\n\r\n if (Librarian.cartWindow)\r\n Librarian.cartWindow.textReplaces = null;\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Send\r\n\r\n /*\r\n * Sends the cart content as a portal. If the cart contains sections, this will automatically save the cart as a My Favorite and the send that instead\r\n *\r\n * eventType - The type of event to send this content with. Special restrictions are in place for newsletters - Optional\r\n */\r\n sendCart: function(eventType) {\r\n // If there is no cart or the cart is empty, there is nothing to clear.\r\n if (!Librarian.userCart || (Librarian.userCart.cartItems.getSize() == 0))\r\n return false;\r\n\r\n if (typeof eventType != \"number\")\r\n eventType = Librarian.eventType.oneOff;\r\n\r\n var openSendWindow = function(data) {\r\n new Librarian.EventSendWindow({\r\n eventType: eventType,\r\n onSuccess: function() {\r\n if (Librarian.cart.clearCartOnSend)\r\n Librarian.Cart.doClear();\r\n }.bind(this)\r\n }, data).show();\r\n };\r\n\r\n if (Librarian.cart.canCombineShares &&\r\n (Librarian.userCart.sections.length > 0 || Librarian.userCart.hasEditedItems())) {\r\n // Newsletters are not allowed to send edited items\r\n if (eventType === Librarian.eventType.newsletter) {\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_newsletter_noedits\"), false);\r\n return false;\r\n }\r\n\r\n // Create a pre-named My Favorite in a hidden category and send that\r\n var createPackage = new Librarian.CreatePackage({\r\n showNotification: false,\r\n onSuccess: function(json) {\r\n var data = (json && json.data && json.data[0]);\r\n if (!data)\r\n return;\r\n\r\n // Set ext so we can tell the content type\r\n data.ext = \"vpres\";\r\n\r\n openSendWindow(data);\r\n }\r\n });\r\n createPackage.send({ clearOnSave: false }, { catid: -2, name: \"Content Collection \" + new Date().format(\"%m-%d-%Y %k.%M.%S\"), description: '', create: false });\r\n }\r\n else {\r\n // Newsletters are not allowed to send slides\r\n if ((eventType === Librarian.eventType.newsletter) && Librarian.userCart.hasSlides()) {\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_newsletter_noslides\"), false);\r\n return false;\r\n }\r\n\r\n openSendWindow(Librarian.userCart.getCartItems());\r\n }\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Determines whether sending from the cart is allowed\r\n */\r\n canSend: function() {\r\n return Librarian.event.canShare;\r\n },\r\n\r\n /*\r\n * Determines whether all of the items in the cart can be sent\r\n */\r\n canSendItems: function() {\r\n var items = Librarian.userCart.getCartItems();\r\n for (var i = items.length; i--;) {\r\n var item = items[i];\r\n\r\n if (!Librarian.Cart.canSendItem(item))\r\n return false;\r\n }\r\n\r\n return true;\r\n },\r\n\r\n /*\r\n * Determines whether an individual item can be sent\r\n */\r\n canSendItem: function(item) {\r\n return Library.canShare(item);\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Save/Load from Server\r\n\r\n /*\r\n * Saves the content of the cart to the server\r\n */\r\n saveCart: function() {\r\n if (!Librarian.userCart || !Librarian.cart.saveCartToServer)\r\n return;\r\n\r\n // Get all items, including deleted\r\n var cartList = Librarian.userCart.getCartItems(true);\r\n if (!cartList)\r\n return;\r\n\r\n var request = new Librarian.Request({\r\n method: \"post\",\r\n url: Librarian.path.getUpdateUrl(\"savecart\"),\r\n data: {\r\n fcont: JSON.encode(cartList)\r\n }\r\n });\r\n request.send();\r\n\r\n request = null;\r\n },\r\n\r\n /*\r\n * Loads a previously saved copy of the cart from the server\r\n */\r\n loadCart: function() {\r\n function onLoadCart(json) {\r\n if (!Librarian.userCart || !json)\r\n return;\r\n\r\n // Add each item to the cart\r\n for (var i = 0; i < json.length; i++)\r\n Librarian.userCart.addToCart(json[i], false);\r\n\r\n // Update the checkboxes on the main page\r\n Librarian.Utils.updateAllCheckboxes();\r\n\r\n Librarian.Cart.onChange();\r\n\r\n // Run the update function to make sure all the counts are displayed correctly\r\n Librarian.userCart.onUpdate(false);\r\n }\r\n\r\n var request = new Librarian.Request.JSON({\r\n url: Librarian.path.getMethodUrl(\"getcart\") + \"&out=text\",\r\n onSuccess: onLoadCart\r\n });\r\n request.send();\r\n\r\n request = null;\r\n },\r\n\r\n //#endregion\r\n\r\n /*\r\n * Updates the cart window after changes are made\r\n */\r\n onChange: function() {\r\n if (Librarian.cartWindow) {\r\n if (Librarian.cartWindow.isVisible())\r\n Librarian.cartWindow.reload();\r\n\r\n Librarian.cartWindow.updateCreateWindow();\r\n }\r\n },\r\n\r\n /*\r\n * Loads information about content rules from the server and stores it in this item\r\n *\r\n * item - The cart item for which content rules are being retrieved from the server\r\n * insert - Whether or not this is an insert operation - Optional, defaults to false\r\n * onComplete - Callback to call once rules have been loaded - Optional\r\n * update - Whether or not to run the update rules after completing this operation - Optional\r\n */\r\n getItemRules: function(item, insert, onComplete) {\r\n onComplete = onComplete || $empty;\r\n if (!Librarian.cart.enableGroupRules) {\r\n onComplete(item);\r\n return null;\r\n }\r\n\r\n var contentType = Librarian.contentType.file,\r\n contentId = item.fileid;\r\n if (item.slideid > 0) {\r\n contentType = Librarian.contentType.slide;\r\n contentId = item.slideid;\r\n var parentContentId = item.fileid;\r\n }\r\n\r\n // We only had rules for files and slides, if this is neither then don't get rules\r\n if ((typeof contentId != \"number\") || (contentId <= 0)) {\r\n onComplete(item);\r\n return null;\r\n }\r\n\r\n // Pass views if we have them set to try and get meta for the gathered rule items\r\n var url = Librarian.path.getMethodUrl(\"getcrules\") + \"&out=ljson&cntid=\" + contentId + \"&cnttype=\" + contentType;\r\n\r\n var getRules = function(url) {\r\n if (Librarian.search.viewNameByType) {\r\n if (Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES])\r\n url += \"&vname=\" + Librarian.search.viewNameByType[Librarian.Search.outputTypes.SLIDES];\r\n if (Librarian.search.viewNameByType[Librarian.Search.outputTypes.FILES])\r\n url += \"&fvname=\" + Librarian.search.viewNameByType[Librarian.Search.outputTypes.FILES];\r\n }\r\n\r\n var request = new Librarian.Request.JSON({\r\n url: url,\r\n onSuccess: function(json) {\r\n // Save the rules, if there are any\r\n if (json) {\r\n item.ruleGroup = json.groupid;\r\n item.orderindex = json.orderindex;\r\n item.rules = json.rules;\r\n item.ruleItems = json.items;\r\n item.isDependent = json.isdependent;\r\n item.isTrigger = json.istrigger;\r\n item.isIntegrity = json.isintegrity;\r\n item.isOrdering = json.isordering;\r\n item.isGrouping = json.isgrouping;\r\n }\r\n\r\n onComplete(item);\r\n }\r\n });\r\n request.send();\r\n return request;\r\n }\r\n\r\n getRules(url);\r\n\r\n if (parentContentId && Librarian.cart.addFileGroupRulesFromSlide) {\r\n url = Librarian.path.getMethodUrl(\"getcrules\") + \"&out=ljson&cntid=\" + parentContentId + \"&cnttype=\" + Librarian.contentType.file ;\r\n getRules(url);\r\n }\r\n }\r\n});","Librarian.Cart.Item = new Class({\r\n //#region Properties\r\n\r\n //#region Identifiers\r\n\r\n contentid: 0,\r\n contenttype: 0,\r\n fileid: 0,\r\n groupid: 0,\r\n presid: 0,\r\n slideid: 0,\r\n linkid: 0,\r\n slidenumber: 0,\r\n itemnumber: 0,\r\n\r\n //#endregion\r\n\r\n //#region Counts\r\n\r\n slidecount: 0,\r\n itemcount: 0,\r\n pagecount: 0,\r\n filesize: 0,\r\n \r\n //#endregion\r\n\r\n //#region Other Properties\r\n\r\n fromWizard: false,\r\n ext: null,\r\n sourceext: null,\r\n name: null,\r\n filename: null,\r\n title: null,\r\n extrafields: null,\r\n parentfields: null,\r\n thumbnailid: null,\r\n flags: 0,\r\n // The URL to download and replace this file with on the server\r\n fileUrl: null,\r\n\r\n catType: Librarian.catType.file,\r\n catId: -1,\r\n\r\n //#endregion\r\n\r\n //#region Cart-specific Properties\r\n\r\n // Whether this item has been deleted or not\r\n deleted: false,\r\n duplicate: false,\r\n // The children items this item may have\r\n items: null,\r\n // How this item was added to the cart\r\n addType: null,\r\n originalAddType: null,\r\n // The section index that this item belongs to\r\n section: -1,\r\n\r\n //#endregion\r\n\r\n //#region VP-specific Properties\r\n\r\n prestype: Librarian.virtPresType.undefined,\r\n isslideshow: false,\r\n isshared: false,\r\n\r\n //#endregion\r\n\r\n //#region Editable Properties\r\n\r\n hasedits: false,\r\n editable: false,\r\n editsXML: null,\r\n editFileName: null,\r\n\r\n //#endregion\r\n\r\n //#region Rules Properties\r\n\r\n isDependent: false,\r\n isTrigger: false,\r\n isIntegrity: false,\r\n isOrdering: false,\r\n isGrouping: false,\r\n isMandatory: false,\r\n // What position this item is locked to in the cart, \"Start\" or \"End\"\r\n cartPosition: null,\r\n // Whether this was automatically added as the result of rules\r\n fromRules: false,\r\n\r\n rules: [],\r\n ruleItems: [],\r\n ruleGroup: -1,\r\n orderindex: -1,\r\n\r\n //#endregion\r\n\r\n //#endregion\r\n\r\n /*\r\n * Initializes a new instance of this Item and ensures that default data values are set\r\n */\r\n initialize: function(data) {\r\n // Store original data\r\n this.data = data;\r\n\r\n // Store the information given\r\n this.contentid = data.contentid || 0;\r\n this.contenttype = data.contenttype || 0;\r\n this.fileid = data.fileid || 0;\r\n this.groupid = data.groupid || 0;\r\n this.presid = data.presid || 0;\r\n this.slideid = data.slideid || 0;\r\n this.linkid = data.linkid || 0;\r\n this.flags = data.flags || 0;\r\n\r\n // If the number is < 0, use 0\r\n // If the number is > 0, keep it\r\n this.slidenumber = data.slidenumber ? Math.max(data.slidenumber, 0) : 0;\r\n this.itemnumber = data.itemnumber ? Math.max(data.itemnumber, 0) : 0;\r\n // If the count is < 0, use 1 (this is for files with no slides)\r\n this.slidecount = data.slidecount ? Math.max(data.slidecount, 1) : 1;\r\n this.itemcount = data.itemcount;\r\n if (data.pagecount)\r\n this.pagecount = data.pagecount;\r\n this.filesize = data.filesize || 0;\r\n\r\n this.isslideshow = !!data.isslideshow;\r\n this.isshared = !!data.isshared;\r\n this.deleted = !!data.deleted;\r\n this.duplicate = !!data.duplicate;\r\n\r\n this.hasedits = !!data.hasedits;\r\n this.editable = !!data.editable;\r\n if (typeof data.editsXML == \"string\")\r\n this.editsXML = data.editsXML;\r\n if (typeof data.editFileName == \"string\")\r\n this.editFileName = data.editFileName;\r\n\r\n // Store the group or file name and extension\r\n this.name = data.name || data.filename;\r\n this.filename = data.filename;\r\n this.title = data.title;\r\n this.ext = data.filetypeextension || data.ext || '';\r\n if (data.sourceext)\r\n this.sourceext = data.sourceext;\r\n\r\n this.extrafields = data.extrafields;\r\n this.parentfields = data.parentfields;\r\n\r\n if (data.thumbnailid)\r\n this.thumbnailid = data.thumbnailid;\r\n\r\n this.setAddType(data.addType);\r\n\r\n if (typeof data.section == \"number\")\r\n this.section = data.section;\r\n if (typeof data.prestype == \"number\")\r\n this.prestype = data.prestype;\r\n\r\n // Save the category that this is being added from\r\n if (data.catId >= 0)\r\n this.catId = data.catId;\r\n // Edge case for group rule items\r\n else if (data.catid >= 0)\r\n this.catId = data.catid;\r\n else {\r\n var hashData = Librarian.Utils.getHash().parseQueryString();\r\n if (hashData.catid && hashData.type) {\r\n this.catId = hashData.catid;\r\n this.catType = hashData.type; \r\n }\r\n }\r\n\r\n // Set cat type\r\n if (typeof data.cattype == \"number\" || typeof data.catType == \"number\")\r\n this.catType = data.catType || data.cattype;\r\n\r\n // If there is a file name\r\n if (data.filename) {\r\n // And this is a global and we should show the global name, save that instead\r\n if ((this.groupid > 0) && !Librarian.cart.showGlobalFavoriteName)\r\n this.name = data.filename;\r\n\r\n // Or this is a my favorite and we should show the my favorite name, save that instead\r\n if ((this.presid > 0) && !Librarian.cart.showMyFavoriteName)\r\n this.name = data.filename;\r\n }\r\n\r\n // Rules Properties\r\n this.isDependent = !!data.isDependent;\r\n this.isTrigger = !!data.isTrigger;\r\n this.isIntegrity = !!data.isIntegrity;\r\n this.isOrdering = !!data.isOrdering;\r\n this.isGrouping = !!data.isGrouping;\r\n this.rules = data.rules || [];\r\n this.ruleItems = data.ruleItems || [];\r\n this.ruleGroup = data.ruleGroup || -1;\r\n if (data.orderindex >= 0)\r\n this.orderindex = data.orderindex;\r\n this.fromRules = !!data.fromRules;\r\n this.updateIsMandatory();\r\n this.updatePosition();\r\n\r\n // Keep track of items coming from wizards\r\n this.fromWizard = !!data.fromWizard;\r\n\r\n // Initialize the list of items\r\n this.items = new Librarian.Cart.List();\r\n },\r\n\r\n /*\r\n * Clears the list of children\r\n */\r\n destroy: function() {\r\n if (this.items) {\r\n this.items.clear();\r\n this.items = null;\r\n }\r\n },\r\n\r\n //#region Set Methods\r\n\r\n /*\r\n * Sets a child of this item to be deleted\r\n *\r\n * data - Data representing the child cart item to be marked as deleted\r\n */\r\n setItemDeleted: function(data) {\r\n // Sets a given child item deleted\r\n if (this.items)\r\n this.items.setItemDeleted(data);\r\n },\r\n\r\n /*\r\n * Sets how this item was added to the cart\r\n * Used to determine how things are displayed in MIXED view mode\r\n *\r\n * addType - Value representing how this item was originally added to the cart\r\n */\r\n setAddType: function(addType) {\r\n // If a valid addType was provided, save it\r\n if ((typeof addType != \"undefined\") && (addType != null) && (addType >= Librarian.Cart.addTypes.FILE)) {\r\n this.addType = addType;\r\n if (this.originalAddType == null)\r\n this.originalAddType = this.addType;\r\n }\r\n },\r\n\r\n /*\r\n * Sets the parent fields of the cart item\r\n * Also recalculates the isMandatory and cartPosition properties if the respective settings are enabled\r\n *\r\n * fields - The list of extra fields from this item's parent\r\n */\r\n setParentFields: function(fields) {\r\n this.parentfields = fields;\r\n this.updateIsMandatory();\r\n this.updatePosition();\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Get Methods\r\n\r\n /*\r\n * Gets the list of child items that match the given options\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n * addType - The type of item to include - Optional, If specified this will force all items in the list into the specified type. If not specified, items will be added as they were added to the list\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getItems: function(includeDeleted, addType, includeDuplicates) {\r\n return this.items ? this.items.getItems(includeDeleted, addType, includeDuplicates) : [];\r\n },\r\n\r\n /*\r\n * Gets the count of the child items that match the given options\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getSize: function(includeDeleted, includeDuplicates) {\r\n var size = 0;\r\n if (this.items)\r\n size = this.items.getSize(includeDeleted, null, includeDuplicates);\r\n if (this.isslideshow && (size == 0))\r\n size = 1;\r\n\r\n return size;\r\n },\r\n\r\n /*\r\n * Gets the count of child items that match the given options\r\n * If this does not have any child items, this item's data is used to determine the count\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getCount: function(includeDeleted, includeDuplicates) {\r\n // If we are not told to include deleted items, assume not\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n // If we aren't told whether to include duplicated items, assume we shouldn't\r\n if ((typeof includeDuplicates == \"undefined\") || (includeDuplicates == null))\r\n includeDuplicates = true;\r\n\r\n // If this has no children, ignoring the given settings\r\n if (this.getSize() == 0) {\r\n // If this is a slide, return 1\r\n if ((this.slideid > 0) || (this.addType == Librarian.Cart.addTypes.SLIDE))\r\n return 1;\r\n\r\n // Otherwise return the slide count (Shouldn't ever happen)\r\n return Math.max(this.slidecount, 1);\r\n }\r\n\r\n // Return the number of slides this item has\r\n // that match the requested deleted and duplicate state\r\n return this.getSize(includeDeleted, includeDuplicates);\r\n },\r\n\r\n /*\r\n * Gets the item at the location specified by `index`\r\n *\r\n * index - The location in this list that the item is being retrieved from\r\n */\r\n getItem: function(index) {\r\n return this.items ? this.items.items[index] : null;\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Boolean Methods\r\n\r\n /*\r\n * Determines whether this item equals the given data\r\n *\r\n * data - The data with which this is being compared for equality\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n equals: function(data, ignoreGroup) {\r\n return Librarian.Utils.isDataEqual(this, data);\r\n },\r\n\r\n /*\r\n * Determines whether this item is a child of the given parent item\r\n *\r\n * parentItem - The item against which this is being checked as a potential parent\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n isChildOf: function(parentItem, ignoreGroup) {\r\n // If we aren't told to ignore groups, assume not\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null))\r\n ignoreGroup = false;\r\n // If the parent isn't actually a parent,\r\n // this can't be its child\r\n if (parentItem.slidenumber > 0)\r\n return false;\r\n\r\n // If the given item is a parent item who is related to this item, it is this item's parent\r\n return this.isRelatedTo(parentItem, ignoreGroup);\r\n },\r\n\r\n /*\r\n * Determines whether this istem is the parent of a given child item\r\n */\r\n isParentOf: function(childItem) {\r\n // If this isn't actually a parent,\r\n // the child can't be its child\r\n if (this.slidenumber > 0)\r\n return false;\r\n\r\n // If this item is a parent item who is related to the given item, it is that item's parent\r\n return this.isRelatedTo(childItem);\r\n },\r\n\r\n /*\r\n * Determines whether this item is related to the given item\r\n *\r\n * item - The item against which this is being compared for relation\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n isRelatedTo: function(item, ignoreGroup) {\r\n // If we aren't told to ignore groups, assume not\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null))\r\n ignoreGroup = false;\r\n\r\n // If this isn't a group\r\n if (ignoreGroup || (this.groupid == 0)) {\r\n // Check if it's a virtual presentation\r\n if (!ignoreGroup && (this.presid != 0))\r\n return this.presid == item.presid;\r\n\r\n // If not, compare the file ids\r\n return this.fileid == item.fileid;\r\n }\r\n\r\n // Otherwise compare the group ids\r\n return this.groupid == item.groupid;\r\n },\r\n\r\n /*\r\n * Determines whether this item has the given item in its list of children\r\n *\r\n * item - The item which is being searched for within this item's list of children\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n contains: function(item, includeDeleted, ignoreGroup) {\r\n return this.items ? this.items.contains(item, includeDeleted, ignoreGroup) : false;\r\n },\r\n\r\n /*\r\n * Determines whether or not the given location has two items next to eachother in the same Rule Group\r\n *\r\n * index - The location at which to check for adjacent Rule Group items\r\n *\r\n * Returns true if this location has two rule group items next to eachother, false otherwise\r\n */\r\n isLocNextToRuleGroupItem: function(index) {\r\n if (!Librarian.userCart)\r\n return true;\r\n\r\n var targetItem = Librarian.userCart.getItem(index);\r\n // Only check grouping if we're dropping on an item that isn't in our group\r\n if (targetItem && targetItem.isGrouping && (targetItem.ruleGroup != this.ruleGroup)) {\r\n // Check if moving this item to this location will break the continuity of the group at the destination\r\n var prevItem = Librarian.userCart.getItem(index - 1);\r\n // If this is the previous item we are actually moving AFTER this item so we have to check the next item instead\r\n if (prevItem && prevItem.equals(this))\r\n prevItem = Librarian.userCart.getItem(index + 1);\r\n\r\n // If this item exists and its in the same group as the destination item then we're breaking the grouping rules\r\n if (prevItem && (prevItem.ruleGroup == targetItem.ruleGroup))\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n /*\r\n * Determines whether or not this item has mandatory items in its rule group\r\n */\r\n hasMandatoryRuleChildren: function() {\r\n if (!Librarian.cart.enableGroupRules || (this.ruleGroup <= 0) || !Librarian.userCart)\r\n return false;\r\n\r\n return (Librarian.userCart.getMandatoryItems(this.ruleGroup) || []).length > 0;\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Add/Remove\r\n\r\n /*\r\n * Adds the given item to this item's list of children\r\n *\r\n * item - Item to be added to this item's list\r\n * undelete - Whether to unmark the item for deletion if it already exists in this item's list of children\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n addItem: function(item, undelete, ignoreGroup) {\r\n if (!this.items)\r\n return;\r\n this.items.addItem(item, undelete, ignoreGroup);\r\n },\r\n\r\n /*\r\n * Removes the given item from this item's list of children\r\n *\r\n * item - Item to be removed from this item's list\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n removeItem: function(item, ignoreGroup) {\r\n if (!this.items)\r\n return;\r\n this.items.removeItem(item, ignoreGroup);\r\n },\r\n\r\n /*\r\n * Removes the children of the given item from this item's list of children\r\n *\r\n * item - Item whose children are to be removed from this item's list\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n removeItemChildren: function(item, ignoreGroup) {\r\n if (!this.items)\r\n return;\r\n this.items.removeItemChildren(item, ignoreGroup);\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Rules\r\n\r\n /*\r\n * Handles logic of automatically adding rule-based items for Dependent Trigger and Integrity Group items\r\n * as well as positioning of Ordering Group, Grouping Group, and fixed position items\r\n *\r\n * insert - Whether or not this item was added as the result of an insert operation\r\n * update - Whether or not to run the update rules after completing this operation\r\n */\r\n onAdd: function(insert, update) {\r\n if (!Librarian.cart.enableGroupRules || !Librarian.userCart)\r\n return;\r\n\r\n var doPositioning = function(thisItem) {\r\n // If we're not inserting and this thing should be at the end, we're already done\r\n // New items are added to the end automatically\r\n if (!insert && (thisItem.cartPosition == \"end\"))\r\n return;\r\n\r\n var itemIndex = Librarian.userCart.getItemIndex(thisItem);\r\n if (itemIndex < 0)\r\n return;\r\n\r\n // If this item is already at the beginning then we're already done\r\n if ((itemIndex == 0) && (thisItem.cartPosition == \"start\"))\r\n return;\r\n\r\n var cartItems = Librarian.userCart.getCartItems(true);\r\n // If this item is already at the end then we're already done\r\n if ((thisItem.cartPosition == \"end\") && (itemIndex == (cartItems.length - 1)))\r\n return;\r\n\r\n // Remove this item from it's position in the list\r\n Librarian.userCart.cartItems.items.remove(itemIndex);\r\n\r\n // Move this item in front of the first item in the list\r\n if (thisItem.cartPosition == \"start\")\r\n Librarian.userCart.cartItems.items.unshift(thisItem);\r\n // Move this item after the last item in the list\r\n else\r\n Librarian.userCart.cartItems.items.push(thisItem);\r\n\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_moved_rules\"));\r\n \r\n },\r\n doPositionedRules = function(thisItem) {\r\n if (!thisItem.isGrouping || !thisItem.isOrdering)\r\n return;\r\n\r\n var ruleItems = Librarian.userCart.getRuleGroupItems(thisItem.ruleGroup);\r\n // Don't bother doing anything if this is the only item in its group in the cart\r\n if (ruleItems.length <= 1)\r\n return;\r\n\r\n var sortByOrder = function(list) {\r\n return list.sort(function(a, b) {\r\n if (a.orderindex < b.orderindex)\r\n return -1;\r\n else if (a.orderindex > b.orderindex)\r\n return 1;\r\n return 0;\r\n });\r\n },\r\n insertBefore = function(list) {\r\n var thisIndex = Librarian.userCart.cartItems.indexOf(thisItem);\r\n Librarian.userCart.cartItems.insertItemsAt(list, thisIndex);\r\n },\r\n insertAfter = function(list) {\r\n var thisIndex = Librarian.userCart.cartItems.indexOf(thisItem);\r\n Librarian.userCart.cartItems.insertItemsAt(list, thisIndex + 1);\r\n },\r\n getRulesLists = function(beforeList, afterList) {\r\n // Sort each item in to the correct `before` or `after` list based on their position relative to this item\r\n for (var i = Librarian.userCart.cartItems.items.length; i--;) {\r\n var cartItem = Librarian.userCart.cartItems.items[i];\r\n if (!cartItem || (cartItem.ruleGroup != thisItem.ruleGroup) || (cartItem.orderindex == thisItem.orderindex))\r\n continue;\r\n\r\n var remove = false;\r\n // Add this item to the correct list\r\n if (cartItem.orderindex < thisItem.orderindex) {\r\n if (beforeList != null) {\r\n beforeList.push(cartItem);\r\n remove = true;\r\n }\r\n }\r\n else if (afterList != null) {\r\n afterList.push(cartItem);\r\n remove = true;\r\n }\r\n\r\n // Remove this item from the cart list for now\r\n if (remove)\r\n Librarian.userCart.cartItems.items.remove(i);\r\n }\r\n\r\n // Sort these lists if everything should be in order\r\n if (thisItem.isOrdering) {\r\n if (beforeList)\r\n beforeList = sortByOrder(beforeList);\r\n if (afterList)\r\n afterList = sortByOrder(afterList);\r\n }\r\n }\r\n\r\n // Apply grouping and ordering rules based on the fact that the newly added item cannot move but the other rules should still apply relative to it\r\n if (thisItem.isGrouping) {\r\n var beforeItems = [],\r\n afterItems = [];\r\n getRulesLists(beforeItems, afterItems);\r\n\r\n // Move these items to their correct position in the cart\r\n insertBefore(beforeItems);\r\n insertAfter(afterItems);\r\n }\r\n else {\r\n var afterItems = [];\r\n getRulesLists(null, afterItems);\r\n\r\n // Move all the items with a higher order index after this item in the cart\r\n insertAfter(afterItems);\r\n }\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_moved_rules\"));\r\n },\r\n doOrdering = function(thisItem) {\r\n var cartItems = Librarian.userCart.getCartItems(true);\r\n // Find the first thing from this same group whose order index is greater than this one's\r\n for (var i = 0, length = cartItems.length; i < length; i++) {\r\n var item = cartItems[i];\r\n // Only check items that are in the same rule group\r\n if (!item || (item.ruleGroup != thisItem.ruleGroup) || item.equals(thisItem, true))\r\n continue;\r\n\r\n // Find the first item that comes after this item and move this before it\r\n if (item.orderindex > thisItem.orderindex) {\r\n Librarian.userCart.moveItem(thisItem, item, update, true);\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_moved_rules\"));\r\n return;\r\n }\r\n }\r\n },\r\n doGrouping = function(thisItem) {\r\n var index = Librarian.userCart.getItemIndex(thisItem),\r\n nextItem = Librarian.userCart.getItem(index + 1);\r\n\r\n // Check to make sure this item isn't already grouped\r\n if ((nextItem != null) && (nextItem.ruleGroup == thisItem.ruleGroup))\r\n return;\r\n var prevItem = Librarian.userCart.getItem(index - 1);\r\n if ((prevItem != null) && (prevItem.ruleGroup == thisItem.ruleGroup))\r\n return;\r\n\r\n var cartItems = Librarian.userCart.getCartItems(true);\r\n // Find the last thing that is a part of this group\r\n for (var i = cartItems.length; i--;) {\r\n var item = cartItems[i];\r\n // Only check items that are in the same rule group\r\n if (!item || (item.ruleGroup != thisItem.ruleGroup) || item.equals(thisItem, true))\r\n continue;\r\n\r\n nextItem = Librarian.userCart.getItem(i + 1);\r\n // If the next item doesn't exist or this is the next item, there's nothing for us to do here\r\n if ((nextItem != null) && !nextItem.equals(thisItem)) {\r\n Librarian.userCart.moveItem(thisItem, nextItem, update, true);\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_moved_rules\"));\r\n return;\r\n }\r\n }\r\n };\r\n\r\n // Do cart positioning of this item based on set meta before doing anything else\r\n if (this.cartPosition) {\r\n doPositioning(this);\r\n doPositionedRules(this);\r\n }\r\n else if (Librarian.cart.itemPositionMetaName) {\r\n // Apply positioning to items added after \"end\" items by moving them before the \"end\" items while also not breaking their grouping\r\n var endItems = Librarian.userCart.getPositionedItems(\"end\", true);\r\n if (endItems.length > 0) {\r\n // Order of endItems matches the order from the cart, 100% of the time because \"filter\" is done using an in-order for loop\r\n var targetItem = endItems[0];\r\n\r\n // Don't break \"grouping\" rules if the target item has them\r\n if (targetItem.isGrouping) {\r\n // Get the list of this group's items and save the first one as the target\r\n var groupItems = Librarian.userCart.getGroupingItems(targetItem.ruleGroup, true);\r\n if (groupItems.length > 0)\r\n targetItem = groupItems[0];\r\n }\r\n\r\n var thisIndex = Librarian.userCart.getItemIndex(this),\r\n targetIndex = Librarian.userCart.getItemIndex(targetItem);\r\n // If this item isn't already before the target item, move it\r\n if (thisIndex > targetIndex) {\r\n Librarian.userCart.moveItem(this, targetItem, update, true);\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_moved_rules\"));\r\n }\r\n }\r\n }\r\n\r\n // Only run this rule check for dependent triggers and integrity group members that have content\r\n if ((this.isTrigger || this.isIntegrity) && (this.ruleItems.length > 0)) {\r\n var section = 0;\r\n\r\n var lastSection = Librarian.userCart.getLastSectionIndex();\r\n if (lastSection < 0)\r\n lastSection = null;\r\n\r\n // If we want to preserve grouping\r\n if (this.isGrouping) {\r\n section = this.section;\r\n }\r\n // Otherwise use the last section\r\n else {\r\n section = lastSection;\r\n }\r\n\r\n // Add each group member to the cart automatically\r\n var added = 0;\r\n for (var i = 0, length = this.ruleItems.length; i < length; i++) {\r\n var data = this.ruleItems[i];\r\n\r\n /* This doesn't make sense and causes the item to show up wrong. What was the intent?\r\n // Convert this item into a group item\r\n data.itemnumber = data.orderindex + 1;\r\n data.slidecount = this.ruleItems.length;\r\n data.sourceext = data.filetypeextension;\r\n data.ext = data.filetypeextension = \"favg\";\r\n data.name = data.groupname;\r\n */\r\n\r\n if (Librarian.userCart.isInCart(data, false, null, true))\r\n continue;\r\n\r\n // Convert some properties to how the cart is expecting them\r\n data.isDependent = this.isDependent;\r\n data.isTrigger = this.isTrigger;\r\n data.isIntegrity = this.isIntegrity;\r\n data.isOrdering = this.isOrdering;\r\n data.isGrouping = this.isGrouping;\r\n data.rules = this.rules;\r\n data.fromRules = true;\r\n data.ruleGroup = data.groupid;\r\n delete data.groupid;\r\n\r\n // If this is a trigger slide, all items we're adding are dependents\r\n if (this.isTrigger) {\r\n data.isDependent = true;\r\n data.isTrigger = false;\r\n }\r\n\r\n var cartItem = Librarian.userCart.addToCartEx(data, null, true, section, true);\r\n // Only increase the counter if we successfully added to the cart\r\n if (cartItem != null) {\r\n added++;\r\n\r\n // If this is an integrity item, copy the rules items over so it can handle its own rules\r\n if (this.isIntegrity)\r\n cartItem.ruleItems = this.ruleItems;\r\n\r\n // If the added item has a position set, make sure it is placed there\r\n var position = Librarian.Cart.Item.getItemPosition(cartItem);\r\n if (position) {\r\n doPositioning(cartItem);\r\n doPositionedRules(cartItem);\r\n }\r\n else {\r\n // Make sure the added item is in correct ordering\r\n if (cartItem.isOrdering)\r\n doOrdering(cartItem);\r\n\r\n // Don't bother calling this on add because everything is already grouped\r\n if ((insert === true) && cartItem.isGrouping)\r\n doGrouping(cartItem);\r\n }\r\n }\r\n }\r\n\r\n // Notify the user that some slide were automatically added\r\n if (added > 0) {\r\n if (this.isOrdering)\r\n Librarian.Utils.notification(Librarian.Lang.getPluralArgString(\"cart_added_moved_rules\", added, added));\r\n else\r\n Librarian.Utils.notification(Librarian.Lang.getPluralArgString(\"cart_added_rules\", added, added));\r\n\r\n\r\n // Update the changeboxes outside the cart\r\n Librarian.Utils.updateAllCheckboxes();\r\n }\r\n }\r\n // Don't run the other rules when adding something with position rules because the position rules item needs to be the anchor around which everything else moves\r\n else if (!this.cartPosition) {\r\n if (this.isOrdering)\r\n doOrdering(this);\r\n if (this.isGrouping)\r\n doGrouping(this);\r\n }\r\n },\r\n\r\n /*\r\n * Determines whether this item can be inserted at the given location without breaking group rules\r\n *\r\n * Returns true if this is a valid location, false otherwise\r\n */\r\n canInsert: function(destLoc) {\r\n if (!Librarian.cart.enableGroupRules || !Librarian.userCart)\r\n return true;\r\n\r\n var targetItem = Librarian.userCart.getItem(destLoc);\r\n // Make sure the position we are putting this item obeys forced ordering\r\n if (this.isOrdering) {\r\n // Get the entire list of items so we can check the destination position relative to the actual location of each item in the cart\r\n var cartItems = Librarian.userCart.getCartItems(true);\r\n // Find the first thing from this same group whose order index is greater than this one's\r\n for (var i = 0, length = cartItems.length; i < length; i++) {\r\n var item = cartItems[i];\r\n // Only check items that are in the same rule group\r\n if (!item || (item.ruleGroup != this.ruleGroup) || item.equals(this, true))\r\n continue;\r\n\r\n // If the found item should come after this item but the current position is before where we're trying to put this item,\r\n // that violates the Ordering of this group\r\n if ((this.orderindex > item.orderindex) && (i >= destLoc)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_insert_fail\"));\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n // Only bother checking grouping rules if there are other items in the cart in this same group\r\n if (this.isGrouping && Librarian.userCart.hasRuleGroupItem(this)) {\r\n var prev = destLoc - 1,\r\n found = false,\r\n isRuleItem = function(indexItem) {\r\n // If this item exists and the group matches, this is a valid position\r\n if ((indexItem != null) && (indexItem.ruleGroup == this.ruleGroup))\r\n return true;\r\n return false;\r\n }.bind(this);\r\n\r\n // If there is a previous item, check if it belongs to the same group\r\n if (prev >= 0) {\r\n if (isRuleItem(Librarian.userCart.getItem(prev)))\r\n found = true;\r\n }\r\n\r\n // If the previous item wasn't valid, check if the next item belongs to the same group\r\n if (!found) {\r\n if (isRuleItem(targetItem))\r\n found = true;\r\n }\r\n\r\n // If neither item on either side of the destination is in this group, grouping rules are violated\r\n if (!found) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_insert_fail\"));\r\n return false;\r\n }\r\n }\r\n\r\n // Only check the target item if there actually is one\r\n if (targetItem) {\r\n // If this item is not next to a rule group item we're breaking continuity\r\n if (this.isLocNextToRuleGroupItem(destLoc)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_insert_fail\"));\r\n return false;\r\n }\r\n\r\n // Only check groups that actually have rules\r\n // It's OK to break apart basic, pdf, and pptx groups\r\n var hasRules = (targetItem.ruleGroup > 0) && ((targetItem.rules || []).length > 0),\r\n addType = targetItem.originalAddType;\r\n if (typeof addType != \"number\")\r\n addType = targetItem.addType;\r\n // If the cart is in slide view and the target is a file item inside a group, make sure doing this insert won't break the file apart\r\n if (Librarian.userCart.isInSlideView() && hasRules && (addType == Librarian.Cart.addTypes.FILE) && (targetItem.slidenumber > 1)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_insert_fail\"));\r\n return false;\r\n }\r\n\r\n // Only check this logic if item positioning is enabled\r\n if (Librarian.cart.itemPositionMetaName) {\r\n var cartItems = null,\r\n checkPosition = function(start, end, position) {\r\n // Cache the list of cart items but only pull it if this method is called at least once\r\n if (cartItems == null)\r\n cartItems = Librarian.userCart.getCartItems(true);\r\n // If we're not given a valid end, go to the end of the list\r\n if (end < 0)\r\n end = cartItems.length;\r\n\r\n for (var idx = start; idx < end; idx++) {\r\n var cartItem = cartItems[idx];\r\n // Skip ones without position because we don't care where those are while doing this check\r\n // We only care if we're before a \"start\" or after an \"end\"\r\n if (!cartItem || !cartItem.cartPosition)\r\n continue;\r\n\r\n if (cartItem.cartPosition != position)\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n // Items inserted before \"start\" and after \"end\" should be blocked\r\n if (!checkPosition(0, destLoc, \"start\") || !checkPosition(destLoc, -1, \"end\")) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_insert_fail\"));\r\n return false;\r\n }\r\n }\r\n }\r\n return true;\r\n },\r\n\r\n /*\r\n * Handles logic of automatically adding rule-based items for Dependent Trigger and Integrity Group items after insert\r\n * Also handles moving items with fixed positions after they are dropped into the cart\r\n */\r\n onInsert: function() {\r\n if (this.isTrigger || this.isIntegrity || this.cartPosition)\r\n this.onAdd(true);\r\n },\r\n\r\n /*\r\n * Determines whether this item can be moved to the given location without breaking group rules\r\n *\r\n * Returns true if this is a valid location, false otherwise\r\n */\r\n canMove: function(destItem) {\r\n if (!Librarian.cart.enableGroupRules || !Librarian.userCart)\r\n return true;\r\n\r\n var destLoc = Librarian.userCart.getItemIndex(destItem, true);\r\n if (this.isOrdering) {\r\n // Can't reorder ordering items within the same group\r\n if (destItem.ruleGroup == this.ruleGroup) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_move_fail\"));\r\n return false;\r\n }\r\n // Check if moving this item to this location will break this item's ordering\r\n // Allow a group with Ordering and Grouping to be moved because the onMove code will move the rest of the group with it\r\n else if ((destLoc >= 0) && !this.isGrouping) {\r\n var currLoc = Librarian.userCart.getItemIndex(this),\r\n // Only get this group's items because we only care about where they are relative to eachother, we don't care about anything else in the cart\r\n cartItems = Librarian.userCart.getRuleGroupItems(this.ruleGroup, true),\r\n doCheck = function(idx, forward) {\r\n var item = cartItems[idx];\r\n // Don't check this same item\r\n if (!item || item.equals(this, true))\r\n return true;\r\n\r\n // If the item at this location's order index is less than this item's order index, putting this item in front of it will violate group rules\r\n if ((forward && (item.orderindex > this.orderindex)) || (item.orderindex < this.orderindex)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_move_fail\"));\r\n return false;\r\n }\r\n return true;\r\n }.bind(this);\r\n\r\n // If we're moving backwards in the cart, make sure the items with higher order index are all after this item\r\n if (currLoc < destLoc) {\r\n for (var i = currLoc; i < destLoc; i++) {\r\n if (!doCheck(i, true))\r\n return false;\r\n }\r\n }\r\n // Otherwise we're moving forwards and we need to make sure all items with lower order index are before this one\r\n else {\r\n for (var i = destLoc; i < currLoc; i++)\r\n if (!doCheck(i))\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n // Only check the target item if there actually is one\r\n if (destItem) {\r\n var thisLoc = Librarian.userCart.getItemIndex(this, true),\r\n checkLoc = destLoc;\r\n // If we're moving from before the current location then we need to check that we're not\r\n // breaking the NEXT location since this inserts after the `destItem`\r\n if (thisLoc < destLoc)\r\n checkLoc++;\r\n\r\n // If this item is not next to a rule group item we're breaking continuity\r\n if (this.isLocNextToRuleGroupItem(checkLoc)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_move_fail_target\"));\r\n return false;\r\n }\r\n\r\n // Only check groups that actually have rules\r\n // It's OK to break apart basic, pdf, and pptx groups\r\n var hasRules = (destItem.ruleGroup > 0) && ((destItem.rules || []).length > 0),\r\n addType = destItem.originalAddType;\r\n if (typeof addType != \"number\")\r\n addType = destItem.addType;\r\n // If the cart is in slide view and the target is a file item inside a group, make sure doing this insert won't break the file apart\r\n if (Librarian.userCart.isInSlideView() && hasRules && (addType == Librarian.Cart.addTypes.FILE) && (destItem.slidenumber > 1)) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_move_fail_target\"));\r\n return false;\r\n }\r\n\r\n // Only check this logic if item positioning is enabled\r\n if (Librarian.cart.itemPositionMetaName) {\r\n var cartItems = null,\r\n checkPosition = function(start, end, position, equals) {\r\n // Cache the list of cart items but only pull it if this method is called at least once\r\n if (cartItems == null)\r\n cartItems = Librarian.userCart.getCartItems(true);\r\n\r\n for (var idx = start; idx < end; idx++) {\r\n var cartItem = cartItems[idx];\r\n // Don't skip ones without position\r\n // We need to make sure we're not moving a \"start\" before a non-\"start\" or an \"end\" after a non-\"end\"\r\n if (!cartItem)\r\n continue;\r\n\r\n if ((equals && (cartItem.cartPosition == position)) ||\r\n (!equals && (cartItem.cartPosition != position)))\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n var canMove = true;\r\n // If either the current item or the destination item have a set position, make sure this move doesn't violate rules\r\n // If the positions are the same then allow them to move around eachother\r\n if (this.cartPosition && (this.cartPosition != destItem.cartPosition)) {\r\n // Don't allow moving \"end\" before non-\"end\"\r\n if (this.cartPosition == \"end\")\r\n canMove = checkPosition(destLoc, thisLoc, this.cartPosition);\r\n // Don't allow moving \"start\" after non-\"start\"\r\n else\r\n canMove = checkPosition(thisLoc + 1, destLoc + 1, this.cartPosition);\r\n }\r\n // Make sure moving this item doesn't violate the rules of other items in the cart\r\n else if (!this.cartPosition) {\r\n // Don't allow moving non-\"start\" before \"start\"\r\n canMove = checkPosition(destLoc, thisLoc, \"start\", true) &&\r\n // or non-\"end\" after \"end\"\r\n checkPosition(thisLoc + 1, destLoc + 1, \"end\", true);\r\n }\r\n\r\n // Report to the user if they cannot move this item and stop the move\r\n if (!canMove) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_move_fail_target\"));\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n\r\n /*\r\n * Handles the logic of automatically moving Grouping Group items together while maintaining order\r\n */\r\n onMove: function(oldLoc) {\r\n if (!Librarian.cart.enableGroupRules || (oldLoc < 0) || !this.isGrouping || !Librarian.userCart || !Librarian.userCart.hasRuleGroupItem(this))\r\n return;\r\n\r\n // Get this item's index, if it doesn't have one then don't bother continuing\r\n var index = Librarian.userCart.getItemIndex(this);\r\n if (index < 0)\r\n return;\r\n\r\n // Get the next and previous item\r\n var prevItem = Librarian.userCart.getItem(index - 1),\r\n nextItem = Librarian.userCart.getItem(index + 1),\r\n found = false;\r\n\r\n // If there is a previous item check if it matches the same group as this item\r\n if (prevItem && (prevItem.ruleGroup == this.ruleGroup))\r\n found = true;\r\n\r\n // If there is a next item check if it matches the same group as this item\r\n if (!found && nextItem && (nextItem.ruleGroup == this.ruleGroup))\r\n found = true;\r\n\r\n // If neither the next nor previous item are in the same group, we need to move all group members into position\r\n if (!found) {\r\n var moved = 0,\r\n previousItems = [],\r\n nextItems = [],\r\n cartItems = Librarian.userCart.getCartItems(true),\r\n offset = 0;\r\n\r\n // If we're moving to a smaller location, increase the offset so we start in the right place\r\n if (index < oldLoc)\r\n offset = 1;\r\n\r\n // Find any item from the group from before the old location, those items will be inserted before the new location\r\n for (var i = (oldLoc + offset); i--;) {\r\n var item = cartItems[i];\r\n if (item && (item.ruleGroup == this.ruleGroup) && !item.equals(this)) {\r\n cartItems.remove(i);\r\n previousItems.push(item);\r\n }\r\n }\r\n\r\n // Find any item from the group from after the old location, those items will be inserted after the new location\r\n for (var i = (oldLoc + offset) - previousItems.length, length = cartItems.length; i < length; i++) {\r\n var item = cartItems[i];\r\n if (item && (item.ruleGroup == this.ruleGroup) && !item.equals(this)) {\r\n cartItems.remove(i);\r\n nextItems.push(item);\r\n // Decrease the counter and length since we removed an item\r\n i--;\r\n length--;\r\n }\r\n }\r\n\r\n // If the new location is after the old location we need a negative offset for the items\r\n // so the location is correct when there are more grouped items than the index delta\r\n var beforeIndex = index,\r\n afterIndex = index + previousItems.length + offset;\r\n if (index > oldLoc) {\r\n // Adjust the index to compensate for the items that were removed to be moved to their correct locations\r\n beforeIndex -= (previousItems.length + nextItems.length);\r\n // Insert the items after the end of the previously added items and the item being dragged\r\n afterIndex = beforeIndex + previousItems.length + 1;\r\n }\r\n\r\n // Make sure these items are in the correct order before inserting them\r\n previousItems.sort(function(a, b) {\r\n if (a.orderindex < b.orderindex)\r\n return -1;\r\n else if (a.orderindex > b.orderindex)\r\n return 1;\r\n return 0;\r\n });\r\n\r\n // Insert all the items from before the old location before the new location as well\r\n Librarian.userCart.cartItems.insertItemsAt(previousItems, beforeIndex);\r\n moved += previousItems.length;\r\n // Insert all the items from after the old location after the new location as well\r\n Librarian.userCart.cartItems.insertItemsAt(nextItems, afterIndex);\r\n moved += nextItems.length;\r\n\r\n // If we moved anything, update the cart\r\n if (moved > 0) {\r\n // Fire onUpdate if it exists\r\n Librarian.userCart.onUpdate();\r\n\r\n Librarian.Cart.onChange();\r\n\r\n // And notify the user\r\n Librarian.Utils.notification(Librarian.Lang.getPluralArgString(\"cart_move_auto\", moved, moved));\r\n }\r\n }\r\n },\r\n\r\n /*\r\n * Determines whether this item can be removed from the cart and calls the cart's doRemoveFromCart if it can\r\n *\r\n * fromCart - Whether this request is coming from within the cart itself. If true, the item is marked as deleted, otherwise the item is removed - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item to remove from the cart - Optional, defaults to false\r\n * update - Whether to run the update function after this operation is complete - Optional, defaults to true\r\n * fromRules - Whether to bypass the \"allowed\" checks because this is from group rules - Optional, defaults to false\r\n * onRemove - Callback which is called after the remove has completed - Optional\r\n * onRemoveFail - Callback which is called if remove failed - Optional\r\n */\r\n canRemove: function(fromCart, ignoreGroup, update, fromRules, onRemove, onRemoveFail) {\r\n var doRemove = function(removeAutomaticallyAddedItemsOnly, bypassPostRulesCheck) {\r\n if (Librarian.userCart)\r\n Librarian.userCart.doRemoveFromCart(this, fromCart, ignoreGroup, update, bypassPostRulesCheck, onRemove, removeAutomaticallyAddedItemsOnly);\r\n }.bind(this);\r\n\r\n // Don't bother prompting or checking if this is being removed by rules unless this is a mandatory item\r\n var runRules = !fromRules || this.isMandatory;\r\n if (!Librarian.cart.enableGroupRules || !runRules || !Librarian.userCart) {\r\n doRemove(false, fromRules);\r\n return;\r\n }\r\n\r\n // Update the checkboxes if the user decided to abort the removal\r\n var abortRemoval = function() {\r\n // Update cart checkboxes\r\n if (fromCart)\r\n Librarian.Cart.onChange();\r\n\r\n Librarian.Utils.updateAllCheckboxes();\r\n if (typeof onRemoveFail == \"function\")\r\n onRemoveFail();\r\n },\r\n prompt = null;\r\n\r\n var isMandatory = this.isMandatory || this.hasMandatoryRuleChildren();\r\n if (isMandatory) {\r\n var itemType = Librarian.Utils.getItemType(this),\r\n message = \"cart_remove_mandatory_prompt\";\r\n\r\n // If this is the mandatory item then show the \"this is mandatory\" prompt\r\n if (this.isMandatory) {\r\n if (itemType == \"slide\")\r\n message = \"cart_remove_mandatory_slide_prompt\";\r\n else if (itemType == \"item\")\r\n itemType = \"file\";\r\n }\r\n // Otherwise this prompt is coming from a rule group\r\n else\r\n itemType = \"group\";\r\n\r\n // Prompt the removal of mandatory slides\r\n prompt = new Librarian.ConfirmWindow({\r\n id: this.fileid + \"-\" + this.slideid + \"-mandatory-confirm\",\r\n question: Librarian.Lang.getArgString(message, Librarian.Lang.getString(itemType).toLowerCase()),\r\n title: Librarian.Lang.getString(\"cart_remove_title\"),\r\n height: 100,\r\n width: 525,\r\n resize: false,\r\n defaultButton: 2\r\n });\r\n prompt.onFirstButtonClicked = Librarian.Cart.doClear;\r\n prompt.onSecondButtonClicked = abortRemoval;\r\n }\r\n else if (this.isIntegrity) {\r\n // Prompt for removal if outside the cart\r\n if (!fromCart) {\r\n // Prompt the removal of integrity slides\r\n prompt = new Librarian.ConfirmWindow({\r\n id: this.ruleGroup + \"-\" + this.slideid + \"-integrity-confirm\",\r\n question: Librarian.Lang.getString(\"cart_remove_integrity_prompt\"),\r\n title: Librarian.Lang.getString(\"cart_remove_title\"),\r\n height: 100,\r\n width: 500,\r\n resize: false,\r\n defaultButton: 2\r\n });\r\n prompt.onFirstButtonClicked = doRemove.pass([false, fromRules]);\r\n prompt.onSecondButtonClicked = abortRemoval;\r\n }\r\n }\r\n else if (this.isDependent) {\r\n // Prompt for removal if outside the cart\r\n if (!fromCart) {\r\n var triggerSlides = Librarian.userCart.getTriggerItems(this.ruleGroup);\r\n // Prompt the removal of the trigger slides if there are any\r\n if (triggerSlides.length > 0) {\r\n prompt = new Librarian.ConfirmWindow({\r\n id: this.ruleGroup + \"-\" + this.slideid + \"-dependent-confirm\",\r\n question: Librarian.Lang.getString(\"cart_remove_trigger_prompt\"),\r\n title: Librarian.Lang.getString(\"cart_remove_title\"),\r\n height: 100,\r\n width: 500,\r\n resize: false,\r\n defaultButton: 2\r\n });\r\n prompt.onFirstButtonClicked = doRemove.pass([false, fromRules]);\r\n prompt.onSecondButtonClicked = abortRemoval;\r\n }\r\n }\r\n }\r\n else if (this.isTrigger) {\r\n // Prompt for removal if there is only 1 trigger left\r\n var triggerSlides = Librarian.userCart.getTriggerItems(this.ruleGroup);\r\n if (triggerSlides && (triggerSlides.length <= 1)) {\r\n prompt = new Librarian.ConfirmWindow({\r\n id: this.ruleGroup + \"-\" + this.slideid + \"-trigger-confirm\",\r\n question: Librarian.Lang.getString(\"cart_remove_dependent_prompt\"),\r\n title: Librarian.Lang.getString(\"cart_remove_title\"),\r\n height: 170,\r\n width: 500,\r\n resize: false,\r\n useThirdButton: true,\r\n useFourthButton: true,\r\n firstButtonText: Librarian.Lang.getString(\"yes\"),\r\n secondButtonText: Librarian.Lang.getString(\"yes_all\"),\r\n thirdButtonText: Librarian.Lang.getString(\"no\"),\r\n fourthButtonText: Librarian.Lang.getString(\"cancel\"),\r\n defaultButton: 4\r\n });\r\n // Remove this item and all items that came along the item\r\n prompt.onFirstButtonClicked = doRemove.pass([true, fromRules]);\r\n // Remove this item and all items belonging to the same Rule Id\r\n prompt.onSecondButtonClicked = doRemove.pass([false, fromRules]);\r\n // Remove this item but do not remove related items; set fromRules = false to bypass post remove rules\r\n prompt.onThirdButtonClicked = doRemove.pass([false, true]);\r\n prompt.onFourthButtonClicked = abortRemoval;\r\n }\r\n }\r\n\r\n // Prompt before removing the item\r\n if (prompt) {\r\n prompt.show();\r\n return;\r\n }\r\n\r\n doRemove(false, fromRules);\r\n },\r\n\r\n /*\r\n * Handles logic of automatically removing rule-based items for Dependent, Trigger and Integrity Group items after removal\r\n *\r\n * fromCart - Whether this request is coming from within the cart itself. If true, the item is marked as deleted, otherwise the item is removed - Optional, defaults to false\r\n * removeAutomaticallyAddedItemsOnly - Used by the post remove rules to determine whether or not to only remove items that were added automatically\r\n */\r\n onRemove: function(fromCart, removeAutomaticallyAddedItemsOnly) {\r\n if (!Librarian.cart.enableGroupRules || !Librarian.userCart)\r\n return;\r\n\r\n var removeSlideList = function(type, filter, notify) {\r\n // Find all the items for this type\r\n var list = Librarian.userCart[\"get\" + type.toCapitalCase() + \"Items\"](this.ruleGroup);\r\n // Filter items unless we're told not to\r\n if (filter !== false) {\r\n list = list.filter(function(item) {\r\n return item.fromRules;\r\n });\r\n }\r\n\r\n if (list.length > 0) {\r\n // Remove them all\r\n for (var i = 0, len = list.length; i < len; i++)\r\n Librarian.userCart.doRemoveFromCart(list[i], fromCart, null, true, true);\r\n\r\n // If within cart and we're not told to not notify, notify that these items were removed\r\n if (fromCart && (notify !== false)) {\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_remove_\" + type + \"_notify\"));\r\n }\r\n \r\n // Refresh cart\r\n Librarian.Cart.onChange();\r\n }\r\n }.bind(this);\r\n\r\n // On removal of items under forced integrity when a group item is removed...\r\n if (this.isIntegrity)\r\n removeSlideList(\"integrity\", false);\r\n // If there are no more triggers, remove the dependent items as well\r\n else if (this.isTrigger) {\r\n var triggerSlides = Librarian.userCart.getTriggerItems(this.ruleGroup);\r\n if (triggerSlides && (triggerSlides.length <= 0)) {\r\n if (removeAutomaticallyAddedItemsOnly)\r\n removeSlideList(\"dependent\", true, false);\r\n else\r\n removeSlideList(\"dependent\", false);\r\n }\r\n }\r\n // If this is a dependent that was removed, remove all the triggers\r\n else if (this.isDependent)\r\n removeSlideList(\"trigger\", false);\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Updates\r\n\r\n /*\r\n * Updates the duplicate state of all the items in this item's list of children\r\n */\r\n updateDuplicateState: function() {\r\n if (!this.items)\r\n return;\r\n this.items.updateDuplicateState();\r\n },\r\n\r\n /*\r\n * Updates the property that determines whether an item is mandatory in the cart\r\n * If the item does not have a value explicitly set then it will default to the parent's value, if that is available\r\n */\r\n updateIsMandatory: function() {\r\n if (!Librarian.cart.enableGroupRules || !Librarian.cart.mandatoryItemMetaName)\r\n return;\r\n\r\n var itemValue = this.extrafields && this.extrafields[Librarian.cart.mandatoryItemMetaName],\r\n parentValue = this.parentfields && this.parentfields[Librarian.cart.mandatoryItemMetaName];\r\n\r\n this.isMandatory = (itemValue == \"true\") ||\r\n ((itemValue == '') && (parentValue == \"true\"));\r\n },\r\n\r\n /*\r\n * Updates the property that determines where an item must stay within the cart\r\n * If the item does not have a value explicitly set then it will default to the parent's value, if that is available\r\n */\r\n updatePosition: function() {\r\n this.cartPosition = Librarian.Cart.Item.getItemPosition(this);\r\n }\r\n\r\n //#endregion\r\n});\r\n\r\nLibrarian.Cart.Item.extend({\r\n /*\r\n * Converts the given item into a file-level cart item\r\n */\r\n makeParent: function(data) {\r\n var parentItem = new Librarian.Cart.Item(data);\r\n\r\n // Change this item into a probable parent\r\n // That means the slide number is 0\r\n parentItem.slidenumber = 0;\r\n // and the slide ID is 0\r\n parentItem.slideid = 0;\r\n // and there is no item number either\r\n parentItem.itemnumber = 0;\r\n // If this data has a file name, use that as the \"name\" of this item\r\n if (data.filename)\r\n parentItem.name = data.filename;\r\n\r\n return parentItem;\r\n },\r\n\r\n /*\r\n * Gets the property that determines where an item must stay within the cart\r\n * If the item does not have a value explicitly set then it will default to the parent's value, if that is available\r\n */\r\n getItemPosition: function(data) {\r\n if (!Librarian.cart.enableGroupRules || !Librarian.cart.itemPositionMetaName)\r\n return null;\r\n\r\n var itemValue = ((data.extrafields && data.extrafields[Librarian.cart.itemPositionMetaName]) || '').trim().toLowerCase(),\r\n parentValue = ((data.parentfields && data.parentfields[Librarian.cart.itemPositionMetaName]) || '').trim().toLowerCase();\r\n\r\n if (itemValue.length > 0)\r\n return itemValue;\r\n else if (parentValue.length > 0)\r\n return parentValue;\r\n return null;\r\n }\r\n});","Librarian.Cart.List = new Class({\r\n Binds: [\"addItem\"],\r\n // The items stored in this list\r\n items: null,\r\n\r\n /*\r\n * Creates a new empty List instance\r\n */\r\n initialize: function() {\r\n this.items = [];\r\n },\r\n\r\n /*\r\n * Destroys every item stored in the current list and resets it to empty\r\n */\r\n clear: function() {\r\n for (var i = 0; i < this.items.length; i++) {\r\n this.items[i].destroy();\r\n this.items[i] = null;\r\n }\r\n\r\n this.items.length = 0;\r\n },\r\n\r\n //#region Get Methods\r\n\r\n /*\r\n * Gets the count of the items in this list which match the given options\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n * addType - The type of item to count - Optional, If specified this will force all items in the list into the specified type before counting. If not specified, items will be counted as they were added to the list\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getSize: function(includeDeleted, addType, includeDuplicates) {\r\n // If we aren't told whether to include deleted items, assume we should\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = true;\r\n\r\n return this.getItems(includeDeleted, addType, includeDuplicates).length;\r\n },\r\n\r\n /*\r\n * Gets the items in this list that match the given options\r\n *\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to true\r\n * addType - The type of item to include - Optional, If specified this will force all items in the list into the specified type. If not specified, items will be added as they were added to the list\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to true\r\n */\r\n getItems: function(includeDeleted, addType, includeDuplicates) {\r\n // If we aren't told whether to include deleted items, assume we shouldn't\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n // If we aren't told whether to include duplicated items, assume we shouldn't\r\n if ((typeof includeDuplicates == \"undefined\") || (includeDuplicates == null))\r\n includeDuplicates = true;\r\n\r\n // If we are included deleted items and aren't looking for a specific type\r\n // of item, it's just as simple as returning every item\r\n if (includeDeleted && ((typeof addType == \"undefined\") || (addType == null))) {\r\n // If we include duplicates, it's literally just this list\r\n if (Librarian.cart.allowDuplicates || includeDuplicates)\r\n return this.items;\r\n // Otherwise filter out the duplicates\r\n else {\r\n return this.items.filter(function(item) {\r\n return !item.duplicate;\r\n });\r\n }\r\n }\r\n\r\n var items = [],\r\n // Use custom contains and indexOf methods so we can use our item's `equals` method\r\n contains = function(item, ignoreGroup) {\r\n return items.some(function(currentItem) {\r\n return item.equals(currentItem, ignoreGroup);\r\n });\r\n },\r\n indexOf = function(item) {\r\n for (var j = 0; j < items.length; j++) {\r\n if (item.equals(items[j]))\r\n return j;\r\n }\r\n\r\n return -1;\r\n };\r\n\r\n // Otherwise, we have to iterate through each item\r\n for (var i = 0; i < this.items.length; i++) {\r\n // Skip the duplicate ones and deleted ones (only if we're told not to include them)\r\n if ((!includeDeleted && this.items[i].deleted) || (!includeDuplicates && this.items[i].duplicate))\r\n continue;\r\n\r\n // If this is a file inside a group, don't add it to the parent group if there is one\r\n // Fixes a case creating a package from two files in a group would only add the first file to the list\r\n var ignoreGroup = ((this.items[i].groupid > 0) || (this.items[i].presid > 0)) && (this.items[i].slideid <= 0) && (this.items[i].fileid > 0);\r\n\r\n // If this was added as a file and we want to see slides,\r\n // add all of its slides as items in the items array\r\n if ((addType == Librarian.Cart.addTypes.SLIDE) && (this.items[i].addType == Librarian.Cart.addTypes.FILE)) {\r\n // Add each of this item's children, if there are any\r\n if (this.items[i].items) {\r\n var childItems = this.items[i].items.getItems(includeDeleted, null, includeDuplicates);\r\n // Treat SlideShows and locked files differently because they don't have any items\r\n if ((childItems.length == 0) && (this.items[i].isslideshow || ((this.items[i].flags & Librarian.fileFlags.passwordProtected) == Librarian.fileFlags.passwordProtected)) && !contains(this.items[i], ignoreGroup))\r\n items.push(this.items[i]);\r\n else\r\n items.append(childItems);\r\n }\r\n // Otherwise just add this (if it's not there already)\r\n else if (!contains(this.items[i], ignoreGroup))\r\n items.push(this.items[i]);\r\n }\r\n // If this was added as a slide and we want to see files\r\n else if ((addType == Librarian.Cart.addTypes.FILE) && (this.items[i].addType == Librarian.Cart.addTypes.SLIDE)) {\r\n // Make this item's parent\r\n var parentFile = Librarian.Cart.Item.makeParent(this.items[i]);\r\n\r\n // If we don't already have this item in the files list, add it\r\n if (!contains(parentFile)) {\r\n parentFile.addItem(this.items[i]);\r\n items.push(parentFile);\r\n }\r\n else {\r\n var parentIndex = indexOf(parentFile);\r\n items[parentIndex].addItem(this.items[i]);\r\n }\r\n }\r\n // Otherwise just add this item straight, if we don't already have it\r\n else if (!contains(this.items[i], ignoreGroup))\r\n items.push(this.items[i]);\r\n }\r\n\r\n return items;\r\n },\r\n\r\n /*\r\n * Gets the specified item or its parent, whichever exists in the list\r\n *\r\n * data - The data for which to get the representative cart item or its parent\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n getParentOrItemItself: function(data, ignoreGroup) {\r\n // If we aren't told to ignore groups, assume not.\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null))\r\n ignoreGroup = false;\r\n // Create an item out of the data given\r\n var item = new Librarian.Cart.Item(data),\r\n // Check if this item is in the list\r\n itemIndex = this.indexOf(item, true, ignoreGroup);\r\n\r\n item.destroy();\r\n item = null;\r\n\r\n // If it is, return that item.\r\n if (itemIndex >= 0)\r\n return this.items[itemIndex];\r\n\r\n // Otherwise, change this item into a probable parent\r\n item = Librarian.Cart.Item.makeParent(data);\r\n\r\n // If this list doesn't contain the parent, return null\r\n var parentIndex = this.indexOf(item, true, ignoreGroup);\r\n\r\n // Destroy the created parent item\r\n item.destroy();\r\n item = null;\r\n\r\n if (parentIndex < 0)\r\n return null;\r\n\r\n // Otherwise return the parent itself\r\n return this.items[parentIndex];\r\n },\r\n\r\n /*\r\n * Gets the data stored at the given index within the list\r\n *\r\n * index - The location from which to get data\r\n */\r\n getItem: function(index) {\r\n return this.items[index];\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Set Methods\r\n\r\n /*\r\n * Sets the item in this list at the given index to the given value\r\n *\r\n * index - The location to insert the given value at\r\n * value - The data to insert into the list\r\n */\r\n setItem: function(index, value) {\r\n // Only set the item if the given index is valid.\r\n if (!value || (index < 0) || (index >= this.items.length))\r\n return;\r\n\r\n this.items[index] = value;\r\n },\r\n\r\n /*\r\n * Sets the list item represented by the given data to be deleted\r\n *\r\n * data - The data whose list item is being set to be deleted\r\n */\r\n setItemDeleted: function(data) {\r\n if (!data)\r\n return;\r\n\r\n // Get the parent item if there is one\r\n var parentItem = this.getParentOrItemItself(data);\r\n\r\n if (parentItem) {\r\n // If this item is just the data wrapped\r\n // in an object set it to deleted\r\n if (parentItem.equals(data))\r\n parentItem.deleted = true;\r\n else {\r\n // Otherwise split this parent item into its slides\r\n this.splitFileAndAddInPlace(parentItem);\r\n // Find the slide for this item\r\n var index = this.indexOf(data);\r\n // And set it to deleted\r\n this.items[index].deleted = true;\r\n }\r\n }\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Add/Remove\r\n\r\n /*\r\n * Adds the given item to this list\r\n *\r\n * item - Item to be added to the list\r\n * undelete - Whether to undelete this item if it already exists in the list - Optional, defaults to true\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n *\r\n * Returns the item or its parent if it has one\r\n */\r\n addItem: function(item, undelete, ignoreGroup) {\r\n // If we aren't told whether or not to undelete a deleted item, assume we should\r\n if ((typeof undelete == \"undefined\") || (undelete == null))\r\n undelete = true;\r\n\r\n // Try to get the parent, if there is one\r\n var parentItem = this.getParentOrItemItself(item, ignoreGroup);\r\n if (parentItem) {\r\n // If we just got ourselves, check if it is deleted\r\n if (parentItem.equals(item, ignoreGroup)) {\r\n // If it is deleted and we're allowed to undelete, do so\r\n if (parentItem.deleted && undelete)\r\n parentItem.deleted = false;\r\n\r\n // Return the parentItem instead of the item because object references\r\n // matter when expanding the item into it's individual slides\r\n // If \"item\" was returned here, the parent in cartItems wouldn't get\r\n // it's child slides added to it\r\n return parentItem;\r\n }\r\n // The parent handles duplication checks and unsetting\r\n // the \"deleted\" flag when adding children\r\n else\r\n parentItem.addItem(item);\r\n }\r\n // If there's no parent, just add the item straight up\r\n else\r\n this.items.push(item);\r\n\r\n // Return the new item\r\n return item;\r\n },\r\n\r\n /*\r\n * Removes the item that represents the given data from this list\r\n *\r\n * data - The data whose representative item in this list is going to be removed\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n *\r\n * Returns true if the removal succeeded, false otherwise\r\n */\r\n removeItem: function(data, ignoreGroup) {\r\n // If we aren't told to ignore groups, assume not\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null))\r\n ignoreGroup = false;\r\n\r\n // Get the index of the item to remove, even if it's deleted\r\n var index = this.indexOf(data, true, ignoreGroup);\r\n\r\n // If this item wasn't found and it was a slide\r\n if ((index < 0) && (data.slidenumber > 0)) {\r\n // Try to find its file\r\n index = this.indexOfParent(data, true);\r\n // If the file was found\r\n if (index >= 0) {\r\n var item = this.items[index];\r\n // Split it into its slides\r\n this.splitFileAndAddInPlace(item);\r\n // and find the index of this slide now\r\n index = this.indexOf(data, true, ignoreGroup);\r\n }\r\n }\r\n\r\n return this.removeItemByIndex(index);\r\n },\r\n\r\n /*\r\n * Removes the item in this list at the given index\r\n *\r\n * Returns true if the removeal succeeded, false otherwise\r\n */\r\n removeItemByIndex: function(index) {\r\n // If the item exists, cut it out and return true\r\n if (index >= 0) {\r\n this.items.splice(index, 1);\r\n return true;\r\n }\r\n\r\n // Otherwise return false to show we didn't remove anything\r\n return false;\r\n },\r\n\r\n /*\r\n * Removes every item in this list who is a child of the given `parentItem`\r\n *\r\n * parentItem - The parent item whose children are to be removed from this list\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n */\r\n removeItemChildren: function(parentItem, ignoreGroup) {\r\n // If we aren't told to ignore groups, assume not\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null))\r\n ignoreGroup = false;\r\n // If the parent isn't actually a parent, this can't be its child\r\n if ((parentItem.slidenumber > 0) || (parentItem.itemnumber > 0))\r\n return;\r\n\r\n // For every item in this list\r\n for (var i = 0, length = this.getSize(); i < length; i++) {\r\n // Check if it is a child of the given parent and remove it\r\n if (this.items[i].isChildOf(parentItem, ignoreGroup)) {\r\n // If it removes, decrement the counter so that\r\n // when it is incremented we don't skip an item\r\n if (this.removeItemByIndex(i)) {\r\n i--;\r\n length--;\r\n }\r\n }\r\n }\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Array Overrides and Expansions\r\n\r\n //#region Index Of\r\n\r\n /*\r\n * Finds the index of the item in this list which represents the given data\r\n *\r\n * data - Data whose representative list item is being found\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n *\r\n * Returns the index of the item or -1 if it is not in this list\r\n */\r\n indexOf: function(data, includeDeleted, ignoreGroup, includeSubItems) {\r\n // If we aren't told to ignore groups, assume not\r\n if ((typeof ignoreGroup == \"undefined\") || (ignoreGroup == null))\r\n ignoreGroup = false;\r\n // If we aren't told whether or not to find deleted files, assume not\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n\r\n var item;\r\n // For every item in this list\r\n if (includeSubItems) {\r\n for (var i = 0, length = this.getSize(); i < length; i++) {\r\n item = this.items[i];\r\n if (item.items && item.items.items && item.items.items.length > 0) {\r\n for (var j = 0, subLength = item.items.getSize(); j < subLength; j++) {\r\n var subItem = item.items.items[j];\r\n // Skip it if it is deleted and we don't want deleted items\r\n if (!includeDeleted && item.deleted)\r\n continue;\r\n\r\n // Otherwise check if it the item we're looking for\r\n if (subItem.equals(data, ignoreGroup))\r\n return j;\r\n }\r\n } else {\r\n // Skip it if it is deleted and we don't want deleted items\r\n if (!includeDeleted && item.deleted)\r\n continue;\r\n\r\n // Otherwise check if it the item we're looking for\r\n if (item.equals(data, ignoreGroup))\r\n return i;\r\n }\r\n }\r\n } \r\n else {\r\n for (var i = 0, length = this.getSize(); i < length; i++) {\r\n item = this.items[i];\r\n\r\n // Skip it if it is deleted and we don't want deleted items\r\n if (!includeDeleted && item.deleted)\r\n continue;\r\n\r\n // Otherwise check if it the item we're looking for\r\n if (item.equals(data, ignoreGroup))\r\n return i;\r\n }\r\n }\r\n\r\n // If we didn't find the right item, return -1 as a default\r\n return -1;\r\n },\r\n\r\n /*\r\n * Finds the index of the item in this list which represents the given parent of the data\r\n *\r\n * childItem - Item for which the parent list item is being found\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n indexOfParent: function(childItem, includeDeleted) {\r\n // If we aren't told whether or not to find deleted files, assume not.\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n\r\n var item;\r\n // Find the index of the first non-deleted parent of the given child.\r\n for (var i = 0, length = this.getSize() ; i < length; i++) {\r\n item = this.items[i];\r\n\r\n // Skip it if it is deleted and we don't want deleted items.\r\n if (!includeDeleted && item.deleted)\r\n continue;\r\n\r\n // Otherwise check if this is the parent of the item we're looking for\r\n if (item.isParentOf(childItem))\r\n return i;\r\n }\r\n\r\n // If this list doesn't have any parents for that child, return -1\r\n return -1;\r\n },\r\n\r\n /*\r\n * Finds the index of the last item in this list which is a child of the given `parentItem`\r\n *\r\n * parentItem - Item for which the last child list item is being found\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n lastIndexOfChild: function(parentItem, includeDeleted) {\r\n // If we aren't told whether or not to find deleted files, assume not.\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n\r\n var item;\r\n // Find the index of the last non-deleted child of the given parent.\r\n for (var i = this.getSize() - 1; i >= 0; i--) {\r\n item = this.items[i];\r\n\r\n if (!includeDeleted && item.deleted)\r\n continue;\r\n\r\n if (item.isChildOf(parentItem))\r\n return i;\r\n }\r\n\r\n // If this list doesn't have any children of that parent, return -1\r\n return -1;\r\n },\r\n\r\n /*\r\n * Finds the index of the first item in this list which is a child of the given `parentItem`\r\n *\r\n * parentItem - Item for which the first child list item is being found\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n */\r\n firstIndexOfChild: function(parentItem, includeDeleted) {\r\n // If we aren't told whether or not to find deleted files, assume not.\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n\r\n var item;\r\n // Find the index of the first non-deleted child of the given parent.\r\n for (var i = 0, length = this.getSize() ; i < length; i++) {\r\n item = this.items[i];\r\n\r\n if (!includeDeleted && item.deleted)\r\n continue;\r\n\r\n if (item.isChildOf(parentItem))\r\n return i;\r\n }\r\n\r\n // If this list doesn't have any children of that parent, return -1\r\n return -1;\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Contains\r\n\r\n /*\r\n * Determines whether the given data exists in the list and is marked for deletion\r\n *\r\n * data - Data to find the representative list item of\r\n *\r\n * Returns true if the item is found and is marked for deletion, false otherwise\r\n */\r\n containsDeleted: function(data) {\r\n var item;\r\n // For every item in this list\r\n for (var i = 0, length = this.getSize(); i < length; i++) {\r\n item = this.items[i];\r\n\r\n // Skip it if it isn't deleted\r\n if (!item.deleted)\r\n continue;\r\n\r\n // Otherwise check if it the item we're looking for.\r\n if (item.equals(data))\r\n return true;\r\n }\r\n\r\n // If we didn't find the right item, return false\r\n return false;\r\n },\r\n\r\n /*\r\n * Determines whether the given data exists in the list and matches the given options\r\n *\r\n * data - Data to find the representative list item of\r\n * includeDeleted - Whether to include items that are unchecked in the cart - Optional, defaults to false\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item or its parent - Optional, defaults to false\r\n * includeDuplicates - Whether to include items that are duplicated in the cart - Optional, defaults to false\r\n */\r\n contains: function (data, includeDeleted, ignoreGroup, includeDuplicates) {\r\n // If we aren't told whether to include duplicated items, assume we shouldn't\r\n if ((typeof includeDeleted == \"undefined\") || (includeDeleted == null))\r\n includeDeleted = false;\r\n // If we aren't told whether to include duplicated items, assume we shouldn't\r\n if ((typeof includeDuplicates == \"undefined\") || (includeDuplicates == null))\r\n includeDuplicates = false;\r\n\r\n var dataItem = new Librarian.Cart.Item(data);\r\n\r\n // Returns true if at least 1 of the items in this list is equal\r\n // and it is either not deleted, or deleted items are allowed.\r\n return this.items.some(function(item) {\r\n var flag = true;\r\n\r\n // If this item is deleted, check whether we allow that or not.\r\n if (item.deleted)\r\n flag = (item.deleted === includeDeleted);\r\n if (!includeDuplicates && item.duplicate)\r\n flag = false;\r\n\r\n // The deleted status needs to be allowed AND the items\r\n // need to match for this to be true.\r\n //return flag && dataItem.equals(item, ignoreGroup) || (item.contentId == dataItem.contentId && item.contentType == dataItem.contentType);\r\n return flag && dataItem.equals(item, ignoreGroup);\r\n });\r\n },\r\n\r\n //#endregion\r\n\r\n /*\r\n * Adds the given item to the end of the list\r\n *\r\n * item - The item to be added to the list\r\n */\r\n push: function(item) {\r\n return this.items.push(item);\r\n },\r\n\r\n /*\r\n * Determines whether any of the items in the list matches the given predicate function\r\n *\r\n * func - Boolean function which checks whether the given item matches a set of search criteria\r\n */\r\n some: function(func) {\r\n return this.items.some(func);\r\n },\r\n\r\n /*\r\n * Filters the list of items to only contain items that match the given predicate function\r\n *\r\n * func - Boolean function which checks whether the given item matches a set of search criteria\r\n */\r\n filter: function(func) {\r\n return this.items.filter(func);\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Helper Methods\r\n\r\n /*\r\n * Determines whether this list has any deleted items\r\n */\r\n hasDeleted: function() {\r\n var item;\r\n // For every item in this list\r\n for (var i = 0, length = this.getSize(); i < length; i++) {\r\n item = this.items[i];\r\n\r\n // Skip it if it isn't deleted\r\n if (!item.deleted)\r\n continue;\r\n\r\n // If we ever get here, we have a deleted item\r\n return true;\r\n }\r\n\r\n // If we ever get here, we don't have a deleted item\r\n return false;\r\n },\r\n\r\n /*\r\n * Splits the given file item into its contained slide items which are then inserted at the same location the file once occupied\r\n *\r\n * data - File item to be split into slides\r\n */\r\n splitFileAndAddInPlace: function(data) {\r\n // Only files are splitable\r\n if (data.addType != Librarian.Cart.addTypes.FILE)\r\n return;\r\n\r\n var index = this.indexOf(data, true),\r\n item = this.items[index],\r\n items = [];\r\n // Get each child of this item\r\n for (var i = 0, length = item.getSize(); i < length; i++) {\r\n var slide = item.getItem(i);\r\n\r\n // If this is a group, set the item number\r\n if ((slide.groupid > 0) || (slide.presid > 0))\r\n slide.itemnumber = (i + 1);\r\n // Otherwise, set the slide number\r\n else if (slide.fileid > 0)\r\n slide.slidenumber = (i + 1);\r\n\r\n // Change it to a Slide\r\n slide.addType = Librarian.Cart.addTypes.SLIDE;\r\n // Save its extra fields\r\n slide.parentfields = item.extrafields;\r\n // And save it\r\n items.push(slide);\r\n }\r\n\r\n // Remove the item at this index and add all the split items we just created\r\n this.removeItemByIndex(index);\r\n this.insertItemsAt(items, index);\r\n },\r\n\r\n /*\r\n * Moves an item in the list in front of a second item\r\n *\r\n * firstItem - The item to be moved\r\n * secondItem - The item in front of which the first item will be moved\r\n * ignoreGroup - Whether to ignore the group properties of the data when finding the item - Optional, defaults to false\r\n */\r\n moveItem: function(firstItem, secondItem, ignoreGroup) {\r\n // If the cart isn't valid, somehow, we can't continue past this point\r\n if (!Librarian.userCart)\r\n return;\r\n\r\n var fromParent = false, toParent = false;\r\n // Get the indeces for the given items\r\n if (Librarian.userCart.isInSlideView()) {\r\n // If this was added as a file\r\n if (firstItem.addType == Librarian.Cart.addTypes.FILE) {\r\n // And we're not dropping it on the first slide,\r\n // split it into its individual slides\r\n if (firstItem.slidenumber > 1)\r\n this.splitFileAndAddInPlace(Librarian.Cart.Item.makeParent(firstItem));\r\n // Otherwise, remember to get the parent index instead\r\n else\r\n fromParent = true;\r\n }\r\n\r\n // If this was added as a file\r\n if (secondItem.addType == Librarian.Cart.addTypes.FILE) {\r\n // And we're not dropping it on the first slide,\r\n // split it into its individual slides\r\n if (secondItem.slidenumber > 1)\r\n this.splitFileAndAddInPlace(Librarian.Cart.Item.makeParent(secondItem));\r\n // Otherwise, remember to get the parent index instead\r\n else\r\n toParent = true;\r\n }\r\n }\r\n\r\n var from;\r\n // Get the index of the parent, if we're told to\r\n if (fromParent)\r\n from = this.indexOfParent(firstItem, true);\r\n // Otherwise just get the index of this item\r\n else\r\n from = this.indexOf(firstItem, true, ignoreGroup);\r\n\r\n var to;\r\n // Get the index of the parent, if we're told to\r\n if (toParent)\r\n to = this.indexOfParent(secondItem, true);\r\n // Otherwise just get the index of this item\r\n else\r\n to = this.indexOf(secondItem, true, ignoreGroup);\r\n\r\n var size = this.getSize();\r\n // If the \"to\" index is invalid, don't continue\r\n if ((to < 0) || (to >= size))\r\n return;\r\n\r\n // If the \"from\" index is invalid, don't continue\r\n if ((from < 0) || (from >= size))\r\n return;\r\n\r\n // If the indeces are the same, don't continue\r\n if (from == to)\r\n return;\r\n\r\n // Store the current item\r\n var item = this.items[from];\r\n\r\n // Move this item to the same section\r\n item.section = this.items[to].section;\r\n\r\n // Move all the other items to the correct place\r\n if (from < to) {\r\n for (var i = from; i < to; i++)\r\n this.setItem(i, this.items[i + 1]);\r\n }\r\n else {\r\n for (var i = from; i > to; i--)\r\n this.setItem(i, this.items[i - 1]);\r\n }\r\n\r\n // Set the item to its new location\r\n this.setItem(to, item);\r\n\r\n // If we rearranged stuff, close the download window because it will need to reprocess the data\r\n if (Librarian.userCart.downloadWindow) {\r\n Librarian.userCart.downloadWindow.close();\r\n Librarian.userCart.downloadWindow = null;\r\n }\r\n },\r\n\r\n /*\r\n * Inserts the given item at the location specified by `index`\r\n *\r\n * item - List item to be inserted\r\n * index - Location within the list to which the item will be inserted\r\n */\r\n insertItemAt: function(item, index) {\r\n this.items.splice(index, 0, item);\r\n },\r\n\r\n /*\r\n * Inserts the given list of items at the location specified by `index`\r\n *\r\n * item - List of list items to be inserted\r\n * index - Location within the list to which the items will be inserted\r\n */\r\n insertItemsAt: function(items, index) {\r\n // Add each item, 1-by-1, in order, to the given location\r\n for (var i = 0, length = items.length; i < length; i++)\r\n this.insertItemAt(items[i], index + i);\r\n },\r\n\r\n /*\r\n * Updates the duplicate state of each item in this list\r\n */\r\n updateDuplicateState: function() {\r\n // If the cart isn't valid, somehow, we can't continue past this point\r\n if (!Librarian.userCart)\r\n return;\r\n\r\n // Go through each item\r\n for (var i = 0, length = this.items.length; i < length; i++) {\r\n // If it's duplicate, but it's not marked as in the cart anymore, remove the duplicate flag\r\n if (this.items[i].duplicate && !Librarian.userCart.isInCart(this.items[i], true, false))\r\n this.items[i].duplicate = false;\r\n this.items[i].updateDuplicateState();\r\n }\r\n }\r\n\r\n //#endregion\r\n});","Librarian.Cart.Window = new Class({\r\n Implements: Events,\r\n Extends: Librarian.Window,\r\n Binds: [\r\n \"updateCart\", \"doUpdate\", \"doRefresh\", \"onResize\", \"onBeforeCreatePackage\",\r\n \"changeView\", \"downloadCart\", \"cleanCartList\", \"setTextReplace\",\r\n \"onBeforeSaveFavorite\", \"saveAsFavorite\", \"reload\", \"addSection\", \"onViewClick\"\r\n ],\r\n\r\n options: {\r\n cartContainer: \"cartTileList\",\r\n wrapperClass: \"tile-list-wrapper-cart\",\r\n id: \"cartWindow\",\r\n height: 565,\r\n width: 845,\r\n toolbar: true,\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0\r\n },\r\n maximizable: true,\r\n resizable: true\r\n },\r\n\r\n // Path to the layout\r\n path: '',\r\n // Whether the toolbar has been loaded already or not\r\n toolbarLoaded: false,\r\n // Information about the collapse state for the toolbar\r\n toolbarInfo: {\r\n collapsed: false,\r\n leftWidth: null,\r\n rightWidth: null\r\n },\r\n // Whether or not we are displaying sections\r\n hasSections: false,\r\n // The tileList object for the cart\r\n cartList: null,\r\n // The createPackage object for the cart\r\n // Used to close this window when the cart is closed.\r\n createPackage: null,\r\n // The saveFavorite object for the cart\r\n // Used to close this window when the cart is closed.\r\n saveFavorite: null,\r\n onVPCreated: null,\r\n onVPCatCreated: null,\r\n // Text replace data to be passed along into the create window\r\n textReplaces: null,\r\n // Extra fields data to be passed along into the create window\r\n extraFields: null,\r\n // Optional override to use instead of cart data\r\n dataOverride: null,\r\n\r\n /*\r\n * Initializes an instance of the Cart window with the given options and event handler functions\r\n *\r\n * options - Option overrides\r\n * onVPCreatedFn - A function run when a My Favorite is created\r\n * onVPCatCreatedFn - A function run when a My Favorite category is created\r\n */\r\n initialize: function(options, onVPCreatedFn, onVPCatCreatedFn) {\r\n this.setOptions(options);\r\n\r\n // window type either default or modal\r\n if(Librarian.cart.openAsModalWindow) {\r\n this.options.type = \"modal\";\r\n }\r\n\r\n this.updateTitle();\r\n\r\n this.onVPCreated = onVPCreatedFn;\r\n this.onVPCatCreated = onVPCatCreatedFn;\r\n\r\n // Get the path to the layout\r\n this.path = Librarian.path.getLayoutsPath();\r\n\r\n // Load the cart page\r\n this.options.contentURL = this.path + \"/pages/cart.html\";\r\n\r\n // Set the toolbar URL\r\n this.options.toolbarURL = Librarian.path.getLibraryPath() + \"toolbar-cart.html\";\r\n\r\n // Handle hiding/showing text in toolbar buttons when resizing and maximizing\r\n this.options.onResize = this.onResize;\r\n this.options.onMaximize = this.onResize;\r\n this.options.onRestore = this.onResize;\r\n\r\n this.setWindowPosition();\r\n\r\n this.parent(this.options);\r\n },\r\n\r\n //#region Window Event Handlers\r\n\r\n /*\r\n * Handles the window resizing\r\n * This is currently used to expand/collapse the buttons on the toolbar to fit the window width\r\n */\r\n onResize: function() {\r\n // We only care about the window resizing when the buttons are supposed to automatically\r\n // switch between small and large icons\r\n if (!Librarian.cart.enableLabelSquishing)\r\n return;\r\n\r\n var toolbarWidth = this.toolbarEl.getWidth(),\r\n leftBarEl = this.toolbarEl.getElement(\".toolbox-left\"),\r\n rightBarEl = this.toolbarEl.getElement(\".toolbox\"),\r\n buttonEls = this.toolbarEl.getElements(\".ico-cart-wrapper\"),\r\n menuLabelEls = this.toolbarEl.getElements(\".dropdown-menu-bar > li > a\"),\r\n leftWidth,\r\n rightWidth;\r\n\r\n // If we have a previously saved width of the left bar, use that\r\n if (typeof this.toolbarInfo.leftWidth == \"number\")\r\n leftWidth = this.toolbarInfo.leftWidth;\r\n // Otherwise calculate the current width\r\n else\r\n leftWidth = leftBarEl ? leftBarEl.getWidth() : 0;\r\n\r\n // If we have a previously saved width of the right bar, use that\r\n if (typeof this.toolbarInfo.rightWidth == \"number\")\r\n rightWidth = this.toolbarInfo.rightWidth;\r\n // Otherwise calculate the current width\r\n else\r\n rightWidth = rightBarEl ? rightBarEl.getWidth() : 0;\r\n\r\n // If the two bars are larger than their parent, they need to be collapsed\r\n if (Librarian.cart.hideButtonLabels || ((rightWidth + leftWidth) > toolbarWidth)) {\r\n // Set collapse state\r\n this.toolbarInfo.collapsed = true;\r\n this.toolbarInfo.leftWidth = leftWidth;\r\n this.toolbarInfo.rightWidth = rightWidth;\r\n\r\n buttonEls.forEach(function (buttonEl) {\r\n if (!buttonEl.hasClass(\"hide-icon\"))\r\n buttonEl.addClass(\"hide-text\");\r\n });\r\n\r\n menuLabelEls.forEach(function(label) {\r\n label.addClass(\"hide-text\");\r\n });\r\n }\r\n // Otherwise, if this is already collapsed then we need to expand it\r\n else if (this.toolbarInfo.collapsed) {\r\n // Remove collapse state\r\n this.toolbarInfo.collapsed = false;\r\n this.toolbarInfo.leftWidth = null;\r\n this.toolbarInfo.rightWidth = null;\r\n\r\n buttonEls.forEach(function (buttonEl) {\r\n buttonEl.addClass(\"hide-text\");\r\n });\r\n\r\n menuLabelEls.forEach(function(label) {\r\n label.removeClass(\"hide-text\");\r\n });\r\n }\r\n },\r\n\r\n /*\r\n * Handles setting up the toolbar buttons when it has finished loading the first time\r\n */\r\n onToolbarLoaded: function () {\r\n // Don't do this stuff more than once\r\n if (this.toolbarLoaded)\r\n return;\r\n\r\n this.parent();\r\n\r\n if (Librarian.cart.convertButtonsToMenu)\r\n this.buildCartMenu();\r\n\r\n var libraryPath = Librarian.path.getLibraryPath(),\r\n iconsPath = Librarian.path.getDefaultThemePath() + \"images/icons/\",\r\n buttonEl = $(\"updateCart\");\r\n // If the remove button is there\r\n if (buttonEl) {\r\n // Set the correct icon\r\n buttonEl.src = libraryPath + \"img/updateCart.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.updateCart);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"clearCart\");\r\n var imageEl = $(\"clearCartImage\");\r\n // If the clear button is there\r\n if (buttonEl) {\r\n // Set the correct icon\r\n if (imageEl)\r\n imageEl.src = libraryPath + \"img/clearCart.gif\";\r\n else\r\n buttonEl.src = libraryPath + \"img/clearCart.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.clearCart);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"sendCart\");\r\n // If the clear button is there\r\n if (buttonEl) {\r\n if (!Librarian.Cart.canSend() || Librarian.Utils.isUserMemberOfGroup(Librarian.cart.disableShareUserGroups))\r\n buttonEl.destroy();\r\n else {\r\n // Set the correct icon\r\n if (buttonEl.tagName == \"IMG\")\r\n buttonEl.src = libraryPath + \"/img/send.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(Librarian.Cart.sendCart);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n }\r\n\r\n buttonEl = $(\"sendNewsletter\");\r\n // If the clear button is there\r\n if (buttonEl) {\r\n if (!Librarian.Cart.canSend())\r\n buttonEl.destroy();\r\n else {\r\n // Set the correct icon\r\n if (buttonEl.tagName == \"IMG\")\r\n buttonEl.src = libraryPath + \"/img/send.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(function() {\r\n Librarian.Cart.sendCart(Librarian.eventType.newsletter);\r\n });\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n }\r\n\r\n buttonEl = $(\"changeView\");\r\n // If the clear button is there\r\n if (buttonEl) {\r\n if (Librarian.cart.allowDisplaySwitch) {\r\n // Set the correct icon\r\n buttonEl.src = iconsPath + \"SmallThumbnailView.png\";\r\n var name = \"cart_view_slide\";\r\n\r\n if (Librarian.userCart && Librarian.userCart.isInSlideView()) {\r\n buttonEl.src = iconsPath + \"FileView.png\";\r\n name = \"cart_view_mixed\";\r\n }\r\n\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.changeView);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n // And update the mouse over\r\n buttonEl.alt = buttonEl.title = Librarian.Lang.getArgString(\"cart_view_button\", [Librarian.Lang.getString(name)]);\r\n }\r\n else {\r\n var parentEl = buttonEl.getParent();\r\n buttonEl.destroy();\r\n\r\n if (parentEl && parentEl.hasClass(\"ico-cart-wrapper\"))\r\n parentEl.destroy();\r\n }\r\n }\r\n\r\n buttonEl = $(\"refreshThumb\");\r\n if (buttonEl) {\r\n // Set the correct icon\r\n buttonEl.src = this.path + \"/img/Refresh.png\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.doRefresh);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"downloadCart\");\r\n imageEl = $(\"downloadCartImage\");\r\n // If the download button is there\r\n if (buttonEl) {\r\n // Set the correct icon\r\n if (imageEl)\r\n imageEl.src = libraryPath + \"img/create.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.downloadCart);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"saveFavorite\");\r\n imageEl = $(\"saveFavoriteImage\");\r\n // If the save button is there\r\n if (buttonEl) {\r\n // Set the correct icon\r\n if (imageEl)\r\n imageEl.src = libraryPath + \"img/save.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.saveAsFavorite);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"saveSlideShow\");\r\n imageEl = $(\"saveSlideShowImage\");\r\n // If the save button is there\r\n if (buttonEl) {\r\n // Set the correct icon\r\n if (imageEl)\r\n imageEl.src = libraryPath + \"img/save.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.saveAsFavorite.pass([Library.refreshSlideShowTree, Library.refreshSlideShowTree, null, null, Librarian.virtPresType.slideshow]), this);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"saveSharedFavorite\");\r\n imageEl = $(\"saveSharedFavoriteImage\");\r\n // If the save button is there\r\n if (buttonEl) {\r\n // Set the correct icon\r\n if (imageEl)\r\n imageEl.src = libraryPath + \"img/save.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.saveAsFavorite.pass([Library.refreshSharedFavTree, Library.refreshSharedFavTree, null, null, Librarian.virtPresType.sharedFavorite]), this);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"saveSharedSlideShow\");\r\n imageEl = $(\"saveSharedSlideShowImage\");\r\n // If the save button is there\r\n if (buttonEl) {\r\n // Set the correct icon\r\n if (imageEl)\r\n imageEl.src = libraryPath + \"img/save.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.saveAsFavorite.pass([Library.refreshSharedSlideShowTree, Library.refreshSharedSlideShowTree, null, null, Librarian.virtPresType.sharedSlideshow]), this);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n\r\n buttonEl = $(\"addSectionButton\");\r\n imageEl = $(\"addSectionImage\");\r\n if (buttonEl) {\r\n if (Librarian.features.sections.load) {\r\n // Set the correct icon\r\n if (imageEl)\r\n imageEl.src = Librarian.path.getLibraryPath() + \"img/Add-Section.gif\";\r\n // Add the onclick method\r\n buttonEl.addOnClick(this.addSection, this);\r\n // And update the ID\r\n buttonEl.id = this.options.id + '_' + buttonEl.id;\r\n }\r\n else\r\n buttonEl.destroy();\r\n }\r\n\r\n buttonEl = $(\"cartViewDropdown\");\r\n if (buttonEl) {\r\n // Create the list of views to switch between if the library defines them\r\n if (typeof Library.getCartViews == \"function\")\r\n this.createViewDropdown(buttonEl, Library.getCartViews());\r\n else\r\n buttonEl.destroy();\r\n }\r\n\r\n // Show/hide send buttons based on items\r\n this.updateSendButtons();\r\n\r\n // Loading complete\r\n this.toolbarLoaded = true;\r\n // Run the onResize so that the toolbar has the correct sizes and stuff now\r\n this.onResize();\r\n Librarian.Lang.translateElements(this.windowEl);\r\n },\r\n\r\n buildCartMenu: function () {\r\n // Create menu\r\n var toolboxEl = this.toolbarEl.getElement(\".toolbox\"),\r\n menuWrapperEl = new Element(\"div\", { id: \"cartMenuDropdown\", \"class\": \"dropdown-menu-wrapper\" }).inject(toolboxEl),\r\n ulEl = new Element(\"ul\", { \"class\": \"dropdown-menu-bar\" }).inject(menuWrapperEl),\r\n liEl = new Element(\"li\").inject(ulEl),\r\n linkEl = new Element(\"a\", { \"class\": \"ico-dot-menu\" }).inject(liEl),\r\n menuEl = new Element(\"div\").inject(liEl);\r\n\r\n // Move buttons into menu\r\n var buttonEls = this.toolbarEl.getElements(\".ico-cart-wrapper\");\r\n buttonEls.forEach(function (buttonEl) {\r\n // Handle the create button separately\r\n if (buttonEl.id.contains(\"downloadCart\") && !Librarian.cart.createInMenu) {\r\n // Hide icon\r\n buttonEl.addClass(\"hide-icon\");\r\n buttonEl.removeClass(\"ico-cart-wrapper\");\r\n\r\n // Style as button\r\n var textEl = buttonEl.firstElementChild;\r\n if (textEl) {\r\n textEl.addClass(\"pure-button\");\r\n textEl.removeClass(\"ico-cart-label\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Get menu text from inner element or button title\r\n var itemEl = buttonEl.getElement(\"a\");\r\n var text = (itemEl && itemEl.get(\"text\")) || buttonEl.title;\r\n if (!text)\r\n return;\r\n\r\n // Add new element to menu with same id as button\r\n var menuItemEl = new Element(\"a\", {\r\n id: buttonEl.id,\r\n text: text\r\n }).inject(menuEl);\r\n\r\n buttonEl.destroy();\r\n });\r\n\r\n Librarian.Utils.bindSDDMMenus([{ parent: linkEl, menu: menuEl }]);\r\n },\r\n\r\n /*\r\n * Handles loading the list of cart data after the window has loaded\r\n * Also sets up an override of the minimize button to reset the window to its initial position, but only when the `useMinimizeAsReset` setting is enabled\r\n */\r\n onWindowLoaded: function () {\r\n this.parent();\r\n\r\n // If the minimize button is being overridden\r\n if (Librarian.cart.useMinimizeAsReset) {\r\n var buttonEl = $(this.options.id + \"_minimizeButton\");\r\n // Get the button\r\n if (buttonEl) {\r\n // Remove the default event\r\n buttonEl.removeEvents(Librarian.hasTouchSupport() ? \"touchstart\" : \"click\");\r\n // When the button is clicked, set the position to the default\r\n buttonEl.addOnClick(this.setWindowPosition, this);\r\n }\r\n }\r\n\r\n // Display the list of slides\r\n this.reload();\r\n },\r\n\r\n /*\r\n * Handles cleaning up of the window elements when it is closed\r\n */\r\n onClose: function() {\r\n // Run the update function to clear out deleted items.\r\n this.doUpdate();\r\n\r\n if (this.createPackage) {\r\n this.createPackage.closeWindow();\r\n this.createPackage = null;\r\n }\r\n\r\n if (this.saveFavorite) {\r\n this.saveFavorite.close();\r\n this.saveFavorite = null;\r\n }\r\n\r\n this.cleanCartList();\r\n this.parent();\r\n },\r\n\r\n //#endregion\r\n\r\n //#region View Change Dropdown\r\n\r\n /*\r\n * Creates a dropdown to allow the user to switch between the available cart views\r\n *\r\n * menuContainerEl - The DOM element to create the dropdown menu in\r\n * views - The list of views to create within the dropdown\r\n */\r\n createViewDropdown: function(menuContainerEl, views) {\r\n var viewContainerEl = new Element(\"ul\", { \"class\": \"views-dropdown dropdown-menu-bar\" }).injectInside(menuContainerEl),\r\n viewListEl = new Element(\"li\").injectInside(viewContainerEl),\r\n triggerEl = new Element(\"a\").injectInside(viewListEl),\r\n menuEl = new Element(\"div\", { id: this.options.id + \"_viewMenu\" }).injectInside(viewListEl);\r\n\r\n // Create the dropdown menu handler for the created menu\r\n Librarian.Utils.bindSDDMMenus([{ parent: triggerEl, menu: menuEl }]);\r\n\r\n // Add each view to the dropdown list\r\n for (var i = 0; i < views.length; i++) {\r\n if (views[i].cart === false)\r\n continue;\r\n\r\n var text = Librarian.Lang.getString(views[i].name),\r\n selected = false;\r\n if (typeof views[i].selected == \"function\")\r\n selected = views[i].selected();\r\n else if (typeof views[i].selected == \"boolean\")\r\n selected = views[i].selected;\r\n\r\n var itemEl = new Element(\"a\", {\r\n \"id\": views[i].id,\r\n \"title\": text,\r\n \"class\": \"ico-view-item\"\r\n });\r\n\r\n var iconEl = new Element(\"span\", {\r\n \"class\": views[i][\"class\"] + \"-icon ico-view-item\",\r\n \"title\": \"\",\r\n \"text\": \"\"\r\n }).injectInside(itemEl);\r\n\r\n itemEl.viewIndex = i;\r\n itemEl.appendChild(document.createTextNode(text));\r\n\r\n // If this is the first item or it is explicitly selected, make it show inside the trigger element\r\n if (selected || i == 0) {\r\n triggerEl.set(\"title\", text);\r\n triggerEl.appendChild(document.createTextNode(text));\r\n triggerEl.removeClass(views[0][\"class\"]);\r\n triggerEl.addClass(views[i][\"class\"]);\r\n }\r\n\r\n itemEl.addOnClick(this.onViewClick);\r\n menuEl.appendChild(itemEl);\r\n }\r\n\r\n menuEl = null;\r\n triggerEl = null;\r\n viewListEl = null;\r\n viewContainerEl = null;\r\n },\r\n\r\n /*\r\n * Handles when an item in the views dropdown is clicked\r\n * Automatically updates the selected view in the dropdown and the cart item tile size in each inner TileList\r\n *\r\n * e - The event containing information such as which element was clicked\r\n */\r\n onViewClick: function(e) {\r\n if (!e || (typeof Library.getCartViews != \"function\") || !this.cartList)\r\n return;\r\n\r\n var evt = new Event(e),\r\n buttonEl = $(evt.target);\r\n if (!buttonEl)\r\n return;\r\n\r\n function setTileListSize(size) {\r\n this.cartList.reload(size);\r\n Librarian.Utils.updateCheckboxes(this.cartList.getItemStyle());\r\n\r\n var triggerEl = $$(\"#cartViewDropdown .views-dropdown li a\")[0];\r\n if (!triggerEl)\r\n return;\r\n\r\n var views = Library.getCartViews(),\r\n view = views[buttonEl.viewIndex],\r\n text = Librarian.Lang.getString(view.name);\r\n\r\n triggerEl.set(\"title\", text);\r\n Librarian.Utils.setElementValue(triggerEl, text);\r\n var hideText = triggerEl.hasClass(\"hide-text\");\r\n\r\n triggerEl.className = '';\r\n triggerEl.addClass(view[\"class\"]);\r\n if (hideText)\r\n triggerEl.addClass(\"hide-text\");\r\n }\r\n\r\n if (buttonEl.id.endsWith(\"tnailSm\"))\r\n setTileListSize.bind(this)('');\r\n else if (buttonEl.id.endsWith(\"tnailLg\"))\r\n setTileListSize.bind(this)(\"lg\");\r\n else if (buttonEl.id.endsWith(\"detailedList\"))\r\n setTileListSize.bind(this)(\"expand\");\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Button Handlers\r\n\r\n /*\r\n * Clears the cart contents and resets the locally saved text replace data\r\n *\r\n * Returns false\r\n */\r\n clearCart: function() {\r\n Librarian.Cart.clearCart();\r\n return false;\r\n },\r\n\r\n /*\r\n * Prompts the user asking whether they want to update the cart which removes items marked for deletion\r\n *\r\n * Returns false\r\n */\r\n updateCart: function(cancelOnUpdateCall) {\r\n // If there is no cart, there is nothing to update.\r\n if (!Librarian.userCart) { return false; }\r\n\r\n // Get the number of items to be removed.\r\n var count = null;\r\n if(this.cartList) {\r\n count = this.cartList.getUnCheckedElements().length;\r\n }\r\n \r\n // get number of unchecked cart items\r\n if (count === 0) {\r\n // no unchecked items, just reload\r\n this.reload(); \r\n } else {\r\n if(!(Librarian.features.fastlane.load && Librarian.FastLane.isEnabled)) {\r\n // Make sure the user wants to do this first\r\n var confirm = new Librarian.ConfirmWindow({\r\n id: \"updateCartConfirmWindow\",\r\n title: Librarian.Lang.getString(\"update\") + '?',\r\n question: Librarian.Lang.getString(\"cart_update?\")\r\n });\r\n confirm.onFirstButtonClicked = function() {\r\n this.doUpdate(count);\r\n }.bind(this);\r\n confirm.show();\r\n } else {\r\n // skip confirmation window with fastlane enabled\r\n\r\n // if cancelOnUpdateCall, tells cart to not fire 'onUpdate' function after cart update\r\n // (allows cart module to update cart window without infinate loop)\r\n if(cancelOnUpdateCall === null) { cancelOnUpdateCall = false; }\r\n this.doUpdate(count, cancelOnUpdateCall);\r\n }\r\n\r\n }\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Runs the update function which removes all cart items marked for deletion and notifies the user how many were removed\r\n *\r\n * Returns false\r\n */\r\n doUpdate: function(count, cancelOnUpdateCall) {\r\n // If there is no cart, there is nothing to update.\r\n if (!Librarian.userCart) {\r\n return false;\r\n }\r\n\r\n // default value is false\r\n if(cancelOnUpdateCall === null) {\r\n cancelOnUpdateCall = false;\r\n }\r\n\r\n // Update the cart\r\n Librarian.userCart.removeAllDeleted();\r\n\r\n // Reload this window to display the updated list\r\n this.reload();\r\n\r\n // Tell the user how many items were removed\r\n if (count != undefined) {\r\n Librarian.Utils.notification(Librarian.Lang.getPluralArgString(\"cart_removed\", count, [count]));\r\n }\r\n\r\n if(!cancelOnUpdateCall) {\r\n // If items were removed, fire onUpdate\r\n if (((count == undefined) || (count > 0)) && Librarian.userCart.onUpdate) {\r\n Librarian.userCart.onUpdate();\r\n }\r\n }\r\n\r\n // Update the checkboxes on the main page\r\n Librarian.Utils.updateAllCheckboxes();\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Toggles the cart between SLIDE view and MIXED view\r\n *\r\n * Returns false\r\n */\r\n changeView: function() {\r\n // If there isn't a cart, don't bother continuing\r\n if (!Librarian.userCart)\r\n return false;\r\n\r\n // Get the changeView button\r\n var buttonEl = $(this.options.id + \"_changeView\"),\r\n iconsPath = Librarian.path.getDefaultThemePath() + \"images/icons/\";\r\n\r\n // If we're in Mixed View, go to Slide View\r\n if (Librarian.userCart.isInMixedView()) {\r\n Librarian.userCart.changeView(Librarian.Cart.displayModes.SLIDE_VIEW);\r\n\r\n if (buttonEl) {\r\n buttonEl.src = iconsPath + \"FileView.png\";\r\n buttonEl.alt = buttonEl.title = Librarian.Lang.getArgString(\"cart_view_button\", [Librarian.Lang.getString(\"cart_view_mixed\")]);\r\n }\r\n }\r\n // Otherwise, go to Mixed View\r\n else {\r\n Librarian.userCart.changeView(Librarian.Cart.displayModes.MIXED_VIEW);\r\n\r\n if (buttonEl) {\r\n buttonEl.alt = buttonEl.title = Librarian.Lang.getArgString(\"cart_view_button\", [Librarian.Lang.getString(\"cart_view_slide\")]);\r\n buttonEl.src = iconsPath + \"SmallThumbnailView.png\";\r\n }\r\n }\r\n\r\n // Reload this window to display the newly updated list\r\n this.reload();\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Causes the cart list to reload its thumbnails\r\n *\r\n * Returns false\r\n */\r\n doRefresh: function() {\r\n if (this.cartList)\r\n this.cartList.reloadThumbnails();\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Reloads the cart window by completely removing the existing list and regenerating it over again\r\n */\r\n reload: function() {\r\n var contEl = $(this.options.cartContainer);\r\n // If the container and the cart each exist\r\n if (contEl && Librarian.userCart) {\r\n // Add the cartList to the container if we don't have one already\r\n if (!this.cartList || (this.hasSections == (Librarian.userCart.sections.length == 0))) {\r\n var size = null;\r\n if (this.cartList)\r\n size = this.cartList.options.size;\r\n\r\n this.cleanCartList();\r\n contEl.empty();\r\n\r\n this.initCartList(size);\r\n }\r\n\r\n // If we're using sections, load them into the list\r\n if (this.hasSections) {\r\n this.cartList.reset();\r\n var sections = Librarian.userCart.getSectionsList(true, Librarian.cart.showDuplicates);\r\n for (var i = 0; i < sections.length; i++)\r\n this.cartList.addSection(sections[i].items, sections[i].name, sections[i].description);\r\n }\r\n // Otherwise load the display items into the cart list\r\n else\r\n this.cartList.loadFromArray(Librarian.userCart.getDisplayItems(true, Librarian.cart.showDuplicates));\r\n\r\n // Update the count in the title\r\n this.updateTitle();\r\n this.updateSendButtons();\r\n }\r\n },\r\n\r\n /*\r\n * Initialize the cart list\r\n */\r\n initCartList: function(size) {\r\n if (Librarian.features.sections.load && (Librarian.userCart.sections.length > 0)) {\r\n this.cartList = new Librarian.SectionList({\r\n container: $(this.options.cartContainer),\r\n sectionClassPrefix: \"section-cart-\",\r\n tileListStyle: \"tile-list-item-cart\",\r\n size: size,\r\n allowDrag: true,\r\n allowEdit: true,\r\n allowHeaderDrag: true\r\n });\r\n this.cartList.options.targetList = tileList;\r\n\r\n this.hasSections = true;\r\n }\r\n else {\r\n this.cartList = new Librarian.TileList({\r\n id: \"cartTileListWrapper\",\r\n container: $(this.options.cartContainer),\r\n itemStyle: \"tile-list-item-cart\",\r\n size: size,\r\n allowDrag: true,\r\n });\r\n this.cartList.options.targetList = tileList;\r\n\r\n this.hasSections = false;\r\n }\r\n },\r\n\r\n //#endregion\r\n\r\n /*\r\n * Adds a new empty section with the default name and description\r\n */\r\n addSection: function() {\r\n if (!Librarian.features.sections.load || !Librarian.userCart)\r\n return;\r\n\r\n Librarian.userCart.addSection();\r\n this.reload();\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Package Creation\r\n\r\n /*\r\n * Runs checks before opening the create window to determine whether creation should be allowed\r\n * If data is not provided, this will check to make sure there are things in the cart to create\r\n * Also creates the package creation instance to handle the creation process\r\n *\r\n * event - The event containing information such as which element was clicked - Optional\r\n * data - The data being created, if not using the cart - Optional\r\n *\r\n * Returns true if creation is allowed, false otherwise\r\n */\r\n onBeforeCreatePackage: function(event, data) {\r\n // Can't download an empty cart\r\n if ((typeof data == \"undefined\") || (data == null)) {\r\n if (Librarian.userCart) {\r\n if (Librarian.userCart.getCount(true, true) == 0)\r\n return false;\r\n if (Librarian.userCart.isFull()) {\r\n Librarian.Utils.error(Librarian.Lang.getString(\"cart_overfull\"));\r\n return false;\r\n }\r\n }\r\n }\r\n else\r\n this.dataOverride = data;\r\n\r\n // Create a new createPackage item if there isn't one already\r\n if (this.createPackage == null)\r\n this.createPackage = new Librarian.CreatePackage();\r\n\r\n return true;\r\n },\r\n\r\n /*\r\n * Opens the create package window for the user to fill out and begin the create process\r\n *\r\n * event - The event containing information such as which element was clicked - Optional\r\n * data - The data being created, if not using the cart - Optional\r\n * windowOptions - Additional options to pass to the create package window - Optional\r\n *\r\n * Returns false\r\n */\r\n downloadCart: function(event, data, windowOptions) {\r\n // Check to make sure this should be allowed first\r\n if (!this.onBeforeCreatePackage(event, data))\r\n return false;\r\n\r\n // If we have extra properties we need to pass to the cart form\r\n if (this.textReplaces || this.extraFields) {\r\n // Make sure we have a data object\r\n if (!data)\r\n data = {};\r\n // And a data object within the data object\r\n if (!data.data)\r\n data.data = null;\r\n // And an options object\r\n if (!data.options)\r\n data.options = {};\r\n // And then save the given text replaces\r\n if (this.textReplaces) {\r\n data.options.textReplaces = this.textReplaces;\r\n }\r\n // And then save the given extra fields\r\n if (this.extraFields) {\r\n data.options.extraFields = this.extraFields;\r\n }\r\n }\r\n\r\n windowOptions = windowOptions || {};\r\n windowOptions.createOptions = Object.merge({}, windowOptions.createOptions, this.createOptions);\r\n\r\n // Show the createPackage window\r\n this.createPackage.showWindow(data, windowOptions);\r\n\r\n // Center the window element.\r\n var windowEl = this.createPackage.getWindow();\r\n if (windowEl)\r\n MUI.centerWindow(windowEl);\r\n\r\n return false;\r\n },\r\n\r\n /*\r\n * Causes the create package window to update its button status based on changed cart content\r\n */\r\n updateCreateWindow: function() {\r\n if ((this.createPackage == null) || (this.createPackage.window == null))\r\n return;\r\n\r\n this.createPackage.window.updateOutputButtons();\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Favorite Creation\r\n\r\n /*\r\n * Runs checks before opening the save favroite window to determine whether saving a favorite should be allowed\r\n * Is usually overridden on a per-library basis\r\n *\r\n * Returns true\r\n */\r\n onBeforeSaveFavorite: function() {\r\n return true;\r\n },\r\n\r\n /*\r\n * Opens the save favorite window for the user to fill out and begin the saving process\r\n *\r\n * onVPCreatedFn - A function run when a My Favorite is created. Overrides the function given when the cart window was created - Optional\r\n * onVPCatCreatedFn - A function run when a My Favorite category is created. Overrides the function given when the cart window was created - Optional\r\n * defaultName - The name to default this favorite to in the save form\r\n * saveEmpty - Whether to allow saving a favorite even when the cart is empty - Optional, defaults to false\r\n * type - The type of favorite being saved\r\n */\r\n saveAsFavorite: function(onVPCreatedFn, onVPCatCreatedFn, defaultName, saveEmpty, type) {\r\n // Can't save an empty cart\r\n if (!this.onBeforeSaveFavorite() || ((this.dataOverride == null) && (saveEmpty !== true) && Librarian.userCart && (Librarian.userCart.getCount(true, true) == 0))) {\r\n Librarian.Utils.notification(Librarian.Lang.getString(\"cart_is_empty\"));\r\n return false;\r\n }\r\n\r\n this.saveFavorite = new Librarian.MyFavorite.SaveWindow({ defaultName: defaultName, presType: type, data: this.dataOverride });\r\n this.saveFavorite.onCreated = typeof onVPCreatedFn == \"function\" ? onVPCreatedFn : this.onVPCreated;\r\n this.saveFavorite.onCatCreated = typeof onVPCatCreatedFn == \"function\" ? onVPCatCreatedFn : this.onVPCatCreated;\r\n this.saveFavorite.show();\r\n\r\n return false;\r\n },\r\n\r\n //#endregion\r\n\r\n //#region Helper Functions\r\n\r\n /*\r\n * Sets the position and size of this window based on various settings\r\n */\r\n setWindowPosition: function() {\r\n // Make sure to un-maximize the window\r\n this.restore();\r\n\r\n // If we are trying to open this at a non-standard position\r\n if (Librarian.cart.defaultPosition != null) {\r\n var mode = Librarian.cart.positions.center;\r\n\r\n // Get the mode, if it's provided\r\n if (Librarian.cart.defaultPosition.mode != null && !isNaN(Librarian.cart.defaultPosition.mode))\r\n mode = Librarian.cart.defaultPosition.mode;\r\n\r\n // Get the size of the window\r\n var windowDimensions = window.getCoordinates(),\r\n // Get the total height used by all toolbars, et al\r\n extraHeight = (this.options.toolbar ? this.options.toolbarHeight : 0) +\r\n (this.options.toolbar2 ? this.options.toolbar2Height : 0) +\r\n this.options.headerHeight + this.options.footerHeight + (this.options.shadowBlur * 2);\r\n\r\n // Stick the window to the bottom\r\n if (mode == Librarian.cart.positions.bottom)\r\n this.options.y = windowDimensions.height - this.options.height - extraHeight;\r\n else {\r\n // Set the height of the cart window to the height of the browser minus the height of all the window's extra stuff\r\n this.options.height = windowDimensions.height - extraHeight;\r\n\r\n // Set the y position if it's provided and subtract that from the window's height\r\n if (Librarian.cart.defaultPosition.y != null && !isNaN(Librarian.cart.defaultPosition.y)) {\r\n this.options.y = Librarian.cart.defaultPosition.y;\r\n this.options.height -= this.options.y;\r\n }\r\n // Otherwise just move the window to the top so it will fit\r\n else\r\n this.options.y = 0;\r\n }\r\n\r\n if (Librarian.cart.defaultPosition.width != null) {\r\n // Set the width if it's provided as a number\r\n if ((typeof Librarian.cart.defaultPosition.width == \"number\") && (Librarian.cart.defaultPosition.width > 0))\r\n this.options.width = Librarian.cart.defaultPosition.width;\r\n // If it's provided as a percent, calculate that instead\r\n else if ((typeof Librarian.cart.defaultPosition.width == \"string\") && Librarian.cart.defaultPosition.width.endsWith('%')) {\r\n var percent = parseInt(Librarian.cart.defaultPosition.width, 10) / 100;\r\n if (percent > 0)\r\n this.options.width = windowDimensions.width * percent;\r\n }\r\n }\r\n\r\n if (Librarian.cart.defaultPosition.height != null) {\r\n var calcHeight = null;\r\n // Set the height if it's provided as a number\r\n if ((typeof Librarian.cart.defaultPosition.height == \"number\") && (Librarian.cart.defaultPosition.height > 0))\r\n calcHeight = Librarian.cart.defaultPosition.height;\r\n // If it's provided as a percent, calculate that instead\r\n else if ((typeof Librarian.cart.defaultPosition.height == \"string\") && Librarian.cart.defaultPosition.height.endsWith('%')) {\r\n var percent = parseInt(Librarian.cart.defaultPosition.height, 10) / 100;\r\n if (percent > 0)\r\n calcHeight = windowDimensions.height * percent;\r\n }\r\n\r\n // Set the height if it's provided and smaller than the previously calculated height\r\n if (calcHeight < this.options.height)\r\n this.options.height = calcHeight;\r\n }\r\n\r\n // Set the position to the right, if that's the chosen mode\r\n // Subtract an extra 20 off the end to make room for the scroll bar, just in case\r\n if ((mode == Librarian.cart.positions.right) || (Librarian.cart.defaultPosition.right == true))\r\n this.options.x = windowDimensions.width - this.options.width - this.options.shadowBlur - 20;\r\n }\r\n\r\n // If the window is already open\r\n if (this.toolbarLoaded) {\r\n // Resize/reposition it\r\n this.resize({\r\n width: this.options.width,\r\n height: this.options.height,\r\n top: this.options.y,\r\n left: this.options.x,\r\n centered: false\r\n });\r\n\r\n this.onResize();\r\n }\r\n },\r\n\r\n /*\r\n * Updates the title of this window based on settings and the number of items in the cart\r\n * Also updates the name of the window on the dock tabs\r\n */\r\n updateTitle: function() {\r\n // Set the title on init so that we can use the localization\r\n this.options.title = Librarian.Lang.getString(\"cart\");\r\n\r\n // Show the slide count\r\n if (Librarian.cart.showCountInTitle)\r\n this.options.title += \" - \" + Librarian.Lang.getArgString(\"cart_count\", [Librarian.userCart.getCount(Librarian.cart.showSlideCount, true)]);\r\n\r\n var itemEl = $(this.options.id + \"_title\");\r\n if (itemEl) {\r\n itemEl.set(\"text\", MUI.getFittedTitle(this.options.title, this.options.width));\r\n itemEl.title = this.options.title;\r\n }\r\n\r\n // Update the title of the dock tab for hover over\r\n itemEl = $(this.options.id + \"_dockTab\");\r\n if (itemEl)\r\n itemEl.title = this.options.title;\r\n\r\n // Update the text inside of the dock tab\r\n itemEl = $(this.options.id + \"_dockTabText\");\r\n if (itemEl)\r\n itemEl.set(\"text\", this.options.title);\r\n },\r\n\r\n /*\r\n * Updates the send buttons based on whether the items in the cart can be sent\r\n */\r\n updateSendButtons: function() {\r\n var canSend = Librarian.Cart.canSendItems();\r\n\r\n var sendEl = this.getElement(\"sendCart\");\r\n if (sendEl)\r\n sendEl.toggle(canSend);\r\n\r\n var newsletterEl = this.getElement(\"sendNewsletter\");\r\n if (newsletterEl)\r\n newsletterEl.toggle(canSend);\r\n },\r\n\r\n /*\r\n * Determines whether this cart window is currently visible\r\n */\r\n isVisible: function() {\r\n return (this.windowEl.style.visibility == \"visible\") || (this.windowEl.style.visibility == '') || this.isMinimized;\r\n },\r\n\r\n /*\r\n * Sets or adds to the locally saved list of text replace values\r\n *\r\n * textReplaces - Values to be set or added to the local list\r\n * clearExisting - Whether to clear the existing list before adding the given list\r\n */\r\n setTextReplace: function(textReplaces, clearExisting) {\r\n this.textReplaces = (clearExisting === true) ? textReplaces : Object.merge(this.textReplaces || {}, textReplaces);\r\n },\r\n\r\n /*\r\n * Sets or adds to the locally saved list of text replace values\r\n *\r\n * extraFields - Values to be set or added to the local list\r\n * clearExisting - Whether to clear the existing list before adding the given list\r\n */\r\n setExtraFields: function(extraFields, clearExisting) {\r\n this.extraFields = (clearExisting === true) ? extraFields : Object.merge(this.extraFields || {}, extraFields);\r\n },\r\n\r\n setCreateOptions: function (createOptions, clearExisting) {\r\n this.createOptions = (clearExisting === true) ? createOptions : Object.merge(this.createOptions || {}, createOptions);\r\n },\r\n\r\n /*\r\n * Cleans the window's cart list by completely destroying it\r\n */\r\n cleanCartList: function() {\r\n if (this.cartList) {\r\n this.cartList.destroy();\r\n this.cartList = null;\r\n }\r\n }\r\n\r\n //#endregion\r\n});\r\n"]}