Index: in-commerce/checkout/one_step_checkout.tpl
===================================================================
--- in-commerce/checkout/one_step_checkout.tpl (revision 0)
+++ in-commerce/checkout/one_step_checkout.tpl (revision 0)
@@ -0,0 +1,279 @@
+<!--##
+<NAME>One Step Checkout</NAME>
+<DESC>Step, where user enters all order information</DESC>
+<SECTION>Platform||Checkout</SECTION>
+##-->
+
+<inp2:m_RequireLogin condition="Comm_RequireLoginBeforeCheckout" login_template="platform/login/register"/> <!--## CHECK IF LOGIN REQUIRED ##-->
+<inp2:m_CheckSSL mode="required" condition="Require_SSL" /> <!--## CHECK IF SSL REQUIRED ##-->
+
+<!--## PAGE TITLE ELEMENT ##-->
+<inp2:m_DefineElement name="page_title">
+ <inp2:st_PageInfo type="htmlhead_title"/>
+</inp2:m_DefineElement>
+<!--## //PAGE TITLE ELEMENT ##-->
+
+<!--## SIDE-BAR ELEMENT ##-->
+<inp2:m_DefineElement name="sidebar">
+ <div class="movable-area">
+ <div class="movable-element">
+ <inp2:m_RenderElement name="in-commerce/elements/side_boxes/checkout_steps.elm" design="blue_box"/>
+ </div>
+ <div class="movable-element">
+ <inp2:m_RenderElement name="platform/elements/side_boxes/login.elm" design="blue_box"/>
+ </div>
+ <div class="movable-element">
+ <inp2:m_RenderElement name="platform/elements/side_boxes/search.elm" design="blue_box"/>
+ </div>
+ <div class="movable-element">
+ <inp2:m_RenderElement name="in-commerce/elements/side_boxes/recent_products.elm" design="blue_box" data_exists="1"/>
+ </div>
+ </div>
+</inp2:m_DefineElement>
+<!--## /SIDE-BAR ELEMENT ##-->
+
+<!--## MAIN CONTENT ##-->
+<inp2:m_DefineElement name="content">
+ <div class="movable-area">
+ <div class="movable-element">
+ <inp2:m_include template="platform/elements/navigation_bar.elm" titles="lu_title_ShoppingCart" templates="in-commerce/checkout/shop_cart"/>
+ </div>
+ <div class="movable-element">
+ <style type="text/css">
+ table.checkout-form {
+ width: 850px;
+ }
+
+ table.checkout-form td {
+ padding: 5px;
+ vertical-align: top;
+ }
+
+ </style>
+
+ <form method="post" action="<inp2:m_FormAction />">
+ <table border="1" class="checkout-form">
+ <tr>
+ <td style="width: 50%;">
+ <h1>
+ <inp2:st_PageInfo type="htmlhead_title"/>
+ </h1>
+
+ Continue as Guest or <input type="button" value="Log In"/>
+
+ <table class="form-data">
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingEmail" title="lu_fld_Email"/>
+ </table>
+ </td>
+ <td style="width: 50%;">
+ B
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <strong><inp2:m_Phrase name="lu_section_BillingInfo"/></strong>
+ </td>
+ <td>
+ <input type="checkbox" name="same_address" value="1"<inp2:m_if check="m_GetEquals" name="same_address" value="1"> checked</inp2:m_if>"/>
+
+
+ <strong><inp2:m_Phrase name="lu_section_ShippingInfo"/></strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <table class="form-data">
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingTo" title="lu_fld_FullName" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingCompany" title="lu_fld_Company" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingAddress1" title="lu_fld_AddressLine1" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingAddress2" title="lu_fld_AddressLine2" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_options" prefix="ord" field="BillingCountry" title="lu_fld_Country" style="width: 300px;" has_empty="1"/>
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingState" title="lu_fld_State" style="width: 200px;"/>
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingZip" title="lu_fld_Zip" style="width: 100px;"/>
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="BillingPhone" title="lu_fld_Phone" style="width: 150px;" is_last="1"/>
+ </table>
+ </td>
+ <td>
+ <table class="form-data">
+
+ <tr class="<inp2:m_odd_even odd='table_color1' even='table_color2'/>">
+ <inp2:m_RenderElement name="inp_edit_field_caption" prefix="ord" field="ShippingInfo" title="lu_fld_ShippingInfo"/>
+ <td class="field-value">
+ <inp2:m_DefineElement name="order_shipping_type">
+ <option <inp2:m_param name="selected"/> value="<inp2:m_param name='ShippingId'/>"><inp2:m_param name="ShippingName"/> (<inp2:m_if check="m_param" name="ShippingFree" value="1"><inp2:m_Phrase label="lu_comm_FreeShipping" /><inp2:m_else/><inp2:m_param name="TotalCost"/></inp2:m_if>)</option>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="order_shipment">
+ <select class="input-select" name="<inp2:m_param name='field_name'/>">
+ <inp2:ord_PrintShippingTypes render_as="order_shipping_type" currency="selected" />
+ </select>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="no_shipments">
+ <div class="field-error"><inp2:m_Recall name="usps_errors"/></div>
+ <inp2:m_Phrase label="lu_comm_ErrorNoShippingTypes"/>.
+ </inp2:m_DefineElement>
+
+ <inp2:ord_PrintShippings render_as="order_shipment" currency="selected" no_shipments_render_as="no_shipments" />
+ </td>
+ </tr>
+ <inp2:m_RenderElement name="inp_edit_field_separator"/>
+
+
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="ShippingTo" title="lu_fld_FullName" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="ShippingCompany" title="lu_fld_Company" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="ShippingAddress1" title="lu_fld_AddressLine1" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="ShippingAddress2" title="lu_fld_AddressLine2" style="width: 300px;" />
+ <inp2:m_RenderElement name="inp_edit_options" prefix="ord" field="ShippingCountry" title="lu_fld_Country" style="width: 300px;" has_empty="1"/>
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="ShippingState" title="lu_fld_State" style="width: 200px;" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="ShippingZip" title="lu_fld_Zip" style="width: 100px;" is_last="1"/>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <strong><inp2:m_Phrase label="lu_section_PaymentInformation"/></strong>
+ </td>
+ <td>
+
+
+
+ <strong><inp2:m_Phrase name="lu_section_CostSummary"/> (<inp2:ord_ItemsInCart/>)</strong>
+ <a href="#">View Order Details</a>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <img alt="" src="<inp2:m_TemplatesBase module="In-Commerce"/>img/credit_cards/visa.gif" />
+ <img alt="" src="<inp2:m_TemplatesBase module="In-Commerce"/>img/credit_cards/american_express.gif" />
+ <img alt="" src="<inp2:m_TemplatesBase module="In-Commerce"/>img/credit_cards/master_card.gif" />
+ <img alt="" src="<inp2:m_TemplatesBase module="In-Commerce"/>img/credit_cards/novus.gif" />
+
+ <img src="<inp2:m_TemplatesBase module='In-Commerce'/>img/x-click-butcc_pay.gif" width="73" height="44" alt=""/>
+
+ <br />
+
+
+ <input type="hidden" name="check_credit_card" value="true"/>
+
+
+
+ <table class="form-data fullwidth">
+ <!--<inp2:m_RenderElement name="inp_edit_options" prefix="ord" field="PaymentCardType" title="lu_billing_CardType"/>-->
+ <inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="PaymentAccount" title="lu_billing_CreditCardNumber" style="width: 200px;"/>
+ <!--<inp2:m_RenderElement name="inp_edit_box" prefix="ord" field="PaymentNameOnCard" title="lu_billing_NameOnCard" style="width: 260px;"/>-->
+
+ <!-- credit card expiration -->
+ <tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
+ <inp2:m_RenderElement name="inp_edit_field_caption" prefix="ord" field="PaymentCCExpDate" title="lu_billing_CardExpiration"/>
+ <td class="field-value">
+ <inp2:m_if check="ord_HasError" field="PaymentCCExpDate">
+ <span class="field-error"><inp2:ord_Error field="PaymentCCExpDate"/></span><br />
+ </inp2:m_if>
+ <select class="input-select" name="<inp2:ord_InputName field="PaymentCCExpMonth"/>">
+ <inp2:ord_PredefinedOptions field="PaymentCCExpMonth" render_as="inp_option_item" selected="selected"/>
+ </select>
+ /
+ <select class="input-select" name="<inp2:ord_InputName field="PaymentCCExpYear"/>">
+ <option value=''></option>
+ <inp2:ord_PrintYearOptions field="PaymentCCExpYear" render_as="inp_option_item" selected="selected"/>
+ </select>
+ </td>
+ </tr>
+ <inp2:m_RenderElement name="inp_edit_field_separator" is_last="0"/>
+ <!-- // credit card expiration -->
+
+ <!-- credit card CVV2 -->
+ <tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
+ <inp2:m_RenderElement name="inp_edit_field_caption" prefix="ord" field="PaymentCVV2" title="lu_billing_CVV2"/>
+ <td class="field-value">
+ <inp2:m_if check="ord_HasError" field="PaymentCVV2">
+ <span class="field-error"><inp2:ord_Error field="PaymentCVV2"/></span><br />
+ </inp2:m_if>
+ <input type="text" class="input-text" name="<inp2:ord_InputName field="PaymentCVV2"/>" value="<inp2:ord_Field field="PaymentCVV2"/>" tabindex="<inp2:m_get param="tab_index"/>" style="width: 50px;">
+ <a href="javascript:showCVV2Help()"><inp2:m_Phrase label="lu_WhatIsThis" /></a>
+ </td>
+ </tr>
+ <!-- // credit card CVV2 -->
+ </table>
+ </td>
+ <td>
+ <table class="order-totals">
+ <inp2:m_DefineElement name="products_total">
+ <tr>
+ <td><strong><inp2:m_Phrase label="lu_comm_ProductsTotal"/>:</strong></td>
+ <td><inp2:ord_Field name="SubTotal" currency="selected"/></td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="shipping_total">
+ <tr>
+ <td><strong><inp2:m_Phrase label="lu_comm_ShippingCost"/> (<inp2:ord_ShippingType />):</strong></td>
+ <td><inp2:ord_Field name="ShippingCost" currency="selected"/></td>
+ </tr>
+ <tr>
+ <td><strong><inp2:m_Phrase label="lu_comm_Insurance_Fee"/>:</strong></td>
+ <td><inp2:ord_Field name="InsuranceFee" currency="selected"/></td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="processing_total">
+ <tr>
+ <td><strong><inp2:m_Phrase label="lu_comm_ProcessingFee"/>: </strong></td>
+ <td><inp2:ord_Field name="ProcessingFee" currency="selected"/></td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="sub_total">
+ <tr>
+ <td><strong><inp2:m_Phrase label="lu_comm_SubTotal"/>: </strong></td>
+ <td><inp2:ord_Field name="AmountWithoutVAT" currency="selected"/></td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="vat_total">
+ <tr>
+ <td><strong><inp2:m_Phrase label="lu_comm_VAT"/> <inp2:ord_Field name="VATPercent"/>%: </strong></td>
+ <td><inp2:ord_Field name="VAT" currency="selected"/></td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:ord_PrintTotals
+ products_render_as="products_total"
+ shipping_render_as="shipping_total"
+ processing_render_as="processing_total"
+ sub_total_render_as="sub_total"
+ vat_render_as="vat_total"/>
+
+ <inp2:m_if check="ord_Field" name="GiftCertificateId">
+ <tr>
+ <td><strong><inp2:m_Phrase label="lu_comm_Gift_Certificate"/>: </strong></td>
+ <td><inp2:ord_Field name="GiftCertificateDiscount" currency="selected"/></td>
+ </tr>
+ </inp2:m_if>
+
+ <tr class="order-grand-total">
+ <td><inp2:m_Phrase label="lu_comm_GrandTotal"/>:</td>
+ <td><span class="price1"><inp2:ord_Field name="TotalAmount" currency="selected"/></span></td>
+ </tr>
+ </table>
+
+ <input type="submit" name="events[ord][OnCombinedPlaceOrder]" value="<inp2:m_Phrase label='lu_order_CompleteOrder' />" class="button"/>
+ </td>
+ </tr>
+
+ </table>
+ </form>
+
+ </div>
+ </div>
+</inp2:m_DefineElement>
+<!--## /MAIN CONTENT ##-->
+
+<!--## DESIGN TEMPLATE ##-->
+<inp2:m_include template="platform/designs/default_design.des" pass_params="1"/>
+<!--## /DESIGN TEMPLATE ##-->
Property changes on: in-commerce\checkout\one_step_checkout.tpl
___________________________________________________________________
Added: svn:eol-style
+ LF
Index: in-commerce/checkout/shop_cart.tpl
===================================================================
--- in-commerce/checkout/shop_cart.tpl (revision 14590)
+++ in-commerce/checkout/shop_cart.tpl (working copy)
@@ -41,9 +41,13 @@
<inp2:m_Phrase label="lu_title_ShoppingCart"/><inp2:m_if check="orditems_TotalRecords"> (<inp2:orditems_TotalRecords/>)</inp2:m_if>
</inp2:m_Capture>
- <form method="post" action="<inp2:m_FormAction />">
+ <form method="post" id="shopping-cart-form" action="<inp2:m_FormAction />">
- <inp2:m_if check="ord_CartHasError">
+ <div style="border: 1px dashed blue; padding: 3px; margin-bottom: 5px; font-size: 14px; font-family: courier;">
+ <inp2:ord_CheckoutErrorNew/>
+ </div>
+
+ <!--##<inp2:m_if check="ord_CartHasError">
<table class="warning-message fullwidth">
<tr>
<td width="30">
@@ -64,9 +68,9 @@
code_removed_automatically="lu_comm_CouponIsNotEffective"
gc_code_removed_automatically="lu_comm_GiftCertificateIsNotEffective"
changed_after_login="lu_comm_CartChangedAfterLogin" /><br /><br />
- </inp2:m_if>
+ </inp2:m_if>##-->
- <table class="fullwidth">
+ <table class="fullwidth" id="shop-cart-table">
<inp2:m_DefineElement name="shop_cart_header">
<tr>
<td colspan="5">
@@ -75,8 +79,8 @@
</tr>
<tr class="sub-section-header">
<td><inp2:m_Phrase label="lu_comm_ProductDescription"/></td>
+ <td width="50"><inp2:m_Phrase label="lu_comm_Qty"/>.</td>
<td width="60"><inp2:m_Phrase label="lu_comm_YourPrice"/></td>
- <td width="50"><inp2:m_Phrase label="lu_comm_Qty"/>.</td>
<td width="50"><inp2:m_Phrase label="lu_comm_Total"/></td>
<td width="25"> </td>
</tr>
@@ -90,88 +94,100 @@
<inp2:m_include template="in-commerce/elements/options_blocks.elm"/>
<inp2:m_DefineElement name="shop_cart_item">
- <tr>
+ <tr class="shop-cart-row" row_index="<inp2:RowIndex/>" order_item_id="<inp2:Field name='OrderItemId'/>">
<td class="shopping-cart-cell-item-padding">
<table>
<tr>
<td class="shopping-cart-icpn-padding-right">
- <img src="<inp2:m_TemplatesBase module="In-Commerce"/>img/shopping_cart_item.gif" width="16" height="14" alt="" />
+ <img src="<inp2:m_TemplatesBase module='In-Commerce'/>img/shopping_cart_item.gif" width="16" height="14" alt="" />
</td>
<td>
+ <div style="font-size: 14px; font-family: courier;">
+ [ProductId: <strong><inp2:Field name="ProductId"/></strong>; OptionsSalt: <strong><inp2:Field name="OptionsSalt"/></strong>; BackOrderFlag: <strong><inp2:Field name="BackOrderFlag"/></strong>]
+ </div>
+
<inp2:m_if check="FieldEquals" field="Virtual" value="0">
<a href="<inp2:ProductLink template="__default__"/>"><inp2:Field name="Name" /></a>
- <inp2:m_if check="ord_FreePromoShippingAvailable"> <sup><inp2:m_phrase label="lu_cart_FreeShippingAvailable" /></sup>
+ <inp2:m_if check="FreePromoShippingAvailable">
+ <sup><inp2:m_phrase label="lu_cart_FreeShippingAvailable" /></sup>
</inp2:m_if>
<inp2:m_else/>
<inp2:Field name="Name" />
</inp2:m_if>
- <inp2:m_if check="ord_BackorderFlag"> <span class="error"><inp2:m_phrase label="lu_cart_BackorderFlag" /></span></inp2:m_if>
+ <inp2:m_if check="ord_BackorderFlag">
+ <span class="error"><inp2:m_phrase label="lu_cart_BackorderFlag" /></span>
+ </inp2:m_if>
+
<inp2:m_if check="HasOptions">
<br/>
<span style="font-size: 8pt">
- <inp2:m_if check="DisplayOptionsPricing">
- <inp2:PrintOptions render_as="option_element" currency="selected"/>
- <inp2:m_else/>
- <inp2:PrintOptions render_as="option_element_no_price" currency="selected"/>
- </inp2:m_if>
- <inp2:m_if check="FieldEquals" field="OptionsSelectionMode" value="0">
- <a href="<inp2:m_link template="__default__" pass="m,p,orditems"/>"><inp2:m_Phrase label="lu_comm_edit_options"/></a>
- </inp2:m_if>
+ <inp2:m_if check="DisplayOptionsPricing">
+ <inp2:PrintOptions render_as="option_element" currency="selected"/>
+ <inp2:m_else/>
+ <inp2:PrintOptions render_as="option_element_no_price" currency="selected"/>
+ </inp2:m_if>
+
+ <inp2:m_if check="FieldEquals" field="OptionsSelectionMode" value="0">
+ <a href="<inp2:m_link template="__default__" pass="m,p,orditems"/>"><inp2:m_Phrase label="lu_comm_edit_options"/></a>
+ </inp2:m_if>
</span>
</inp2:m_if>
- <inp2:m_if check="p_CustomField" name="Availability">
+
+ <inp2:m_if check="p_Field" name="cust_Availability" db="db">
<br />
<inp2:p_CustomField name="Availability"/>
</inp2:m_if>
- <inp2:m_if check="HasDiscount">
- <br />
- <inp2:m_Phrase label="lu_comm_RegularPrice" />: <inp2:Field name="FlatPrice" currency="selected"/><br />
- <inp2:m_Phrase label="lu_comm_Discount" />: <span class="price1"><inp2:Field name="ItemDiscount" currency="selected" negative="1" /></span>
+
+ <div class="product-discount"<inp2:m_ifnot check="HasDiscount"> style="display: none;"</inp2:m_ifnot>>
+ <inp2:m_Phrase label="lu_comm_RegularPrice" />: <span class="item-price"><inp2:Field name="FlatPrice" currency="selected"/></span><br />
+ <inp2:m_Phrase label="lu_comm_Discount" />: <span class="item-discount price1"><inp2:Field name="ItemDiscount" currency="selected" negative="1" /></span>
+
<!--<a href="javascript:showDiscountInfo('<inp2:ord_DiscountHelpLink template="in-commerce/checkout/discount_info" />')">[?]</a>-->
- </inp2:m_if>
-
+ </div>
</td>
</tr>
</table>
-
</td>
- <td class="shopping-cart-cell-item-padding"><strong><inp2:Field name="Price" currency="selected"/></strong></td>
<td class="shopping-cart-cell-item-padding">
<inp2:m_if check="IsTangible">
-
<inp2:m_if check="m_ModuleEnabled" module="In-Auction">
<inp2:m_if check="ebay-sections_IseBayItem">
- <inp2:Field field="Quantity"/>
+ <span class="product-qty read-only"><inp2:Field field="Quantity"/></span>
<inp2:m_else />
- <input value="<inp2:Field field="Quantity"/>" style="width:20px" class="input-text" name="<inp2:InputName field="Quantity"/>" />
+ <input value="<inp2:Field field="Quantity"/>" style="width:20px" class="input-text product-qty" name="<inp2:InputName field="Quantity"/>" id="<inp2:InputName field="Quantity"/>" />
</inp2:m_if>
<inp2:m_else />
- <input value="<inp2:Field field="Quantity"/>" style="width:20px" class="input-text" name="<inp2:InputName field="Quantity"/>" />
+ <input value="<inp2:Field field="Quantity"/>" style="width:20px" class="input-text product-qty" name="<inp2:InputName field="Quantity"/>" id="<inp2:InputName field="Quantity"/>" />
</inp2:m_if>
<!--<inp2:m_if check="ProductsInStock">
<inp2:m_Phrase name="lu_of"/> <inp2:ProductsInStock/>
</inp2:m_if>-->
<inp2:m_else />
- 1
+ <span class="product-qty read-only"><inp2:Field field="Quantity"/></span>
</inp2:m_if>
</td>
- <td class="shopping-cart-cell-item-padding"><strong><inp2:Field name="ExtendedPrice" currency="selected"/></strong></td>
+ <td class="shopping-cart-cell-item-padding price-cell">
+ <inp2:Field name="Price" currency="selected"/>
+ </td>
+ <td class="shopping-cart-cell-item-padding extended-price-cell" style="font-weight: bold;">
+ <inp2:Field name="ExtendedPrice" currency="selected"/>
+ </td>
<td class="shopping-cart-cell-item-padding" align="center">
<inp2:m_if check="m_ModuleEnabled" module="In-Auction">
<inp2:m_if check="ebay-sections_IseBayItem">
<inp2:m_else />
- <a href="<inp2:LinkRemoveFromCart/>"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/delete.gif" title="Delete" alt="Delete" width="8" height="10" border="0" /></a>
+ <a href="<inp2:LinkRemoveFromCart/>" class="delete-cart-link"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/delete.gif" title="Delete" alt="Delete" width="8" height="10" border="0" /></a>
</inp2:m_if>
<inp2:m_else />
- <a href="<inp2:LinkRemoveFromCart/>"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/delete.gif" title="Delete" alt="Delete" width="8" height="10" border="0" /></a>
+ <a href="<inp2:LinkRemoveFromCart/>" class="delete-cart-link"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/delete.gif" title="Delete" alt="Delete" width="8" height="10" border="0" /></a>
</inp2:m_if>
</td>
</tr>
- <tr>
+ <tr class="separator">
<td colspan="5">
<div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="1" alt="" /></div>
</td>
@@ -186,61 +202,82 @@
<tr >
<td class="cart-subtotal">
<table width="100%">
- <inp2:m_if check="ord_HasDiscount">
- <tr>
+ <tr id="discount-row"<inp2:m_ifnot check="ord_HasDiscount"> style="display: none;"</inp2:m_ifnot>>
<td>
<strong><inp2:m_Phrase label="lu_comm_TotalSavings" />:</strong>
</td>
<td>
- <span class="price1"><strong><inp2:ord_Field name="DiscountTotal" currency="selected" /></strong></span>
+ <span class="price1" style="font-weight: bold;"><inp2:ord_Field name="DiscountTotal" currency="selected"/></span>
</td>
</tr>
- <tr>
+
+ <tr id="discount-row-separator"<inp2:m_ifnot check="ord_HasDiscount"> style="display: none;"</inp2:m_ifnot>>
<td colspan="2">
<img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="5" alt="" />
</td>
</tr>
- </inp2:m_if>
- <inp2:m_if check="ord_Field" name="CouponId">
- <tr>
+
+ <tr id="coupon-row">
<td>
- <inp2:m_Phrase label="lu_comm_CouponHasBeenApplied" />:
+ <div class="used"<inp2:m_ifnot check="ord_Field" name="CouponId" db="db"> style="display: none;"</inp2:m_ifnot>>
+ <inp2:m_Phrase label="lu_comm_CouponHasBeenApplied" />:
+ </div>
+
+ <div class="not-used"<inp2:m_if check="ord_Field" name="CouponId" db="db"> style="display: none;"</inp2:m_if>>
+ <inp2:m_Phrase label="lu_comm_EnterCouponCode" />:
+ </div>
</td>
<td>
- <inp2:ord_Field field="CouponName" />
+ <div class="used"<inp2:m_ifnot check="ord_Field" name="CouponId" db="db"> style="display: none;"</inp2:m_ifnot>>
+ <span class="coupon-name"><inp2:ord_Field field="CouponName" /></span>
+ <a id="remove-coupon" href="<inp2:ord_RemoveCouponLink type='coupon'/>"><img src="<inp2:m_TemplatesBase module='In-Portal'/>img/delete.gif" title="<inp2:m_Phrase label='lu_comm_RemoveCoupon' no_editing='1'/>" alt="<inp2:m_Phrase label='lu_comm_RemoveCoupon' no_editing='1'/>" width="8" height="10" border="0" /></a>
+ </div>
- <a href="<inp2:ord_RemoveCouponLink type="coupon"/>"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/delete.gif" title="<inp2:m_Phrase label="lu_comm_RemoveCoupon" no_editing="1"/>" alt="<inp2:m_Phrase label="lu_comm_RemoveCoupon" no_editing="1"/>" width="8" height="10" border="0" /></a>
+ <div class="not-used"<inp2:m_if check="ord_Field" name="CouponId" db="db"> style="display: none;"</inp2:m_if>>
+ <input type="button" class="button" id="apply-coupon" value="<inp2:m_Phrase name='lu_btn_Apply' no_editing='1' html_escape='1'/>"/>
+
+ <div style="float: left; margin-right: 8px;">
+ <input size="15" class="input-text coupon-code" name="coupon_code" value=""/>
+ </div>
+ </div>
</td>
</tr>
- <inp2:m_else />
+
<tr>
- <td><inp2:m_Phrase label="lu_comm_EnterCouponCode" />: </td>
- <td><input size="15" class="input-text" name="coupon_code" /></td>
+ <td colspan="2">
+ <img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="3" alt="" />
+ </td>
</tr>
- </inp2:m_if>
- <tr>
- <td colspan="2">
- <img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="3" alt="" />
- </td>
- </tr>
- <inp2:m_if check="ord_Field" name="GiftCertificateId">
- <tr>
- <td><inp2:m_Phrase label="lu_comm_GiftCertificateHasBeenApplied" />: </td>
+
+ <tr id="gift-certificate-row">
<td>
- <inp2:ord_Field field="GiftCertificateDiscount" currency="selected" />
- <a href="<inp2:ord_RemoveCouponLink type="gift_certificate"/>"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/delete.gif" title="<inp2:m_Phrase label="lu_comm_RemoveGiftCertificate" no_editing="1"/>" alt="<inp2:m_Phrase label="lu_comm_RemoveGiftCertificate" no_editing="1"/>" width="8" height="10" border="0" /></a>
+ <div class="used"<inp2:m_ifnot check="ord_Field" name="GiftCertificateId" db="db"> style="display: none;"</inp2:m_ifnot>>
+ <inp2:m_Phrase label="lu_comm_GiftCertificateHasBeenApplied" />:
+ </div>
+
+ <div class="not-used"<inp2:m_if check="ord_Field" name="GiftCertificateId" db="db"> style="display: none;"</inp2:m_if>>
+ <inp2:m_Phrase label="lu_comm_EnterGiftCertificateCode" />:
+ </div>
</td>
+ <td>
+ <div class="used"<inp2:m_ifnot check="ord_Field" name="GiftCertificateId" db="db"> style="display: none;"</inp2:m_ifnot>>
+ <span class="gift-certificate-discount"><inp2:ord_Field field="GiftCertificateDiscount" currency="selected" /></span>
+ <a id="remove-gift-certificate" href="<inp2:ord_RemoveCouponLink type='gift_certificate'/>"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/delete.gif" title="<inp2:m_Phrase label="lu_comm_RemoveGiftCertificate" no_editing="1"/>" alt="<inp2:m_Phrase label="lu_comm_RemoveGiftCertificate" no_editing="1"/>" width="8" height="10" border="0" /></a>
+ </div>
+
+ <div class="not-used"<inp2:m_if check="ord_Field" name="GiftCertificateId" db="db"> style="display: none;"</inp2:m_if>>
+ <input type="button" class="button" id="apply-gift-certificate" value="<inp2:m_Phrase name='lu_btn_Apply' no_editing='1' html_escape='1'/>"/>
+
+ <div style="float: left; margin-right: 8px;">
+ <input size="15" class="input-text gift-certificate-code" name="giftcert_code" />
+ </div>
+ </div>
+ </td>
</tr>
- <inp2:m_else />
- <tr>
- <td><inp2:m_Phrase label="lu_comm_EnterGiftCertificateCode" />: </td>
- <td><input size="15" class="input-text" name="giftcert_code" /></td>
- </tr>
- </inp2:m_if>
</table>
</td>
<td class="cart-subtotal" align="right">
- <span class="cart-subtotal-text"><inp2:m_Phrase label="lu_comm_Subtotal"/>: <inp2:ord_Field field="SubtotalWithDiscount" currency="selected"/></span>
+ <span class="cart-subtotal-text"><inp2:m_Phrase label="lu_comm_Subtotal"/>: <span id="sub-total"><inp2:ord_Field field="SubTotal" currency="selected"/></span></span>
</td>
</tr>
<tr>
@@ -252,7 +289,47 @@
<input type="hidden" name="next_step_template" value="<inp2:m_if check="ord_OrderHasTangibleItems">in-commerce/checkout/shipping<inp2:m_else/>in-commerce/checkout/billing</inp2:m_if>" />
<tr>
<td class="shopping-cart-button-padding">
- <input class="button" type="submit" name="events[ord][OnUpdateCart]" value="<inp2:m_Phrase label="lu_comm_UpdateCart" no_editing="1"/>" />
+ <script type="text/javascript">
+ var $aShopCartManager = new ShopCartManager(
+ {
+ updateUrl: '<inp2:m_Link ord_event="OnUpdateCartJSON" currency="selected" pass="m,ord" js_escape="1" no_amp="1"/>',
+ constants: {
+ 'OrderCheckoutErrorType::PRODUCT': <inp2:m_GetConst name="OrderCheckoutErrorType::PRODUCT"/>,
+ 'OrderCheckoutError::FIELD_UPDATE_SUCCESS': <inp2:m_GetConst name="OrderCheckoutError::FIELD_UPDATE_SUCCESS"/>,
+ 'OrderCheckoutError::FIELD_UPDATE_ERROR': <inp2:m_GetConst name="OrderCheckoutError::FIELD_UPDATE_ERROR"/>,
+ 'OrderCheckoutError::QTY_UNAVAILABLE': <inp2:m_GetConst name="OrderCheckoutError::QTY_UNAVAILABLE"/>,
+ 'OrderCheckoutError::QTY_OUT_OF_STOCK': <inp2:m_GetConst name="OrderCheckoutError::QTY_OUT_OF_STOCK"/>,
+ 'OrderCheckoutError::QTY_CHANGED_TO_MINIMAL': <inp2:m_GetConst name="OrderCheckoutError::QTY_CHANGED_TO_MINIMAL"/>,
+
+ 'OrderCheckoutErrorType::COUPON': <inp2:m_GetConst name="OrderCheckoutErrorType::COUPON"/>,
+ 'OrderCheckoutError::COUPON_APPLIED': <inp2:m_GetConst name="OrderCheckoutError::COUPON_APPLIED"/>,
+ 'OrderCheckoutError::COUPON_REMOVED': <inp2:m_GetConst name="OrderCheckoutError::COUPON_REMOVED"/>,
+ 'OrderCheckoutError::COUPON_REMOVED_AUTOMATICALLY': <inp2:m_GetConst name="OrderCheckoutError::COUPON_REMOVED_AUTOMATICALLY"/>,
+ 'OrderCheckoutError::COUPON_CODE_INVALID': <inp2:m_GetConst name="OrderCheckoutError::COUPON_CODE_INVALID"/>,
+ 'OrderCheckoutError::COUPON_CODE_EXPIRED': <inp2:m_GetConst name="OrderCheckoutError::COUPON_CODE_EXPIRED"/>,
+
+
+ 'OrderCheckoutErrorType::GIFT_CERTIFICATE': <inp2:m_GetConst name="OrderCheckoutErrorType::GIFT_CERTIFICATE"/>,
+ 'OrderCheckoutError::GC_APPLIED': <inp2:m_GetConst name="OrderCheckoutError::GC_APPLIED"/>,
+ 'OrderCheckoutError::GC_REMOVED': <inp2:m_GetConst name="OrderCheckoutError::GC_REMOVED"/>,
+ 'OrderCheckoutError::GC_REMOVED_AUTOMATICALLY': <inp2:m_GetConst name="OrderCheckoutError::GC_REMOVED_AUTOMATICALLY"/>,
+ 'OrderCheckoutError::GC_CODE_INVALID': <inp2:m_GetConst name="OrderCheckoutError::GC_CODE_INVALID"/>,
+ 'OrderCheckoutError::GC_CODE_EXPIRED': <inp2:m_GetConst name="OrderCheckoutError::GC_CODE_EXPIRED"/>,
+
+ 'OrderCheckoutErrorType::DISCOUNT': <inp2:m_GetConst name="OrderCheckoutErrorType::DISCOUNT"/>,
+ 'OrderCheckoutError::DISCOUNT_APPLIED': <inp2:m_GetConst name="OrderCheckoutError::DISCOUNT_APPLIED"/>,
+ 'OrderCheckoutError::DISCOUNT_REMOVED': <inp2:m_GetConst name="OrderCheckoutError::DISCOUNT_REMOVED"/>,
+
+ 'PRODUCT_TYPE_TANGIBLE': <inp2:m_GetConst name="PRODUCT_TYPE_TANGIBLE"/>
+ },
+ currencyMask: '<inp2:ord_CurrencyMask currency="selected" js_escape="1"/>',
+ orderInfo: <inp2:ord_PrintOrderInfo currency="selected"/>
+ }
+ );
+
+ </script>
+
+ <input class="button" type="submit" id="update-cart" name="events[ord][OnUpdateCart]" value="<inp2:m_Phrase label="lu_comm_UpdateCart" no_editing="1"/>" />
<input class="button" type="submit" name="events[ord][OnCleanupCart]" onclick="return confirm('<inp2:m_Phrase label="lu_comm_ClearCartConfirmation" />')" value="<inp2:m_Phrase label="lu_comm_CleanupCart" no_editing="1"/>" />
</td>
@@ -317,6 +394,57 @@
</inp2:m_if>
</div>
</div>
+
+ <textarea id="product-row-mask" style="display: none;">
+ <tr class="shop-cart-row" row_index="{ROW_INDEX}" order_item_id="{field:OrderItemId}">
+ <td class="shopping-cart-cell-item-padding">
+ <table>
+ <tr>
+ <td class="shopping-cart-icpn-padding-right">
+ <img src="<inp2:m_TemplatesBase module='In-Commerce'/>img/shopping_cart_item.gif" width="16" height="14" alt="" />
+ </td>
+ <td>
+ <span class="product-with-link" style="display: none;">
+ <a href="#"></a>
+ </span>
+
+ <span class="product-without-link" style="display: none;"></span>
+
+ <span class="free-shipping">
+ <sup><inp2:m_phrase label="lu_cart_FreeShippingAvailable" /></sup>
+ </span>
+
+ <span class="back-order-mark error"><inp2:m_phrase label="lu_cart_BackorderFlag" /></span>
+
+ <span class="product-availability" style="display: none;"></span>
+
+ <div class="product-discount" style="display: none;">
+ <inp2:m_Phrase label="lu_comm_RegularPrice" />: <span class="item-price"></span><br />
+ <inp2:m_Phrase label="lu_comm_Discount" />: <span class="item-discount price1"></span>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="shopping-cart-cell-item-padding">
+ <input value="{field:Quantity}" style="width:20px" class="input-text product-qty" name="<inp2:orditems_InputName field='Quantity' force_id="{field:OrderItemId}"/>" id="<inp2:orditems_InputName field='Quantity' force_id="{field:OrderItemId}"/>" />
+ <span class="product-qty read-only">{field:Quantity}</span>
+ </td>
+ <td class="shopping-cart-cell-item-padding price-cell"></td>
+ <td class="shopping-cart-cell-item-padding extended-price-cell" style="font-weight: bold;"></td>
+ <td class="shopping-cart-cell-item-padding" align="center">
+ <a href="#" class="delete-cart-link"><img src="<inp2:m_TemplatesBase module='In-Portal'/>img/delete.gif" title="Delete" alt="Delete" width="8" height="10" border="0" /></a>
+ </td>
+ </tr>
+ </textarea>
+
+ <textarea id="product-row-separator-mask" style="display: none;">
+ <tr class="separator">
+ <td colspan="5">
+ <div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="1" alt="" /></div>
+ </td>
+ </tr>
+ </textarea>
</inp2:m_DefineElement>
<!--## /MAIN CONTENT ##-->
Index: in-commerce/elements/content_boxes/checkout/shipping_options.elm.tpl
===================================================================
--- in-commerce/elements/content_boxes/checkout/shipping_options.elm.tpl (revision 14590)
+++ in-commerce/elements/content_boxes/checkout/shipping_options.elm.tpl (working copy)
@@ -2,197 +2,22 @@
<option <inp2:m_param name="selected"/> value="<inp2:m_param name="ShippingId"/>"><inp2:m_param name="ShippingName"/> (<inp2:m_if check="m_param" name="ShippingFree" value="1"><inp2:m_Phrase label="lu_comm_FreeShipping" /><inp2:m_else/><inp2:m_param name="TotalCost"/></inp2:m_if>)</option>
</inp2:m_DefineElement>
-<inp2:m_DefineElement name="shippings_table_header">
- <table width="100%">
- <tr>
- <td colspan="4">
- <div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="1" alt="" /></div>
- </td>
- </tr>
- <tr class="sub-section-header">
- <td><inp2:m_Phrase label="lu_ship_Shipment" /></td>
- <td><inp2:m_Phrase label="lu_ship_ItemsNumber" /></td>
- <td><inp2:m_Phrase label="lu_ship_ShippingWeight" /></td>
- <td><inp2:m_Phrase label="lu_ship_ShippingType" /></td>
- </tr>
- <tr>
- <td colspan="4">
- <div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="1" alt="" /></div>
- </td>
- </tr>
-
- <inp2:m_if check="ord_CartHasBackorders">
- <strong><inp2:m_Phrase label="lu_comm_Note"/>:</strong>
- <inp2:m_Phrase label="lu_comm_YouHaveBackorderedItems"/>
-
- <br />
- <inp2:m_DefineElement name="order_option">
- <input onclick="document.getElementById('events[ord][OnUpdate]').click();" type="radio"
- <inp2:m_param name="checked"/>
- name="<inp2:m_param name="field_name"/>"
- id="<inp2:m_param name="field_name"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>">
- <label for="<inp2:m_param name="field_name"/>_<inp2:m_param name="key"/>">
- <inp2:m_phrase label="$option"/>
- </label> <br />
- </inp2:m_DefineElement>
- <inp2:ord_PredefinedOptions field="ShippingOption" render_as="order_option" selected_param="checked" selected="checked=\"checked\""/>
- <br />
- </inp2:m_if>
-
- <inp2:m_if check="m_GetEquals" var="shipping_limitations_apply" value="0"><inp2:m_else/>
- <strong><inp2:m_Phrase label="lu_comm_Note"/>:</strong>
- <inp2:m_if check="m_GetEquals" var="shipping_limitations_apply" value="1">
- <inp2:m_Phrase label="lu_comm_ShippingTypesLimitationApply"/><br/>
- <input type="hidden" name="<inp2:ord_InputName field="ShippingGroupOption"/>" id="<inp2:ord_InputName field="ShippingGroupOption"/>" value="<inp2:ord_Field name="ShippingGroupOption" db="1"/>" />
- <input onclick="document.getElementById('<inp2:ord_InputName field="ShippingGroupOption"/>').value = this.checked ? 1:0; document.getElementById('events[ord][OnUpdate]').click();" type="checkbox"
- <inp2:m_param name="checked"/>
- name="cb_<inp2:ord_InputName field="ShippingGroupOption"/>"
- id="cb_<inp2:ord_InputName field="ShippingGroupOption"/>" value="1" <inp2:ord_Field name="ShippingGroupOption" db="1" checked="checked"/> />
- <label for="cb_<inp2:ord_InputName field="ShippingGroupOption"/>">
- <inp2:m_phrase label="lu_AdjustShippingManually"/>
- </label> <br />
- <inp2:m_else/> <!-- Order canNOT be shipped with single shipping type -->
- <inp2:m_Phrase label="lu_comm_ShippingTypesLimitationApply_CantSingleShip"/><br/>
- <input type="hidden" name="<inp2:ord_InputName field="ShippingGroupOption"/>" value="1" />
- </inp2:m_if>
- </inp2:m_if>
-</inp2:m_DefineElement>
-
-<inp2:m_DefineElement name="shippings_table_footer">
- <tr>
- <td class="shopping-cart-cell-item-padding">
- <input class="button" type="submit" name="events[ord][OnUpdate]" value="<inp2:m_Phrase label="lu_comm_UpdateShipping" no_editing="1"/>"/><br/>
- </td>
- <td> </td>
- <td class="shopping-cart-cell-item-padding" style="text-align: right">
- <strong><inp2:m_Phrase label="lu_comm_ShippingTotal" />:</strong>
- </td>
- <td class="shopping-cart-cell-item-padding">
- <inp2:ord_Field name="ShippingCost" currency="selected"/>
- </td>
- </tr>
-
- <tr class="cart-subtotal">
- <td> </td>
- <td> </td>
- <td style="text-align: right">
- <strong><inp2:m_Phrase label="lu_comm_Insurance_Fee"/>:</strong>
- </td>
- <td class="shopping-cart-cell-item-padding">
- <inp2:ord_Field name="InsuranceFee" currency="selected"/>
- </td>
- </tr>
-
- <inp2:m_DefineElement name="products_total">
- <tr class="cart-subtotal">
- <td> </td>
- <td> </td>
- <td style="text-align: right">
- <strong><inp2:m_Phrase label="lu_comm_ProductsTotal"/>:</strong>
- </td>
- <td>
- <inp2:ord_Field name="SubTotal" currency="selected"/>
- </td>
- </tr>
- </inp2:m_DefineElement>
-
- <inp2:m_DefineElement name="processing_total">
- <tr class="cart-subtotal">
- <td> </td>
- <td> </td>
- <td style="text-align: right">
- <strong><inp2:m_Phrase label="lu_comm_ProcessingFee"/>:</strong>
- </td>
- <td>
- <inp2:ord_Field name="ProcessingFee" currency="selected"/>
- </td>
- </tr>
- </inp2:m_DefineElement>
-
- <inp2:m_DefineElement name="sub_total">
- <tr>
- <td> </td>
- <td> </td>
- <td align="right" class="shopping-cart-cell-item-padding">
- <strong><inp2:m_Phrase label="lu_comm_SubTotal"/>:</strong>
- </td>
- <td class="shopping-cart-cell-item-padding">
- <span class="price1"><inp2:ord_Field name="AmountWithoutVAT" currency="selected"/></span>
- </td>
- </tr>
- </inp2:m_DefineElement>
-
- <inp2:m_DefineElement name="vat_total">
- <tr>
- <td> </td>
- <td> </td>
- <td class="shopping-cart-cell-item-padding" align="right">
- <strong><inp2:m_Phrase label="lu_comm_VAT"/> <inp2:ord_Field name="VATPercent"/>%:</strong>
- </td>
- <td class="shopping-cart-cell-item-padding">
- <span class="price1"><inp2:ord_Field name="VAT" currency="selected"/></span>
- </td>
- </tr>
- </inp2:m_DefineElement>
-
- <inp2:ord_PrintTotals
- products_render_as="products_total"
- processing_render_as="processing_total"
- sub_total_render_as="sub_total"
- vat_render_as="vat_total"/>
-
- <inp2:m_if check="ord_Field" name="GiftCertificateId">
- <tr>
- <td> </td>
- <td> </td>
- <td class="shopping-cart-cell-item-padding" align="right">
- <strong><inp2:m_Phrase label="lu_comm_Gift_Certificate"/>:</strong>
- </td>
- <td class="shopping-cart-cell-item-padding">
- <span class="price1"><inp2:ord_Field name="GiftCertificateDiscount" currency="selected"/></span>
- </td>
- </tr>
- </inp2:m_if>
-
- <tr class="cart-subtotal order-grand-total">
- <td> </td>
- <td> </td>
- <td class="shopping-cart-cell-item-padding" align="right">
- <inp2:m_Phrase label="lu_comm_GrandTotal"/>:
- </td>
- <td class="shopping-cart-cell-item-padding">
- <inp2:ord_Field name="TotalAmount" currency="selected"/>
- </td>
- </tr>
-
- <tr>
- <td> </td>
- <td> </td>
- <td> </td>
- <td class="shopping-cart-cell-item-padding">
- <input type="hidden" name="next_step_template" value="in-commerce/checkout/billing">
- <input type="submit" name="events[ord][OnProceedToBilling]" value="<inp2:m_Phrase label="lu_comm_ProceedToBilling" no_editing="1"/>" class="button">
- </td>
- </tr>
-
- </table>
-</inp2:m_DefineElement>
-
<inp2:m_include template="in-commerce/elements/options_blocks.elm"/>
<inp2:m_DefineElement name="shipping_group_item">
- <inp2:Field name="Name"/><inp2:m_if check="ord_BackorderFlag"> <span class="backordered-product"><inp2:m_phrase label="lu_cart_BackorderFlag" /></span></inp2:m_if><br />
+ <inp2:Field name="ProductName"/><inp2:m_if check="ord_BackorderFlag"> <span class="backordered-product"><inp2:m_phrase label="lu_cart_BackorderFlag" /></span></inp2:m_if><br />
+
<inp2:m_if check="HasOptions">
<br/>
<span style="font-size: 8pt">
- <inp2:m_if check="DisplayOptionsPricing"> <!-- selectable options or overriding combination -->
- <inp2:PrintOptions render_as="option_element" currency="selected"/>
- <inp2:m_else/> <!-- listed combinations -->
- <inp2:PrintOptions render_as="option_element_no_price"/>
- </inp2:m_if>
- <inp2:m_if check="FieldEquals" field="OptionsSelectionMode" value="0"> <!-- selectable options -->
- <a href="<inp2:m_link template="__default__" pass="m,p,orditems"/>"><inp2:m_Phrase label="lu_comm_edit_options"/></a><br />
- </inp2:m_if>
+ <inp2:m_if check="DisplayOptionsPricing"> <!-- selectable options or overriding combination -->
+ <inp2:PrintOptions render_as="option_element" currency="selected"/>
+ <inp2:m_else/> <!-- listed combinations -->
+ <inp2:PrintOptions render_as="option_element_no_price"/>
+ </inp2:m_if>
+ <inp2:m_if check="FieldEquals" field="OptionsSelectionMode" value="0"> <!-- selectable options -->
+ <a href="<inp2:m_link template="__default__" pass="m,p,orditems"/>"><inp2:m_Phrase label="lu_comm_edit_options"/></a><br />
+ </inp2:m_if>
</span>
</inp2:m_if>
</inp2:m_DefineElement>
@@ -201,13 +26,13 @@
<tr class="cart-item">
<td class="shopping-cart-cell-item-padding"><inp2:m_param name="shipment"/><br/>
<b><inp2:m_Phrase label="lu_Items"/>:</b><br />
- <inp2:ord_PrintCart item_render_as="shipping_group_item" requery="1" package_num="$package_num" product_type="1" header_render_as="html:" footer_render_as="html:"/>
+ <inp2:ord_PrintCart item_render_as="shipping_group_item" requery="1" package_num="$package_num" product_type="1"/>
</td>
<td class="shopping-cart-cell-item-padding"><inp2:m_param name="items"/></td>
<td class="shopping-cart-cell-item-padding"><inp2:m_param name="weight"/></td>
<td class="shopping-cart-cell-item-padding">
<select class="input-select" name="<inp2:m_param name="field_name"/>">
- <inp2:ord_PrintShippingTypes render_as="order_shipping_type" currency="selected" />
+ <inp2:ord_PrintShippingTypes render_as="order_shipping_type" currency="selected"/>
</select>
</td>
</tr>
@@ -223,14 +48,185 @@
<inp2:m_Phrase label="lu_comm_ErrorNoShippingTypes"/> (<a href="mailto:<inp2:conf_ConfigValue name="Comm_Contacts_Email"/>"><inp2:conf_ConfigValue name="Comm_Contacts_Email"/></a>).
</inp2:m_DefineElement>
-<inp2:m_DefineElement name="invalid_address">
- <inp2:m_Phrase label="lu_comm_ErrorInvalidShippingAddress"/>.
-</inp2:m_DefineElement>
-
<inp2:m_RenderElement design="content_box">
<inp2:m_Capture to_var="header">
<inp2:m_Phrase label="lu_title_ShippingOptions"/>
</inp2:m_Capture>
- <inp2:ord_PrintShippings render_as="order_shipment" currency="selected" no_shipments_render_as="no_shipments" invalid_address_render_as="invalid_address" table_header_render_as="shippings_table_header" table_footer_render_as="shippings_table_footer" />
+ <inp2:m_if check="ord_AddressValid" type="shipping">
+ <table width="100%">
+ <tr>
+ <td colspan="4">
+ <div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="1" alt="" /></div>
+ </td>
+ </tr>
+ <tr class="sub-section-header">
+ <td><inp2:m_Phrase label="lu_ship_Shipment" /></td>
+ <td><inp2:m_Phrase label="lu_ship_ItemsNumber" /></td>
+ <td><inp2:m_Phrase label="lu_ship_ShippingWeight" /></td>
+ <td><inp2:m_Phrase label="lu_ship_ShippingType" /></td>
+ </tr>
+ <tr>
+ <td colspan="4">
+ <div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="1" height="1" alt="" /></div>
+ </td>
+ </tr>
+
+ <inp2:m_if check="ord_CartHasBackorders">
+ <strong><inp2:m_Phrase label="lu_comm_Note"/>:</strong>
+ <inp2:m_Phrase label="lu_comm_YouHaveBackorderedItems"/>
+
+ <br />
+ <inp2:m_DefineElement name="order_option">
+ <input onclick="document.getElementById('events[ord][OnUpdate]').click();" type="radio"
+ <inp2:m_param name="checked"/>
+ name="<inp2:m_param name="field_name"/>"
+ id="<inp2:m_param name="field_name"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>">
+ <label for="<inp2:m_param name="field_name"/>_<inp2:m_param name="key"/>">
+ <inp2:m_phrase label="$option"/>
+ </label> <br />
+ </inp2:m_DefineElement>
+ <inp2:ord_PredefinedOptions field="ShippingOption" render_as="order_option" selected_param="checked" selected="checked=\"checked\""/>
+ <br />
+ </inp2:m_if>
+
+ <inp2:m_if check="m_GetEquals" var="shipping_limitations_apply" value="0"><inp2:m_else/>
+ <strong><inp2:m_Phrase label="lu_comm_Note"/>:</strong>
+ <inp2:m_if check="m_GetEquals" var="shipping_limitations_apply" value="1">
+ <inp2:m_Phrase label="lu_comm_ShippingTypesLimitationApply"/><br/>
+ <input type="hidden" name="<inp2:ord_InputName field="ShippingGroupOption"/>" id="<inp2:ord_InputName field="ShippingGroupOption"/>" value="<inp2:ord_Field name="ShippingGroupOption" db="1"/>" />
+ <input onclick="document.getElementById('<inp2:ord_InputName field="ShippingGroupOption"/>').value = this.checked ? 1:0; document.getElementById('events[ord][OnUpdate]').click();" type="checkbox"
+ <inp2:m_param name="checked"/>
+ name="cb_<inp2:ord_InputName field="ShippingGroupOption"/>"
+ id="cb_<inp2:ord_InputName field="ShippingGroupOption"/>" value="1" <inp2:ord_Field name="ShippingGroupOption" db="1" checked="checked"/> />
+ <label for="cb_<inp2:ord_InputName field="ShippingGroupOption"/>">
+ <inp2:m_phrase label="lu_AdjustShippingManually"/>
+ </label> <br />
+ <inp2:m_else/> <!-- Order canNOT be shipped with single shipping type -->
+ <inp2:m_Phrase label="lu_comm_ShippingTypesLimitationApply_CantSingleShip"/><br/>
+ <input type="hidden" name="<inp2:ord_InputName field="ShippingGroupOption"/>" value="1" />
+ </inp2:m_if>
+ </inp2:m_if>
+
+ <inp2:ord_PrintShippings render_as="order_shipment" currency="selected" no_shipments_render_as="no_shipments" />
+
+ <tr>
+ <td class="shopping-cart-cell-item-padding">
+ <input class="button" type="submit" name="events[ord][OnUpdate]" value="<inp2:m_Phrase label="lu_comm_UpdateShipping" no_editing="1"/>"/><br/>
+ </td>
+ <td> </td>
+ <td class="shopping-cart-cell-item-padding" style="text-align: right">
+ <strong><inp2:m_Phrase label="lu_comm_ShippingTotal" />:</strong>
+ </td>
+ <td class="shopping-cart-cell-item-padding">
+ <inp2:ord_Field name="ShippingCost" currency="selected"/>
+ </td>
+ </tr>
+
+ <tr class="cart-subtotal">
+ <td> </td>
+ <td> </td>
+ <td style="text-align: right">
+ <strong><inp2:m_Phrase label="lu_comm_Insurance_Fee"/>:</strong>
+ </td>
+ <td class="shopping-cart-cell-item-padding">
+ <inp2:ord_Field name="InsuranceFee" currency="selected"/>
+ </td>
+ </tr>
+
+ <inp2:m_DefineElement name="products_total">
+ <tr class="cart-subtotal">
+ <td> </td>
+ <td> </td>
+ <td style="text-align: right">
+ <strong><inp2:m_Phrase label="lu_comm_ProductsTotal"/>:</strong>
+ </td>
+ <td>
+ <inp2:ord_Field name="SubTotal" currency="selected"/>
+ </td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="processing_total">
+ <tr class="cart-subtotal">
+ <td> </td>
+ <td> </td>
+ <td style="text-align: right">
+ <strong><inp2:m_Phrase label="lu_comm_ProcessingFee"/>:</strong>
+ </td>
+ <td>
+ <inp2:ord_Field name="ProcessingFee" currency="selected"/>
+ </td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="sub_total">
+ <tr>
+ <td> </td>
+ <td> </td>
+ <td align="right" class="shopping-cart-cell-item-padding">
+ <strong><inp2:m_Phrase label="lu_comm_SubTotal"/>:</strong>
+ </td>
+ <td class="shopping-cart-cell-item-padding">
+ <span class="price1"><inp2:ord_Field name="AmountWithoutVAT" currency="selected"/></span>
+ </td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:m_DefineElement name="vat_total">
+ <tr>
+ <td> </td>
+ <td> </td>
+ <td class="shopping-cart-cell-item-padding" align="right">
+ <strong><inp2:m_Phrase label="lu_comm_VAT"/> <inp2:ord_Field name="VATPercent"/>%:</strong>
+ </td>
+ <td class="shopping-cart-cell-item-padding">
+ <span class="price1"><inp2:ord_Field name="VAT" currency="selected"/></span>
+ </td>
+ </tr>
+ </inp2:m_DefineElement>
+
+ <inp2:ord_PrintTotals
+ products_render_as="products_total"
+ processing_render_as="processing_total"
+ sub_total_render_as="sub_total"
+ vat_render_as="vat_total"/>
+
+ <inp2:m_if check="ord_Field" name="GiftCertificateId">
+ <tr>
+ <td> </td>
+ <td> </td>
+ <td class="shopping-cart-cell-item-padding" align="right">
+ <strong><inp2:m_Phrase label="lu_comm_Gift_Certificate"/>:</strong>
+ </td>
+ <td class="shopping-cart-cell-item-padding">
+ <span class="price1"><inp2:ord_Field name="GiftCertificateDiscount" currency="selected"/></span>
+ </td>
+ </tr>
+ </inp2:m_if>
+
+ <tr class="cart-subtotal order-grand-total">
+ <td> </td>
+ <td> </td>
+ <td class="shopping-cart-cell-item-padding" align="right">
+ <inp2:m_Phrase label="lu_comm_GrandTotal"/>:
+ </td>
+ <td class="shopping-cart-cell-item-padding">
+ <inp2:ord_Field name="TotalAmount" currency="selected"/>
+ </td>
+ </tr>
+
+ <tr>
+ <td> </td>
+ <td> </td>
+ <td> </td>
+ <td class="shopping-cart-cell-item-padding">
+ <input type="hidden" name="next_step_template" value="in-commerce/checkout/billing">
+ <input type="submit" name="events[ord][OnProceedToBilling]" value="<inp2:m_Phrase label="lu_comm_ProceedToBilling" no_editing="1"/>" class="button">
+ </td>
+ </tr>
+ </table>
+ <inp2:m_else/>
+ <inp2:m_Phrase label="lu_comm_ErrorInvalidShippingAddress"/>.
+ </inp2:m_if>
</inp2:m_RenderElement>
\ No newline at end of file
Index: in-commerce/elements/html_head.elm.tpl
===================================================================
--- in-commerce/elements/html_head.elm.tpl (revision 14590)
+++ in-commerce/elements/html_head.elm.tpl (working copy)
@@ -3,4 +3,8 @@
<inp2:m_Compress files="in-commerce/inc/styles.css" to="all_css"/>
<!--## <inp2:m_Compress files="in-commerce/inc/script.js" to="all_js"/> ##-->
+<inp2:m_if check="m_Get" name="t" equals_to="in-commerce/checkout/shop_cart">
+ <inp2:m_Compress files="in-commerce/inc/cart_manager.js" to="all_js"/>
+</inp2:m_if>
+
<!--## /CSS & JAVASCRIPT FOR IN-COMMERCE ##-->
Index: in-commerce/elements/side_boxes/checkout_steps.elm.tpl
===================================================================
--- in-commerce/elements/side_boxes/checkout_steps.elm.tpl (revision 14590)
+++ in-commerce/elements/side_boxes/checkout_steps.elm.tpl (working copy)
@@ -39,6 +39,9 @@
in-commerce/checkout/confirmation" />
</inp2:m_if>
+
+ <br/>
+ <a href="<inp2:m_Link template='in-commerce/checkout/one_step_checkout'/>">One Step Checkout</a>
</td>
</tr>
</table>
\ No newline at end of file
Index: in-commerce/inc/cart_manager.js
===================================================================
--- in-commerce/inc/cart_manager.js (revision 0)
+++ in-commerce/inc/cart_manager.js (revision 0)
@@ -0,0 +1,538 @@
+function ShopCartManager( $settings ) {
+ this.updateUrl = '';
+ this.orderInfo = {};
+ this.constants = {};
+ this.currencyMask = '%s';
+
+ $.extend(this, $settings);
+
+ this.tooltips = [];
+ this.rowTimers = {};
+
+ var $me = this;
+
+ $(document).ready(
+ function () {
+ $me.init();
+ }
+ );
+}
+
+ShopCartManager.prototype.init = function () {
+ var $me = this;
+
+ this.process(this.orderInfo);
+
+ $('.delete-cart-link').click(
+ function ($e) {
+ var $order_item_id = $(this).parents('tr:first').attr('order_item_id');
+
+ $me.apply( [{name: 'delete_id', value: $order_item_id}] );
+
+ return false;
+ }
+ );
+
+ $('.product-qty:input', '#shopping-cart-form')
+ .blur(
+ function ($e) {
+ var $row_index = $(this).parents('tr[row_index]:first').attr('row_index');
+
+ console.log('blur on ', $row_index, ' row');
+
+ $me.clearRowTimers($row_index);
+
+ console.log('doing apply (from blur) on ', $row_index, ' row');
+ $me.apply();
+
+ return false;
+ }
+ )
+ .keyup(
+ function ($e) {
+ var $row_index = $(this).parents('tr[row_index]:first').attr('row_index');
+
+ console.log('keyup on ', $row_index, ' row');
+
+ $me.clearRowTimers($row_index);
+
+ $me.rowTimers[$row_index] = setTimeout(
+ function() {
+ console.log('doing apply (from keyup) on ', $row_index, ' row');
+ $me.apply();
+ }
+ , 2000
+ );
+ }
+ );
+
+
+ $('#remove-coupon').click(
+ function ($e) {
+ $me.apply( [{name: 'remove', value: 'coupon'}] );
+
+ return false;
+ }
+ );
+
+ $('#remove-gift-certificate').click(
+ function ($e) {
+ $me.apply( [{name: 'remove', value: 'gift_certificate'}] );
+
+ return false;
+ }
+ );
+
+ $('#update-cart, #apply-coupon, #apply-gift-certificate').click(
+ function ($e) {
+ $me.apply();
+
+ return false;
+ }
+ );
+}
+
+ShopCartManager.prototype.clearRowTimers = function ($row_index) {
+ if ( this.rowTimers[$row_index] !== undefined ) {
+ console.log('cleartimers on ', $row_index, ' row -> found = delete');
+
+ clearTimeout(this.rowTimers[$row_index]);
+ delete this.rowTimers[$row_index];
+ }
+ else {
+ console.log('cleartimers on ', $row_index, ' row -> not found = skip');
+ }
+}
+
+ShopCartManager.prototype.destroyTooltips = function () {
+ while ( this.tooltips.length ) {
+ var $input = this.tooltips.shift();
+
+ $input.qtip('destroy');
+ }
+}
+
+ShopCartManager.prototype.apply = function ($params) {
+ var $me = this;
+
+ $.post(
+ this.updateUrl,
+ this.getFormData($params),
+ function ($data) {
+ $data = eval('(' + $data + ')');
+
+ $me.process($data);
+ }
+ )
+}
+
+ShopCartManager.prototype.getFormData = function ($params) {
+ var $ret = $('#shopping-cart-form').serializeArray();
+
+ if ( $params !== undefined ) {
+ while( $params.length > 0 ) {
+ $ret.push( $params.shift() );
+ }
+ }
+
+ return $ret;
+}
+
+ShopCartManager.prototype.process = function ($data) {
+ // 1. row missing ajax response -> was deleted in db
+ // 2. row missing in HTML -> was added in db
+ var $me = this,
+ $old_rows = this.getOldRows(),
+ $new_rows = this.getNewRows($data),
+ $add_rows = $new_rows.diff($old_rows),
+ $delete_rows = $old_rows.diff($new_rows);
+
+ console.log('proessing data: ', $data);
+
+ // add rows
+ $($add_rows).each(
+ function () {
+ $me.addRow( this, $data.items[this] );
+ }
+ );
+
+ // delete rows
+ $($delete_rows).each(
+ function () {
+ var $row = $me.getRowByIndex(this);
+
+ $row.next('tr.separator').remove();
+ $row.remove();
+ }
+ );
+
+ this.updateExistingRows($data);
+
+
+ this.showErrors($data);
+ this.showFooter($data);
+
+ console.log('old: ', $old_rows, '; new: ', $new_rows, '; add: ', $add_rows, '; delete: ', $delete_rows);
+}
+
+ShopCartManager.prototype.addRow = function ($row_index, $row_data) {
+ console.log('adding row: ', $row_data);
+
+ var $html = $('#product-row-mask').val(),
+ $value = '';
+
+
+ /*f: OrderItemId ; v: 101
+ f: ProductName ; v: Product With Stock Limit = 5; with backorder
+ f: BackOrderFlag ; v: 1
+ f: FlatPrice ; v: 2
+ f: Price ; v: 1.2308
+ f: Quantity ; v: 2
+ f: Virtual ; v: 0
+ f: cust_Availability ; v:*/
+
+
+ for (var $field in $row_data.fields) {
+ $value = $row_data.fields[$field];
+
+ if ( $field == 'Price' || $field == 'FlatPrice' ) {
+ $value = this.formatPrice($value);
+ }
+
+ $html = $html.replace(new RegExp('{field:' + $field + '}', 'g'), $value);
+
+ console.log('f: ', $field, '; v: ', $value);
+ }
+
+ $html = $html.replace(/{ROW_INDEX}/g, $row_index);
+// $html = $html.replace(/{DISCOUNT}/g, $row_index);
+// $html = $html.replace(/{EXTENDED_PRICE}/g, $row_index);
+
+ var $separator = $( $('#product-row-separator-mask').val() );
+
+ $('.shop-cart-row:last').after($separator);
+ $separator.after($html);
+}
+
+ShopCartManager.prototype.updateExistingRows = function ($data) {
+ for (var $row_index in $data.items) {
+ var $fields = $data.items[$row_index].fields,
+ $discount = $fields['FlatPrice'] - $fields['Price'],
+ $product_row = this.getRowByIndex($row_index),
+ $discount_container = $('.product-discount', $product_row);
+
+ // update product title
+ var $product_with_link = $('.product-with-link', $product_row);
+
+ $('a:first', $product_with_link)
+ .attr('href', $data.items[$row_index].product_url)
+ .html($fields['ProductName']);
+ $product_with_link.toggle( $fields['Virtual'] == 0 );
+
+ $('.product-without-link', $product_row)
+ .toggle( $fields['Virtual'] == 1 )
+ .html($fields['ProductName']);
+
+ $('.free-shipping', $product_row).toggle( $data.items[$row_index].free_promo_shipping );
+ $('.back-order-mark', $product_row).toggle( $fields['BackOrderFlag'] > 0 );
+
+ $('.product-availability', $product_row)
+ .toggle( $fields['cust_Availability'] != '' )
+ .html('<br/>' + $fields['cust_Availability']);
+
+ $('.product-qty.read-only', $product_row).toggle( $fields['Type'] != this.constants['PRODUCT_TYPE_TANGIBLE'] );
+ $('.product-qty:not(.read-only)', $product_row).toggle( $fields['Type'] == this.constants['PRODUCT_TYPE_TANGIBLE'] );
+
+
+ // update product specific disocunt
+ $('.item-price', $discount_container).html( this.formatPrice($fields['FlatPrice']) );
+ $('.item-discount', $discount_container).html( '- ' + this.formatPrice($discount) );
+ $discount_container.toggle( $discount > 0 );
+
+ // update product prices
+ $('.price-cell', $product_row).html( this.formatPrice($fields['Price']) );
+ $('.extended-price-cell', $product_row).html( this.formatPrice($fields['Quantity'] * $fields['Price']) );
+ }
+}
+
+ShopCartManager.prototype.showErrors = function ($data) {
+ var $error_code = 0, $error_info = [],
+ $row_index = '', $field = '',
+ $tooltip_options = '',
+ $coupon_error_code = this.getErrorByType('OrderCheckoutErrorType::COUPON', $data),
+ $gift_certificate_error_code = this.getErrorByType('OrderCheckoutErrorType::GIFT_CERTIFICATE', $data),
+ $discount_error_code = this.getErrorByType('OrderCheckoutErrorType::DISCOUNT', $data);
+
+ this.destroyTooltips();
+
+ if ( $.isArray($data.errors) ) {
+ // when no error, then it's array
+ return ;
+ }
+
+ if ( $coupon_error_code ) {
+ if ( $coupon_error_code == this.constants['OrderCheckoutError::COUPON_APPLIED'] ) {
+ var $input = $('.coupon-name', '#coupon-row');
+ }
+ else {
+ var $input = $('.coupon-code:input', '#coupon-row');
+ }
+
+ $tooltip_options = this.getCouponErrorOptions($coupon_error_code);
+
+ if ( $tooltip_options ) {
+ this.tooltips.push( $input.qtip($tooltip_options) );
+ }
+ }
+
+ if ( $gift_certificate_error_code ) {
+ if ( $gift_certificate_error_code == this.constants['OrderCheckoutError::GC_APPLIED'] ) {
+ var $input = $('.gift-certificate-discount', '#gift-certificate-row');
+ }
+ else {
+ var $input = $('.gift-certificate-code:input', '#gift-certificate-row');
+ }
+
+ $tooltip_options = this.getGiftCertificateErrorOptions($gift_certificate_error_code);
+
+ if ( $tooltip_options ) {
+ this.tooltips.push( $input.qtip($tooltip_options) );
+ }
+ }
+
+ if ( $discount_error_code ) {
+ $input = $('#sub-total');
+
+ $tooltip_options = this.getDiscountErrorOptions($discount_error_code);
+
+ if ( $tooltip_options ) {
+ this.tooltips.push( $input.qtip($tooltip_options) );
+ }
+ }
+
+ for (var $error_type in $data.errors) {
+ $tooltip_options = '';
+ $error_info = $error_type.split(':');
+ $error_code = parseInt( $data.errors[$error_type] );
+
+ if ( $error_info[0] == this.constants['OrderCheckoutErrorType::PRODUCT'] ) {
+ this.processProductError($error_info, $error_code, $data);
+ }
+
+ console.log('error_type: ', $error_type, '; error_code: ', $error_code, '; row_index: ', $row_index, '; field: ', $field);
+ }
+}
+
+ShopCartManager.prototype.showFooter = function ($data) {
+ var $discount_total = $data.order['DiscountTotal'];
+
+ // update "Total Savings"
+ $('#discount-row, #discount-row-separator').toggle( $discount_total > 0 );
+ $('.price1', '#discount-row').html( this.formatPrice($discount_total) );
+
+ // update Coupon Info
+ if ( $data.order['CouponId'] == 0 ) {
+ $('.coupon-code', '#coupon-row').val('');
+ }
+
+ $('.used', '#coupon-row').toggle( $data.order['CouponId'] > 0 );
+ $('.not-used', '#coupon-row').toggle( $data.order['CouponId'] == 0 );
+ $('.coupon-name', '#coupon-row').html( $data.order['CouponName'] );
+
+ // update Gift Certificate Info
+ if ( $data.order['GiftCertificateId'] == 0 ) {
+ $('.gift-certificate-code', '#gift-certificate-row').val('');
+ }
+
+ $('.used', '#gift-certificate-row').toggle( $data.order['GiftCertificateId'] > 0 );
+ $('.not-used', '#gift-certificate-row').toggle( $data.order['GiftCertificateId'] == 0 );
+ $('.gift-certificate-discount', '#gift-certificate-row').html( this.formatPrice($data.order['GiftCertificateDiscount']) );
+
+ // update "subtotal"
+ $('#sub-total').html( this.formatPrice($data.order['SubTotal']) );
+}
+
+ShopCartManager.prototype.processProductError = function ($error_info, $error_code, $data) {
+ var $error_type = $error_info.shift(),
+ $field = $error_info.pop(),
+ $row_index = $error_info.join(':');
+
+ if ( this.getRowByIndex($row_index).length == 0 ) {
+ // row was deleted
+ return ;
+ }
+
+ if ( $field == 'Quantity' ) {
+ var $input = $('.product-qty:input', this.getRowByIndex($row_index)),
+ $allow_qty_replace = [
+ this.constants['OrderCheckoutError::FIELD_UPDATE_SUCCESS'],
+ this.constants['OrderCheckoutError::QTY_CHANGED_TO_MINIMAL']
+ ];
+
+ if ( in_array($error_code, $allow_qty_replace) && $input.val() != $data.items[$row_index]['fields']['Quantity'] ) {
+ // qty changed during ord:OnRecalculateItems
+ $input.val( $data.items[$row_index]['fields']['Quantity'] );
+ }
+
+ $tooltip_options = this.getQtyErrorOptions($error_code);
+
+ if ( $tooltip_options ) {
+ this.tooltips.push( $input.qtip($tooltip_options) );
+ }
+ }
+}
+
+ShopCartManager.prototype.getErrorByType = function ($contant_name, $data) {
+ var $error_type = this.constants[$contant_name];
+
+ return $data.errors[$error_type] !== undefined ? $data.errors[$error_type] : false;
+}
+
+ShopCartManager.prototype.getRowByIndex = function ($row_index) {
+ return $("tr.shop-cart-row[row_index='" + $row_index + "']", '#shop-cart-table');
+}
+
+ShopCartManager.prototype.getOldRows = function () {
+ var $ret = [];
+
+ $('tr.shop-cart-row', '#shop-cart-table').each(
+ function () {
+ $ret.push( $(this).attr('row_index') );
+ }
+ );
+
+ return $ret;
+}
+
+ShopCartManager.prototype.getNewRows = function ($data) {
+ var $ret = [];
+
+ if ( $.isArray($data.items) ) {
+ return $data.items;
+ }
+
+ for (var $row_index in $data.items) {
+ $ret.push( $row_index );
+ }
+
+ return $ret;
+}
+
+ShopCartManager.prototype.formatPrice = function ($price) {
+ // TODO: format currency
+ return this.currencyMask.replace('%s', $price.toFixed(2));
+}
+
+ShopCartManager.prototype.getQtyErrorOptions = function ($error_code) {
+ var $ret = false;
+
+ switch ($error_code) {
+ case this.constants['OrderCheckoutError::FIELD_UPDATE_SUCCESS']:
+ $ret = this.getTooltipOptions('FIELD_UPDATE_SUCCESS', 'ui-tooltip-green');
+ break;
+
+ case this.constants['OrderCheckoutError::FIELD_UPDATE_ERROR']:
+ $ret = this.getTooltipOptions('FIELD_UPDATE_ERROR', 'ui-tooltip-red');
+ break;
+
+ case this.constants['OrderCheckoutError::QTY_UNAVAILABLE']:
+ $ret = this.getTooltipOptions('QTY_UNAVAILABLE', 'ui-tooltip-red');
+ break;
+
+ case this.constants['OrderCheckoutError::QTY_OUT_OF_STOCK']:
+ $ret = this.getTooltipOptions('QTY_OUT_OF_STOCK', 'ui-tooltip-red');
+ break;
+
+ case this.constants['OrderCheckoutError::QTY_CHANGED_TO_MINIMAL']:
+ $ret = this.getTooltipOptions('QTY_CHANGED_TO_MINIMAL', 'ui-tooltip-green');
+ break;
+ }
+
+ return $ret;
+}
+
+ShopCartManager.prototype.getCouponErrorOptions = function ($error_code) {
+ var $ret = false;
+
+ switch ($error_code) {
+ case this.constants['OrderCheckoutError::COUPON_APPLIED']: // for label
+ $ret = this.getTooltipOptions('COUPON_APPLIED', 'ui-tooltip-green');
+ break;
+
+ // all next error for input
+ case this.constants['OrderCheckoutError::COUPON_REMOVED']:
+ $ret = this.getTooltipOptions('COUPON_REMOVED', 'ui-tooltip-green');
+ break;
+
+ case this.constants['OrderCheckoutError::COUPON_REMOVED_AUTOMATICALLY']:
+ $ret = this.getTooltipOptions('COUPON_REMOVED_AUTOMATICALLY', 'ui-tooltip-green');
+ break;
+
+ case this.constants['OrderCheckoutError::COUPON_CODE_INVALID']:
+ $ret = this.getTooltipOptions('COUPON_CODE_INVALID', 'ui-tooltip-red');
+ break;
+
+ case this.constants['OrderCheckoutError::COUPON_CODE_EXPIRED']:
+ $ret = this.getTooltipOptions('COUPON_CODE_EXPIRED', 'ui-tooltip-red');
+ break;
+ }
+
+ return $ret;
+}
+
+ShopCartManager.prototype.getGiftCertificateErrorOptions = function ($error_code) {
+ var $ret = false;
+
+ switch ($error_code) {
+ case this.constants['OrderCheckoutError::GC_APPLIED']: // for label
+ $ret = this.getTooltipOptions('GC_APPLIED', 'ui-tooltip-green');
+ break;
+
+ // all next error for input
+ case this.constants['OrderCheckoutError::GC_REMOVED']:
+ $ret = this.getTooltipOptions('GC_REMOVED', 'ui-tooltip-green');
+ break;
+
+ case this.constants['OrderCheckoutError::GC_REMOVED_AUTOMATICALLY']:
+ $ret = this.getTooltipOptions('GC_REMOVED_AUTOMATICALLY', 'ui-tooltip-green');
+ break;
+
+ case this.constants['OrderCheckoutError::GC_CODE_INVALID']:
+ $ret = this.getTooltipOptions('GC_CODE_INVALID', 'ui-tooltip-red');
+ break;
+
+ case this.constants['OrderCheckoutError::GC_CODE_EXPIRED']:
+ $ret = this.getTooltipOptions('GC_CODE_EXPIRED', 'ui-tooltip-red');
+ break;
+ }
+
+ return $ret;
+}
+
+ShopCartManager.prototype.getDiscountErrorOptions = function ($error_code) {
+ var $ret = false;
+
+ switch ($error_code) {
+ case this.constants['OrderCheckoutError::DISCOUNT_APPLIED']:
+ $ret = this.getTooltipOptions('DISCOUNT_APPLIED', 'ui-tooltip-green');
+ $ret.position.my = 'top right';
+ break;
+
+ case this.constants['OrderCheckoutError::DISCOUNT_REMOVED']:
+ $ret = this.getTooltipOptions('DISCOUNT_REMOVED', 'ui-tooltip-green');
+ $ret.position.my = 'top right';
+ break;
+ }
+
+ return $ret;
+}
+
+ShopCartManager.prototype.getTooltipOptions = function ($text, $css_classes) {
+ return {
+ content: {text: $text},
+ position: {my: 'top left', at: 'bottom center'},
+ show: {when: false, ready: true},
+ hide: {event: 'focus', inactive: 2500},
+ style: {classes: $css_classes}
+ };
+}
Property changes on: in-commerce\inc\cart_manager.js
___________________________________________________________________
Added: svn:eol-style
+ LF
Index: platform/elements/html_head.elm.tpl
===================================================================
--- platform/elements/html_head.elm.tpl (revision 14590)
+++ platform/elements/html_head.elm.tpl (working copy)
@@ -13,9 +13,9 @@
<inp2:m_Compress files="platform/inc/jquery/thickbox/thickbox.css" to="all_css"/>
</inp2:m_ifnot>
-<inp2:m_Compress files="platform/inc/styles.css" to="all_css"/>
+<inp2:m_Compress files="platform/inc/jquery/qtip/jquery.qtip.css|platform/inc/styles.css" to="all_css"/>
-<inp2:m_Compress files="platform/inc/script.js|platform/inc/ajax.js|platform/inc/calendar.js" to="all_js"/>
+<inp2:m_Compress files="platform/inc/script.js|platform/inc/ajax.js|platform/inc/calendar.js|platform/inc/jquery/qtip/jquery.qtip.min.js" to="all_js"/>
<script type="text/javascript">var inportalBase = '<inp2:m_TemplatesBase module="In-Portal"/>';</script>
<script type="text/javascript" src="<inp2:m_TemplatesBase module='In-Portal'/>inc/jquery/jquery.pack.js"></script>
Index: platform/inc/jquery/qtip/jquery.qtip.css
===================================================================
--- platform/inc/jquery/qtip/jquery.qtip.css (revision 0)
+++ platform/inc/jquery/qtip/jquery.qtip.css (revision 0)
@@ -0,0 +1,539 @@
+/*
+* qTip2 - Pretty powerful tooltips
+* http://craigsworks.com/projects/qtip2/
+*
+* Version: nightly
+* Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com
+*
+* Dual licensed under MIT or GPLv2 licenses
+* http://en.wikipedia.org/wiki/MIT_License
+* http://en.wikipedia.org/wiki/GNU_General_Public_License
+*
+* Date: Sun Aug 14 05:10:00 PDT 2011
+*/
+
+/* Core qTip styles */
+.ui-tooltip, .qtip{
+ position: absolute;
+ left: -28000px;
+ top: -28000px;
+ display: none;
+
+ max-width: 280px;
+ min-width: 50px;
+
+ font-size: 10.5px;
+ line-height: 12px;
+
+ z-index: 15000;
+}
+
+ /* Fluid class for determining actual width in IE */
+ .ui-tooltip-fluid{
+ display: block;
+ visibility: hidden;
+ position: static !important;
+ float: left !important;
+ }
+
+ .ui-tooltip-content{
+ position: relative;
+ padding: 5px 9px;
+ overflow: hidden;
+
+ border-width: 1px;
+ border-style: solid;
+
+ text-align: left;
+ word-wrap: break-word;
+ overflow: hidden;
+ }
+
+ .ui-tooltip-titlebar{
+ position: relative;
+ min-height: 14px;
+ padding: 5px 35px 5px 10px;
+ overflow: hidden;
+
+ border-width: 1px 1px 0;
+ border-style: solid;
+
+ font-weight: bold;
+ }
+
+ .ui-tooltip-titlebar + .ui-tooltip-content{ border-top-width: 0px !important; }
+
+ /*! Default close button class */
+ .ui-tooltip-titlebar .ui-state-default{
+ position: absolute;
+ right: 4px;
+ top: 50%;
+ margin-top: -9px;
+
+ cursor: pointer;
+ outline: medium none;
+
+ border-width: 1px;
+ border-style: solid;
+ }
+
+ * html .ui-tooltip-titlebar .ui-state-default{ top: 16px; } /* IE fix */
+
+ .ui-tooltip-titlebar .ui-icon,
+ .ui-tooltip-icon .ui-icon{
+ display: block;
+ text-indent: -1000em;
+ }
+
+ .ui-tooltip-icon, .ui-tooltip-icon .ui-icon{
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ }
+
+ .ui-tooltip-icon .ui-icon{
+ width: 18px;
+ height: 14px;
+
+ text-align: center;
+ text-indent: 0;
+ font: normal bold 10px/13px Tahoma,sans-serif;
+
+ color: inherit;
+ background: transparent none no-repeat -100em -100em;
+ }
+
+
+/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
+.ui-tooltip-focus{
+
+}
+
+/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
+.ui-tooltip-hover{
+
+}
+
+
+/*! Default tooltip style */
+.ui-tooltip-default .ui-tooltip-titlebar,
+.ui-tooltip-default .ui-tooltip-content{
+ border-color: #F1D031;
+ background-color: #FFFFA3;
+ color: #555;
+}
+
+ .ui-tooltip-default .ui-tooltip-titlebar{
+ background-color: #FFEF93;
+ }
+
+ .ui-tooltip-default .ui-tooltip-icon{
+ border-color: #CCC;
+ background: #F1F1F1;
+ color: #777;
+ }
+
+ .ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #AAA;
+ color: #111;
+ }
+
+/* Tips plugin */
+.ui-tooltip .ui-tooltip-tip{
+ margin: 0 auto;
+ overflow: hidden;
+
+ background: transparent !important;
+ border: 0px dashed transparent !important;
+ z-index: 10;
+}
+
+ .ui-tooltip .ui-tooltip-tip,
+ .ui-tooltip .ui-tooltip-tip *{
+ position: absolute;
+
+ line-height: 0.1px !important;
+ font-size: 0.1px !important;
+ color: #123456;
+
+ background: transparent;
+ border: 0px dashed transparent;
+ }
+
+ .ui-tooltip .ui-tooltip-tip canvas{ top: 0; left: 0; }
+
+
+/*! Light tooltip style */
+.ui-tooltip-light .ui-tooltip-titlebar,
+.ui-tooltip-light .ui-tooltip-content{
+ border-color: #E2E2E2;
+ color: #454545;
+}
+
+ .ui-tooltip-light .ui-tooltip-content{
+ background-color: white;
+ }
+
+ .ui-tooltip-light .ui-tooltip-titlebar{
+ background-color: #f1f1f1;
+ }
+
+
+/*! Dark tooltip style */
+.ui-tooltip-dark .ui-tooltip-titlebar,
+.ui-tooltip-dark .ui-tooltip-content{
+ border-color: #303030;
+ color: #f3f3f3;
+}
+
+ .ui-tooltip-dark .ui-tooltip-content{
+ background-color: #505050;
+ }
+
+ .ui-tooltip-dark .ui-tooltip-titlebar{
+ background-color: #404040;
+ }
+
+ .ui-tooltip-dark .ui-tooltip-icon{
+ border-color: #444;
+ }
+
+ .ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #303030;
+ }
+
+
+/*! Cream tooltip style */
+.ui-tooltip-cream .ui-tooltip-titlebar,
+.ui-tooltip-cream .ui-tooltip-content{
+ border-color: #F9E98E;
+ color: #A27D35;
+}
+
+ .ui-tooltip-cream .ui-tooltip-content{
+ background-color: #FBF7AA;
+ }
+
+ .ui-tooltip-cream .ui-tooltip-titlebar{
+ background-color: #F0DE7D;
+ }
+
+ .ui-tooltip-cream .ui-state-default .ui-tooltip-icon{
+ background-position: -82px 0;
+ }
+
+
+/*! Red tooltip style */
+.ui-tooltip-red .ui-tooltip-titlebar,
+.ui-tooltip-red .ui-tooltip-content{
+ border-color: #D95252;
+ color: #912323;
+}
+
+ .ui-tooltip-red .ui-tooltip-content{
+ background-color: #F78B83;
+ }
+
+ .ui-tooltip-red .ui-tooltip-titlebar{
+ background-color: #F06D65;
+ }
+
+ .ui-tooltip-red .ui-state-default .ui-tooltip-icon{
+ background-position: -102px 0;
+ }
+
+ .ui-tooltip-red .ui-tooltip-icon{
+ border-color: #D95252;
+ }
+
+ .ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #D95252;
+ }
+
+
+/*! Green tooltip style */
+.ui-tooltip-green .ui-tooltip-titlebar,
+.ui-tooltip-green .ui-tooltip-content{
+ border-color: #90D93F;
+ color: #3F6219;
+}
+
+ .ui-tooltip-green .ui-tooltip-content{
+ background-color: #CAED9E;
+ }
+
+ .ui-tooltip-green .ui-tooltip-titlebar{
+ background-color: #B0DE78;
+ }
+
+ .ui-tooltip-green .ui-state-default .ui-tooltip-icon{
+ background-position: -42px 0;
+ }
+
+
+/*! Blue tooltip style */
+.ui-tooltip-blue .ui-tooltip-titlebar,
+.ui-tooltip-blue .ui-tooltip-content{
+ border-color: #ADD9ED;
+ color: #5E99BD;
+}
+
+ .ui-tooltip-blue .ui-tooltip-content{
+ background-color: #E5F6FE;
+ }
+
+ .ui-tooltip-blue .ui-tooltip-titlebar{
+ background-color: #D0E9F5;
+ }
+
+ .ui-tooltip-blue .ui-state-default .ui-tooltip-icon{
+ background-position: -2px 0;
+ }
+
+/*! Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE6+, Safari 2+ */
+.ui-tooltip-shadow{
+ -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
+ box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
+}
+
+ .ui-tooltip-shadow .ui-tooltip-titlebar,
+ .ui-tooltip-shadow .ui-tooltip-content{
+ filter: progid:DXImageTransform.Microsoft.Shadow(Color='gray', Direction=135, Strength=3);
+ -ms-filter:"progid:DXImageTransform.Microsoft.Shadow(Color='gray', Direction=135, Strength=3)";
+
+ _margin-bottom: -3px; /* IE6 */
+ .margin-bottom: -3px; /* IE7 */
+ }
+
+
+/*! Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
+.ui-tooltip-rounded,
+.ui-tooltip-rounded .ui-tooltip-content,
+.ui-tooltip-tipsy,
+.ui-tooltip-tipsy .ui-tooltip-content,
+.ui-tooltip-youtube,
+.ui-tooltip-youtube .ui-tooltip-content{
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.ui-tooltip-rounded .ui-tooltip-titlebar,
+.ui-tooltip-tipsy .ui-tooltip-titlebar,
+.ui-tooltip-youtube .ui-tooltip-titlebar{
+ -moz-border-radius: 5px 5px 0 0;
+ -webkit-border-radius: 5px 5px 0 0;
+ border-radius: 5px 5px 0 0;
+}
+
+.ui-tooltip-rounded .ui-tooltip-titlebar + .ui-tooltip-content,
+.ui-tooltip-tipsy .ui-tooltip-titlebar + .ui-tooltip-content,
+.ui-tooltip-youtube .ui-tooltip-titlebar + .ui-tooltip-content{
+ -moz-border-radius: 0 0 5px 5px;
+ -webkit-border-radius: 0 0 5px 5px;
+ border-radius: 0 0 5px 5px;
+}
+
+
+/*! Youtube tooltip style */
+.ui-tooltip-youtube{
+ -webkit-box-shadow: 0 0 3px #333;
+ -moz-box-shadow: 0 0 3px #333;
+ box-shadow: 0 0 3px #333;
+}
+
+ .ui-tooltip-youtube .ui-tooltip-titlebar,
+ .ui-tooltip-youtube .ui-tooltip-content{
+ _margin-bottom: 0; /* IE6 */
+ .margin-bottom: 0; /* IE7 */
+
+ background: transparent;
+ background: rgba(0, 0, 0, 0.85);
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";
+
+ color: white;
+ border-color: #CCCCCC;
+ }
+
+ .ui-tooltip-youtube .ui-tooltip-icon{
+ border-color: #222;
+ }
+
+ .ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #303030;
+ }
+
+
+/* jQuery TOOLS Tooltip style */
+.ui-tooltip-jtools{
+ background: #232323;
+ background: rgba(0, 0, 0, 0.7);
+ background-image: -moz-linear-gradient(top, #717171, #232323);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));
+
+ border: 2px solid #ddd;
+ border: 2px solid rgba(241,241,241,1);
+
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+
+ -webkit-box-shadow: 0 0 12px #333;
+ -moz-box-shadow: 0 0 12px #333;
+ box-shadow: 0 0 12px #333;
+}
+
+ /* IE Specific */
+ .ui-tooltip-jtools .ui-tooltip-titlebar{
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";
+ }
+ .ui-tooltip-jtools .ui-tooltip-content{
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";
+ }
+
+ .ui-tooltip-jtools .ui-tooltip-titlebar,
+ .ui-tooltip-jtools .ui-tooltip-content{
+ background: transparent;
+ color: white;
+ border: 0 dashed transparent;
+ }
+
+ .ui-tooltip-jtools .ui-tooltip-icon{
+ border-color: #555;
+ }
+
+ .ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #333;
+ }
+
+
+/* Cluetip style */
+.ui-tooltip-cluetip{
+ -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
+ -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
+ box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
+}
+
+ .ui-tooltip-cluetip .ui-tooltip-titlebar{
+ background-color: #87876A;
+ color: white;
+ border: 0 dashed transparent;
+ }
+
+ .ui-tooltip-cluetip .ui-tooltip-content{
+ background-color: #D9D9C2;
+ color: #111;
+ border: 0 dashed transparent;
+ }
+
+ .ui-tooltip-cluetip .ui-tooltip-icon{
+ border-color: #808064;
+ }
+
+ .ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #696952;
+ color: #696952;
+ }
+
+
+/* Tipsy style */
+.ui-tooltip-tipsy{
+ border: 0;
+}
+
+ .ui-tooltip-tipsy .ui-tooltip-titlebar,
+ .ui-tooltip-tipsy .ui-tooltip-content{
+ _margin-bottom: 0; /* IE6 */
+ .margin-bottom: 0; /* IE7 */
+
+ background: transparent;
+ background: rgba(0, 0, 0, .87);
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";
+
+ color: white;
+ border: 0px transparent;
+
+ font-size: 11px;
+ font-family: 'Lucida Grande', sans-serif;
+ font-weight: bold;
+ line-height: 16px;
+ text-shadow: 0 1px black;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-titlebar{
+ padding: 6px 35px 0 10;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-content{
+ padding: 6px 10;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-icon{
+ border-color: #222;
+ text-shadow: none;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #303030;
+ }
+
+
+/* Tipped style */
+.ui-tooltip-tipped{
+
+}
+
+ .ui-tooltip-tipped .ui-tooltip-titlebar,
+ .ui-tooltip-tipped .ui-tooltip-content{
+ border: 3px solid #959FA9;
+
+ filter: none; -ms-filter: none;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-titlebar{
+ background: #3A79B8;
+ background-image: -moz-linear-gradient(top, #3A79B8, #2E629D);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D));
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";
+
+ color: white;
+ font-weight: normal;
+ font-family: serif;
+
+ border-bottom-width: 0;
+ -moz-border-radius: 3px 3px 0 0;
+ -webkit-border-radius: 3px 3px 0 0;
+ border-radius: 3px 3px 0 0;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-content{
+ background-color: #F9F9F9;
+ color: #454545;
+
+ -moz-border-radius: 0 0 3px 3px;
+ -webkit-border-radius: 0 0 3px 3px;
+ border-radius: 0 0 3px 3px;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-icon{
+ border: 2px solid #285589;
+ background: #285589;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-icon .ui-icon{
+ background-color: #FBFBFB;
+ color: #555;
+ }
+
+/* IE9 fix - removes all filters */
+.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,
+.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{
+ filter: none;
+ -ms-filter: none;
+}
Property changes on: platform\inc\jquery\qtip\jquery.qtip.css
___________________________________________________________________
Added: svn:eol-style
+ LF
Index: platform/inc/jquery/qtip/jquery.qtip.js
===================================================================
--- platform/inc/jquery/qtip/jquery.qtip.js (revision 0)
+++ platform/inc/jquery/qtip/jquery.qtip.js (revision 0)
@@ -0,0 +1,2712 @@
+/*
+* qTip2 - Pretty powerful tooltips
+* http://craigsworks.com/projects/qtip2/
+*
+* Version: nightly
+* Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com
+*
+* Dual licensed under MIT or GPLv2 licenses
+* http://en.wikipedia.org/wiki/MIT_License
+* http://en.wikipedia.org/wiki/GNU_General_Public_License
+*
+* Date: Sun Aug 14 05:10:00 PDT 2011
+*/
+
+/*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true */
+/*global window: false, jQuery: false, console: false */
+
+
+(function($, window, undefined) {
+
+ "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
+
+ // Munge the primitives - Paul Irish tip
+ var TRUE = true,
+ FALSE = false,
+ NULL = null,
+
+ // Shortcut vars
+ QTIP, PLUGINS, MOUSE,
+ usedIDs = {},
+ uitooltip = 'ui-tooltip',
+ widget = 'ui-widget',
+ disabled = 'ui-state-disabled',
+ selector = 'div.qtip.'+uitooltip,
+ defaultClass = uitooltip + '-default',
+ focusClass = uitooltip + '-focus',
+ hoverClass = uitooltip + '-hover',
+ fluidClass = uitooltip + '-fluid',
+ hideOffset = '-31000px',
+ replaceSuffix = '_replacedByqTip',
+ oldtitle = 'oldtitle',
+ trackingBound;
+
+ /* Thanks to Paul Irish for this one: http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/ */
+ function log() {
+ log.history = log.history || [];
+ log.history.push(arguments);
+
+ // Make sure console is present
+ if('object' === typeof console) {
+
+ // Setup console and arguments
+ var c = console[ console.warn ? 'warn' : 'log' ],
+ args = Array.prototype.slice.call(arguments), a;
+
+ // Add qTip2 marker to first argument if it's a string
+ if(typeof arguments[0] === 'string') { args[0] = 'qTip2: ' + args[0]; }
+
+ // Apply console.warn or .log if not supported
+ a = c.apply ? c.apply(console, args) : c(args);
+ }
+ }
+
+// Option object sanitizer
+function sanitizeOptions(opts)
+{
+ var content;
+
+ if(!opts || 'object' !== typeof opts) { return FALSE; }
+
+ if('object' !== typeof opts.metadata) {
+ opts.metadata = {
+ type: opts.metadata
+ };
+ }
+
+ if('content' in opts) {
+ if('object' !== typeof opts.content || opts.content.jquery) {
+ opts.content = {
+ text: opts.content
+ };
+ }
+
+ content = opts.content.text || FALSE;
+ if(!$.isFunction(content) && ((!content && !content.attr) || content.length < 1 || ('object' === typeof content && !content.jquery))) {
+ opts.content.text = FALSE;
+ }
+
+ if('title' in opts.content) {
+ if('object' !== typeof opts.content.title) {
+ opts.content.title = {
+ text: opts.content.title
+ };
+ }
+
+ content = opts.content.title.text || FALSE;
+ if(!$.isFunction(content) && ((!content && !content.attr) || content.length < 1 || ('object' === typeof content && !content.jquery))) {
+ opts.content.title.text = FALSE;
+ }
+ }
+ }
+
+ if('position' in opts) {
+ if('object' !== typeof opts.position) {
+ opts.position = {
+ my: opts.position,
+ at: opts.position
+ };
+ }
+ }
+
+ if('show' in opts) {
+ if('object' !== typeof opts.show) {
+ if(opts.show.jquery) {
+ opts.show = { target: opts.show };
+ }
+ else {
+ opts.show = { event: opts.show };
+ }
+ }
+ }
+
+ if('hide' in opts) {
+ if('object' !== typeof opts.hide) {
+ if(opts.hide.jquery) {
+ opts.hide = { target: opts.hide };
+ }
+ else {
+ opts.hide = { event: opts.hide };
+ }
+ }
+ }
+
+ if('style' in opts) {
+ if('object' !== typeof opts.style) {
+ opts.style = {
+ classes: opts.style
+ };
+ }
+ }
+
+ // Sanitize plugin options
+ $.each(PLUGINS, function() {
+ if(this.sanitize) { this.sanitize(opts); }
+ });
+
+ return opts;
+}
+
+/*
+* Core plugin implementation
+*/
+function QTip(target, options, id, attr)
+{
+ // Declare this reference
+ var self = this,
+ docBody = document.body,
+ tooltipID = uitooltip + '-' + id,
+ isPositioning = 0,
+ isDrawing = 0,
+ tooltip = $(),
+ namespace = '.qtip-' + id,
+ elements, cache;
+
+ // Setup class attributes
+ self.id = id;
+ self.rendered = FALSE;
+ self.elements = elements = { target: target };
+ self.timers = { img: {} };
+ self.options = options;
+ self.checks = {};
+ self.plugins = {};
+ self.cache = cache = {
+ event: {},
+ target: $(),
+ disabled: FALSE,
+ attr: attr
+ };
+
+ /*
+ * Private core functions
+ */
+ function convertNotation(notation)
+ {
+ var i = 0, obj, option = options,
+
+ // Split notation into array
+ levels = notation.split('.');
+
+ // Loop through
+ while( option = option[ levels[i++] ] ) {
+ if(i < levels.length) { obj = option; }
+ }
+
+ return [obj || options, levels.pop()];
+ }
+
+ function setWidget() {
+ var on = options.style.widget;
+
+ tooltip.toggleClass(widget, on).toggleClass(defaultClass, !on);
+ elements.content.toggleClass(widget+'-content', on);
+
+ if(elements.titlebar){
+ elements.titlebar.toggleClass(widget+'-header', on);
+ }
+ if(elements.button){
+ elements.button.toggleClass(uitooltip+'-icon', !on);
+ }
+ }
+
+ function removeTitle(reposition)
+ {
+ if(elements.title) {
+ elements.titlebar.remove();
+ elements.titlebar = elements.title = elements.button = NULL;
+
+ // Reposition if enabled
+ if(reposition !== FALSE) { self.reposition(); }
+ }
+ }
+
+ function createButton()
+ {
+ var button = options.content.title.button,
+ isString = typeof button === 'string',
+ close = isString ? button : 'Close tooltip';
+
+ if(elements.button) { elements.button.remove(); }
+
+ // Use custom button if one was supplied by user, else use default
+ if(button.jquery) {
+ elements.button = button;
+ }
+ else {
+ elements.button = $('<a />', {
+ 'class': 'ui-state-default ' + (options.style.widget ? '' : uitooltip+'-icon'),
+ 'title': close,
+ 'aria-label': close
+ })
+ .prepend(
+ $('<span />', {
+ 'class': 'ui-icon ui-icon-close',
+ 'html': '×'
+ })
+ );
+ }
+
+ // Create button and setup attributes
+ elements.button.appendTo(elements.titlebar)
+ .attr('role', 'button')
+ .hover(function(event){ $(this).toggleClass('ui-state-hover', event.type === 'mouseenter'); })
+ .click(function(event) {
+ if(!tooltip.hasClass(disabled)) { self.hide(event); }
+ return FALSE;
+ })
+ .bind('mousedown keydown mouseup keyup mouseout', function(event) {
+ $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down');
+ });
+
+ // Redraw the tooltip when we're done
+ self.redraw();
+ }
+
+ function createTitle()
+ {
+ var id = tooltipID+'-title';
+
+ // Destroy previous title element, if present
+ if(elements.titlebar) { removeTitle(); }
+
+ // Create title bar and title elements
+ elements.titlebar = $('<div />', {
+ 'class': uitooltip + '-titlebar ' + (options.style.widget ? 'ui-widget-header' : '')
+ })
+ .append(
+ elements.title = $('<div />', {
+ 'id': id,
+ 'class': uitooltip + '-title',
+ 'aria-atomic': TRUE
+ })
+ )
+ .insertBefore(elements.content);
+
+ // Create button if enabled
+ if(options.content.title.button) { createButton(); }
+
+ // Redraw the tooltip dimensions if it's rendered
+ else if(self.rendered){ self.redraw(); }
+ }
+
+ function updateButton(button)
+ {
+ var elem = elements.button,
+ title = elements.title;
+
+ // Make sure tooltip is rendered and if not, return
+ if(!self.rendered) { return FALSE; }
+
+ if(!button) {
+ elem.remove();
+ }
+ else {
+ if(!title) {
+ createTitle();
+ }
+ createButton();
+ }
+ }
+
+ function updateTitle(content, reposition)
+ {
+ var elem = elements.title;
+
+ // Make sure tooltip is rendered and if not, return
+ if(!self.rendered || !content) { return FALSE; }
+
+ // Use function to parse content
+ if($.isFunction(content)) {
+ content = content.call(target, cache.event, self);
+ }
+
+ // Remove title if callback returns false
+ if(content === FALSE) { return removeTitle(FALSE); }
+
+ // Append new content if its a DOM array and show it if hidden
+ else if(content.jquery && content.length > 0) {
+ elem.empty().append(content.css({ display: 'block' }));
+ }
+
+ // Content is a regular string, insert the new content
+ else { elem.html(content); }
+
+ // Redraw and reposition
+ self.redraw();
+ if(reposition !== FALSE && self.rendered && tooltip.is(':visible')) {
+ self.reposition(cache.event);
+ }
+ }
+
+ function updateContent(content, reposition)
+ {
+ var elem = elements.content;
+
+ // Make sure tooltip is rendered and content is defined. If not return
+ if(!self.rendered || !content) { return FALSE; }
+
+ // Use function to parse content
+ if($.isFunction(content)) {
+ content = content.call(target, cache.event, self) || '';
+ }
+
+ // Append new content if its a DOM array and show it if hidden
+ if(content.jquery && content.length > 0) {
+ elem.empty().append(content.css({ display: 'block' }));
+ }
+
+ // Content is a regular string, insert the new content
+ else { elem.html(content); }
+
+ // Image detection
+ function detectImages(next) {
+ var images, srcs = {};
+
+ function imageLoad(image) {
+ // Clear src from object and any timers and events associated with the image
+ if(image) {
+ delete srcs[image.src];
+ clearTimeout(self.timers.img[image.src]);
+ $(image).unbind(namespace);
+ }
+
+ // If queue is empty after image removal, update tooltip and continue the queue
+ if($.isEmptyObject(srcs)) {
+ self.redraw();
+ if(reposition !== FALSE) {
+ self.reposition(cache.event);
+ }
+
+ next();
+ }
+ }
+
+ // Find all content images without dimensions, and if no images were found, continue
+ if((images = elem.find('img:not([height]):not([width])')).length === 0) { return imageLoad(); }
+
+ // Apply timer to each image to poll for dimensions
+ images.each(function(i, elem) {
+ // Skip if the src is already present
+ if(srcs[elem.src] !== undefined) { return; }
+
+ (function timer(){
+ // When the dimensions are found, remove the image from the queue
+ if(elem.height || elem.width) { return imageLoad(elem); }
+
+ // Restart timer
+ self.timers.img[elem.src] = setTimeout(timer, 700);
+ }());
+
+ // Also apply regular load/error event handlers
+ $(elem).bind('error'+namespace+' load'+namespace, function(){ imageLoad(this); });
+
+ // Store the src and element in our object
+ srcs[elem.src] = elem;
+ });
+ }
+
+ /*
+ * If we're still rendering... insert into 'fx' queue our image dimension
+ * checker which will halt the showing of the tooltip until image dimensions
+ * can be detected properly.
+ */
+ if(self.rendered < 0) { tooltip.queue('fx', detectImages); }
+
+ // We're fully rendered, so reset isDrawing flag and proceed without queue delay
+ else { isDrawing = 0; detectImages($.noop); }
+
+ return self;
+ }
+
+ function assignEvents()
+ {
+ var posOptions = options.position,
+ targets = {
+ show: options.show.target,
+ hide: options.hide.target,
+ viewport: $(posOptions.viewport),
+ document: $(document),
+ window: $(window)
+ },
+ events = {
+ show: $.trim('' + options.show.event).split(' '),
+ hide: $.trim('' + options.hide.event).split(' ')
+ },
+ IE6 = $.browser.msie && parseInt($.browser.version, 10) === 6;
+
+ // Define show event method
+ function showMethod(event)
+ {
+ if(tooltip.hasClass(disabled)) { return FALSE; }
+
+ // If set, hide tooltip when inactive for delay period
+ targets.show.trigger('qtip-'+id+'-inactive');
+
+ // Clear hide timers
+ clearTimeout(self.timers.show);
+ clearTimeout(self.timers.hide);
+
+ // Start show timer
+ var callback = function(){ self.toggle(TRUE, event); };
+ if(options.show.delay > 0) {
+ self.timers.show = setTimeout(callback, options.show.delay);
+ }
+ else{ callback(); }
+ }
+
+ // Define hide method
+ function hideMethod(event)
+ {
+ if(tooltip.hasClass(disabled) || isPositioning || isDrawing) { return FALSE; }
+
+ // Check if new target was actually the tooltip element
+ var relatedTarget = $(event.relatedTarget || event.target),
+ ontoTooltip = relatedTarget.closest(selector)[0] === tooltip[0],
+ ontoTarget = relatedTarget[0] === targets.show[0];
+
+ // Clear timers and stop animation queue
+ clearTimeout(self.timers.show);
+ clearTimeout(self.timers.hide);
+
+ // Prevent hiding if tooltip is fixed and event target is the tooltip. Or if mouse positioning is enabled and cursor momentarily overlaps
+ if((posOptions.target === 'mouse' && ontoTooltip) || (options.hide.fixed && ((/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)))) {
+ event.preventDefault(); event.stopImmediatePropagation(); return;
+ }
+
+ // If tooltip has displayed, start hide timer
+ if(options.hide.delay > 0) {
+ self.timers.hide = setTimeout(function(){ self.hide(event); }, options.hide.delay);
+ }
+ else{ self.hide(event); }
+ }
+
+ // Define inactive method
+ function inactiveMethod(event)
+ {
+ if(tooltip.hasClass(disabled)) { return FALSE; }
+
+ // Clear timer
+ clearTimeout(self.timers.inactive);
+ self.timers.inactive = setTimeout(function(){ self.hide(event); }, options.hide.inactive);
+ }
+
+ function repositionMethod(event) {
+ if(tooltip.is(':visible')) { self.reposition(event); }
+ }
+
+ // On mouseenter/mouseleave...
+ tooltip.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) {
+ var state = event.type === 'mouseenter';
+
+ // Focus the tooltip on mouseenter (z-index stacking)
+ if(state) { self.focus(event); }
+
+ // Add hover class
+ tooltip.toggleClass(hoverClass, state);
+ });
+
+ // Enable hide.fixed
+ if(options.hide.fixed) {
+ // Add tooltip as a hide target
+ targets.hide = targets.hide.add(tooltip);
+
+ // Clear hide timer on tooltip hover to prevent it from closing
+ tooltip.bind('mouseover'+namespace, function() {
+ if(!tooltip.hasClass(disabled)) { clearTimeout(self.timers.hide); }
+ });
+ }
+
+ // If using mouseout/mouseleave as a hide event...
+ if(/mouse(out|leave)/i.test(options.hide.event)) {
+ // Hide tooltips when leaving current window/frame (but not select/option elements)
+ if(options.hide.leave === 'window') {
+ targets.window.bind('mouseout' + namespace, function(event) {
+ if(/select|option/.test(event.target) && !event.relatedTarget) { self.hide(event); }
+ });
+ }
+ }
+
+ /*
+ * Make sure hoverIntent functions properly by using mouseleave to clear show timer if
+ * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
+ */
+ else if(/mouse(over|enter)/i.test(options.show.event)) {
+ targets.hide.bind('mouseleave'+namespace, function(event) {
+ clearTimeout(self.timers.show);
+ });
+ }
+
+ // Hide tooltip on document mousedown if unfocus events are enabled
+ if(('' + options.hide.event).indexOf('unfocus') > -1) {
+ targets.document.bind('mousedown'+namespace, function(event) {
+ var $target = $(event.target),
+ enabled = !tooltip.hasClass(disabled) && tooltip.is(':visible');
+
+ if($target[0] !== tooltip[0] && $target.parents(selector).length === 0 && $target.add(target).length > 1) {
+ self.hide(event);
+ }
+ });
+ }
+
+ // Check if the tooltip hides when inactive
+ if('number' === typeof options.hide.inactive) {
+ // Bind inactive method to target as a custom event
+ targets.show.bind('qtip-'+id+'-inactive', inactiveMethod);
+
+ // Define events which reset the 'inactive' event handler
+ $.each(QTIP.inactiveEvents, function(index, type){
+ targets.hide.add(elements.tooltip).bind(type+namespace+'-inactive', inactiveMethod);
+ });
+ }
+
+ // Apply hide events
+ $.each(events.hide, function(index, type) {
+ var showIndex = $.inArray(type, events.show),
+ targetHide = $(targets.hide);
+
+ // Both events and targets are identical, apply events using a toggle
+ if((showIndex > -1 && targetHide.add(targets.show).length === targetHide.length) || type === 'unfocus')
+ {
+ targets.show.bind(type+namespace, function(event) {
+ if(tooltip.is(':visible')) { hideMethod(event); }
+ else { showMethod(event); }
+ });
+
+ // Don't bind the event again
+ delete events.show[ showIndex ];
+ }
+
+ // Events are not identical, bind normally
+ else { targets.hide.bind(type+namespace, hideMethod); }
+ });
+
+ // Apply show events
+ $.each(events.show, function(index, type) {
+ targets.show.bind(type+namespace, showMethod);
+ });
+
+ // Check if the tooltip hides when mouse is moved a certain distance
+ if('number' === typeof options.hide.distance) {
+ // Bind mousemove to target to detect distance difference
+ targets.show.add(tooltip).bind('mousemove'+namespace, function(event) {
+ var origin = cache.origin || {},
+ limit = options.hide.distance,
+ abs = Math.abs;
+
+ // Check if the movement has gone beyond the limit, and hide it if so
+ if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) {
+ self.hide(event);
+ }
+ });
+ }
+
+ // Mouse positioning events
+ if(posOptions.target === 'mouse') {
+ // Cache mousemove coords on show targets
+ targets.show.bind('mousemove'+namespace, function(event) {
+ MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' };
+ });
+
+ // If mouse adjustment is on...
+ if(posOptions.adjust.mouse) {
+ // Apply a mouseleave event so we don't get problems with overlapping
+ if(options.hide.event) {
+ tooltip.bind('mouseleave'+namespace, function(event) {
+ if((event.relatedTarget || event.target) !== targets.show[0]) { self.hide(event); }
+ });
+ }
+
+ // Update tooltip position on mousemove
+ targets.document.bind('mousemove'+namespace, function(event) {
+ // Update the tooltip position only if the tooltip is visible and adjustment is enabled
+ if(!tooltip.hasClass(disabled) && tooltip.is(':visible')) {
+ self.reposition(event || MOUSE);
+ }
+ });
+ }
+ }
+
+ // Adjust positions of the tooltip on window resize if enabled
+ if(posOptions.adjust.resize || targets.viewport.length) {
+ ($.event.special.resize ? targets.viewport : targets.window).bind('resize'+namespace, repositionMethod);
+ }
+
+ // Adjust tooltip position on scroll if screen adjustment is enabled
+ if(targets.viewport.length || (IE6 && tooltip.css('position') === 'fixed')) {
+ targets.viewport.bind('scroll'+namespace, repositionMethod);
+ }
+ }
+
+ function unassignEvents()
+ {
+ var targets = [
+ options.show.target[0],
+ options.hide.target[0],
+ self.rendered && elements.tooltip[0],
+ options.position.container[0],
+ options.position.viewport[0],
+ window,
+ document
+ ];
+
+ // Check if tooltip is rendered
+ if(self.rendered) {
+ $([]).pushStack( $.grep(targets, function(i){ return typeof i === 'object'; }) ).unbind(namespace);
+ }
+
+ // Tooltip isn't yet rendered, remove render event
+ else { options.show.target.unbind(namespace+'-create'); }
+ }
+
+ // Setup builtin .set() option checks
+ self.checks.builtin = {
+ // Core checks
+ '^id$': function(obj, o, v) {
+ var id = v === TRUE ? QTIP.nextid : v,
+ tooltipID = uitooltip + '-' + id;
+
+ if(id !== FALSE && id.length > 0 && !$('#'+tooltipID).length) {
+ tooltip[0].id = tooltipID;
+ elements.content[0].id = tooltipID + '-content';
+ elements.title[0].id = tooltipID + '-title';
+ }
+ },
+
+ // Content checks
+ '^content.text$': function(obj, o, v){ updateContent(v); },
+ '^content.title.text$': function(obj, o, v) {
+ // Remove title if content is null
+ if(!v) { return removeTitle(); }
+
+ // If title isn't already created, create it now and update
+ if(!elements.title && v) { createTitle(); }
+ updateTitle(v);
+ },
+ '^content.title.button$': function(obj, o, v){ updateButton(v); },
+
+ // Position checks
+ '^position.(my|at)$': function(obj, o, v){
+ // Parse new corner value into Corner objecct
+ if('string' === typeof v) {
+ obj[o] = new PLUGINS.Corner(v);
+ }
+ },
+ '^position.container$': function(obj, o, v){
+ if(self.rendered) { tooltip.appendTo(v); }
+ },
+
+ // Show checks
+ '^show.ready$': function() {
+ if(!self.rendered) { self.render(1); }
+ else { self.toggle(TRUE); }
+ },
+
+ // Style checks
+ '^style.classes$': function(obj, o, v) {
+ tooltip.attr('class', uitooltip + ' qtip ui-helper-reset ' + v);
+ },
+ '^style.widget|content.title': setWidget,
+
+ // Events check
+ '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) {
+ tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
+ },
+
+ // Properties which require event reassignment
+ '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() {
+ var posOptions = options.position;
+
+ // Set tracking flag
+ tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse);
+
+ // Reassign events
+ unassignEvents(); assignEvents();
+ }
+ };
+
+ /*
+ * Public API methods
+ */
+ $.extend(self, {
+ render: function(show)
+ {
+ if(self.rendered) { return self; } // If tooltip has already been rendered, exit
+
+ var title = options.content.title.text,
+ posOptions = options.position,
+ callback = $.Event('tooltiprender');
+
+ // Add ARIA attributes to target
+ $.attr(target[0], 'aria-describedby', tooltipID);
+
+ // Create tooltip element
+ tooltip = elements.tooltip = $('<div/>', {
+ 'id': tooltipID,
+ 'class': uitooltip + ' qtip ui-helper-reset ' + defaultClass + ' ' + options.style.classes,
+ 'width': options.style.width || '',
+ 'height': options.style.height || '',
+ 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
+
+ /* ARIA specific attributes */
+ 'role': 'alert',
+ 'aria-live': 'polite',
+ 'aria-atomic': FALSE,
+ 'aria-describedby': tooltipID + '-content',
+ 'aria-hidden': TRUE
+ })
+ .toggleClass(disabled, cache.disabled)
+ .data('qtip', self)
+ .appendTo(options.position.container)
+ .append(
+ // Create content element
+ elements.content = $('<div />', {
+ 'class': uitooltip + '-content',
+ 'id': tooltipID + '-content',
+ 'aria-atomic': TRUE
+ })
+ );
+
+ // Set rendered flag and prevent redundant redraw/reposition calls for now
+ self.rendered = -1;
+ isDrawing = 1; isPositioning = 1;
+
+ // Update title
+ if(title) {
+ createTitle();
+ updateTitle(title, FALSE);
+ }
+
+ // Set proper rendered flag and update content
+ updateContent(options.content.text, FALSE);
+ self.rendered = TRUE;
+
+ // Setup widget classes
+ setWidget();
+
+ // Assign passed event callbacks (before plugins!)
+ $.each(options.events, function(name, callback) {
+ if($.isFunction(callback)) {
+ tooltip.bind(name === 'toggle' ? 'tooltipshow tooltiphide' : 'tooltip'+name, callback);
+ }
+ });
+
+ // Initialize 'render' plugins
+ $.each(PLUGINS, function() {
+ if(this.initialize === 'render') { this(self); }
+ });
+
+ // Assign events
+ assignEvents();
+
+ /* Queue this part of the render process in our fx queue so we can
+ * load images before the tooltip renders fully.
+ *
+ * See: updateContent method
+ */
+ tooltip.queue('fx', function(next) {
+ // Trigger tooltiprender event and pass original triggering event as original
+ callback.originalEvent = cache.event;
+ tooltip.trigger(callback, [self]);
+
+ // Reset flags
+ isDrawing = 0; isPositioning = 0;
+
+ // Redraw the tooltip manually now we're fully rendered
+ self.redraw();
+
+ // Show tooltip if needed
+ if(options.show.ready || show) {
+ self.toggle(TRUE, cache.event);
+ }
+
+ next(); // Move on to next method in queue
+ });
+
+ return self;
+ },
+
+ get: function(notation)
+ {
+ var result, o;
+
+ switch(notation.toLowerCase())
+ {
+ case 'dimensions':
+ result = {
+ height: tooltip.outerHeight(), width: tooltip.outerWidth()
+ };
+ break;
+
+ case 'offset':
+ result = PLUGINS.offset(tooltip, options.position.container);
+ break;
+
+ default:
+ o = convertNotation(notation.toLowerCase());
+ result = o[0][ o[1] ];
+ result = result.precedance ? result.string() : result;
+ break;
+ }
+
+ return result;
+ },
+
+ set: function(option, value)
+ {
+ var rmove = /^position\.(my|at|adjust|target|container)|style|content|show\.ready/i,
+ rdraw = /^content\.(title|attr)|style/i,
+ reposition = FALSE,
+ redraw = FALSE,
+ checks = self.checks,
+ name;
+
+ function callback(notation, args) {
+ var category, rule, match;
+
+ for(category in checks) {
+ for(rule in checks[category]) {
+ if(match = (new RegExp(rule, 'i')).exec(notation)) {
+ args.push(match);
+ checks[category][rule].apply(self, args);
+ }
+ }
+ }
+ }
+
+ // Convert singular option/value pair into object form
+ if('string' === typeof option) {
+ name = option; option = {}; option[name] = value;
+ }
+ else { option = $.extend(TRUE, {}, option); }
+
+ // Set all of the defined options to their new values
+ $.each(option, function(notation, value) {
+ var obj = convertNotation( notation.toLowerCase() ), previous;
+
+ // Set new obj value
+ previous = obj[0][ obj[1] ];
+ obj[0][ obj[1] ] = 'object' === typeof value && value.nodeType ? $(value) : value;
+
+ // Set the new params for the callback
+ option[notation] = [obj[0], obj[1], value, previous];
+
+ // Also check if we need to reposition / redraw
+ reposition = rmove.test(notation) || reposition;
+ redraw = rdraw.test(notation) || redraw;
+ });
+
+ // Re-sanitize options
+ sanitizeOptions(options);
+
+ /*
+ * Execute any valid callbacks for the set options
+ * Also set isPositioning/isDrawing so we don't get loads of redundant repositioning
+ * and redraw calls.
+ */
+ isPositioning = isDrawing = 1; $.each(option, callback); isPositioning = isDrawing = 0;
+
+ // Update position / redraw if needed
+ if(tooltip.is(':visible') && self.rendered) {
+ if(reposition) {
+ self.reposition( options.position.target === 'mouse' ? NULL : cache.event );
+ }
+ if(redraw) { self.redraw(); }
+ }
+
+ return self;
+ },
+
+ toggle: function(state, event)
+ {
+ // Make sure tooltip is rendered
+ if(!self.rendered) {
+ if(state) { self.render(1); } // Render the tooltip if showing and it isn't already
+ else { return self; }
+ }
+
+ var type = state ? 'show' : 'hide',
+ opts = options[type],
+ visible = tooltip.is(':visible'),
+ sameTarget = !event || options[type].target.length < 2 || cache.target[0] === event.target,
+ posOptions = options.position,
+ contentOptions = options.content,
+ delay,
+ callback;
+
+ // Detect state if valid one isn't provided
+ if((typeof state).search('boolean|number')) { state = !visible; }
+
+ // Return if element is already in correct state
+ if(!tooltip.is(':animated') && visible === state && sameTarget) { return self; }
+
+ // Try to prevent flickering when tooltip overlaps show element
+ if(event) {
+ if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) &&
+ event.target === options.show.target[0] && tooltip.has(event.relatedTarget).length) {
+ return self;
+ }
+
+ // Cache event
+ cache.event = $.extend({}, event);
+ }
+
+ // Call API methods
+ callback = $.Event('tooltip'+type);
+ callback.originalEvent = event ? cache.event : NULL;
+ tooltip.trigger(callback, [self, 90]);
+ if(callback.isDefaultPrevented()){ return self; }
+
+ // Set ARIA hidden status attribute
+ $.attr(tooltip[0], 'aria-hidden', !!!state);
+
+ // Execute state specific properties
+ if(state) {
+ // Store show origin coordinates
+ cache.origin = $.extend({}, MOUSE);
+
+ // Focus the tooltip
+ self.focus(event);
+
+ // Update tooltip content & title if it's a dynamic function
+ if($.isFunction(contentOptions.text)) { updateContent(contentOptions.text, FALSE); }
+ if($.isFunction(contentOptions.title.text)) { updateTitle(contentOptions.title.text, FALSE); }
+
+ // Cache mousemove events for positioning purposes (if not already tracking)
+ if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) {
+ $(document).bind('mousemove.qtip', function(event) {
+ MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' };
+ });
+ trackingBound = TRUE;
+ }
+
+ // Update the tooltip position
+ self.reposition(event);
+
+ // Hide other tooltips if tooltip is solo, using it as the context
+ if(opts.solo) { $(selector, opts.solo).not(tooltip).qtip('hide', callback); }
+ }
+ else {
+ // Clear show timer if we're hiding
+ clearTimeout(self.timers.show);
+
+ // Remove cached origin on hide
+ delete cache.origin;
+
+ // Remove mouse tracking event if not needed (all tracking qTips are hidden)
+ if(trackingBound && !$(selector+'[tracking="true"]:visible', opts.solo).not(tooltip).length) {
+ $(document).unbind('mousemove.qtip');
+ trackingBound = FALSE;
+ }
+
+ // Blur the tooltip
+ self.blur(event);
+ }
+
+ // Define post-animation, state specific properties
+ function after() {
+ if(state) {
+ // Prevent antialias from disappearing in IE by removing filter
+ if($.browser.msie) { tooltip[0].style.removeAttribute('filter'); }
+
+ // Remove overflow setting to prevent tip bugs
+ tooltip.css('overflow', '');
+
+ // Autofocus elements if enabled
+ if('string' === typeof opts.autofocus) {
+ $(opts.autofocus, tooltip).focus();
+ }
+
+ // Call API method
+ callback = $.Event('tooltipvisible');
+ callback.originalEvent = event ? cache.event : NULL;
+ tooltip.trigger(callback, [self]);
+ }
+ else {
+ // Reset CSS states
+ tooltip.css({
+ display: '',
+ visibility: '',
+ opacity: '',
+ left: '',
+ top: ''
+ });
+ }
+ }
+
+ // Clear animation queue if same target
+ if(sameTarget) { tooltip.stop(0, 1); }
+
+ // If no effect type is supplied, use a simple toggle
+ if(opts.effect === FALSE) {
+ tooltip[ type ]();
+ after.call(tooltip);
+ }
+
+ // Use custom function if provided
+ else if($.isFunction(opts.effect)) {
+ opts.effect.call(tooltip, self);
+ tooltip.queue('fx', function(n){ after(); n(); });
+ }
+
+ // Use basic fade function by default
+ else { tooltip.fadeTo(90, state ? 1 : 0, after); }
+
+ // If inactive hide method is set, active it
+ if(state) { opts.target.trigger('qtip-'+id+'-inactive'); }
+
+ return self;
+ },
+
+ show: function(event){ return self.toggle(TRUE, event); },
+
+ hide: function(event){ return self.toggle(FALSE, event); },
+
+ focus: function(event)
+ {
+ if(!self.rendered) { return self; }
+
+ var qtips = $(selector),
+ curIndex = parseInt(tooltip[0].style.zIndex, 10),
+ newIndex = QTIP.zindex + qtips.length,
+ cachedEvent = $.extend({}, event),
+ focusedElem, callback;
+
+ // Only update the z-index if it has changed and tooltip is not already focused
+ if(!tooltip.hasClass(focusClass))
+ {
+ // Call API method
+ callback = $.Event('tooltipfocus');
+ callback.originalEvent = cachedEvent;
+ tooltip.trigger(callback, [self, newIndex]);
+
+ // If default action wasn't prevented...
+ if(!callback.isDefaultPrevented()) {
+ // Only update z-index's if they've changed
+ if(curIndex !== newIndex) {
+ // Reduce our z-index's and keep them properly ordered
+ qtips.each(function() {
+ if(this.style.zIndex > curIndex) {
+ this.style.zIndex = this.style.zIndex - 1;
+ }
+ });
+
+ // Fire blur event for focused tooltip
+ qtips.filter('.' + focusClass).qtip('blur', cachedEvent);
+ }
+
+ // Set the new z-index
+ tooltip.addClass(focusClass)[0].style.zIndex = newIndex;
+ }
+ }
+
+ return self;
+ },
+
+ blur: function(event) {
+ var cachedEvent = $.extend({}, event),
+ callback;
+
+ // Set focused status to FALSE
+ tooltip.removeClass(focusClass);
+
+ // Trigger blur event
+ callback = $.Event('tooltipblur');
+ callback.originalEvent = cachedEvent;
+ tooltip.trigger(callback, [self]);
+
+ return self;
+ },
+
+ reposition: function(event, effect)
+ {
+ if(!self.rendered || isPositioning) { return self; }
+
+ // Set positioning flag
+ isPositioning = 1;
+
+ var target = options.position.target,
+ posOptions = options.position,
+ my = posOptions.my,
+ at = posOptions.at,
+ adjust = posOptions.adjust,
+ method = adjust.method.split(' '),
+ elemWidth = tooltip.outerWidth(),
+ elemHeight = tooltip.outerHeight(),
+ targetWidth = 0,
+ targetHeight = 0,
+ callback = $.Event('tooltipmove'),
+ fixed = tooltip.css('position') === 'fixed',
+ viewport = posOptions.viewport,
+ position = { left: 0, top: 0 },
+ tip = self.plugins.tip,
+ readjust = {
+ // Repositioning method and axis detection
+ horizontal: method[0],
+ vertical: method[1] || method[0],
+
+ // Reposition methods
+ left: function(posLeft) {
+ var isShift = readjust.horizontal === 'shift',
+ viewportScroll = viewport.offset.left + viewport.scrollLeft,
+ myWidth = my.x === 'left' ? elemWidth : my.x === 'right' ? -elemWidth : -elemWidth / 2,
+ atWidth = at.x === 'left' ? targetWidth : at.x === 'right' ? -targetWidth : -targetWidth / 2,
+ tipWidth = tip && tip.size ? tip.size.width || 0 : 0,
+ tipAdjust = tip && tip.corner && tip.corner.precedance === 'x' && !isShift ? tipWidth : 0,
+ overflowLeft = viewportScroll - posLeft + tipAdjust,
+ overflowRight = posLeft + elemWidth - viewport.width - viewportScroll + tipAdjust,
+ offset = myWidth - (my.precedance === 'x' || my.x === my.y ? atWidth : 0),
+ isCenter = my.x === 'center';
+
+ // Optional 'shift' style repositioning
+ if(isShift) {
+ tipAdjust = tip && tip.corner && tip.corner.precedance === 'y' ? tipWidth : 0;
+ offset = (my.x === 'left' ? 1 : -1) * myWidth - tipAdjust;
+
+ // Adjust position but keep it within viewport dimensions
+ position.left += overflowLeft > 0 ? overflowLeft : overflowRight > 0 ? -overflowRight : 0;
+ position.left = Math.max(
+ viewport.offset.left + (tipAdjust && tip.corner.x === 'center' ? tip.offset : 0),
+ posLeft - offset,
+ Math.min(
+ Math.max(viewport.offset.left + viewport.width, posLeft + offset),
+ position.left
+ )
+ );
+ }
+
+ // Default 'flip' repositioning
+ else {
+ if(overflowLeft > 0 && (my.x !== 'left' || overflowRight > 0)) {
+ position.left -= offset + (isCenter ? 0 : 2 * adjust.x);
+ }
+ else if(overflowRight > 0 && (my.x !== 'right' || overflowLeft > 0) ) {
+ position.left -= isCenter ? -offset : offset + (2 * adjust.x);
+ }
+ if(position.left !== posLeft && isCenter) { position.left -= adjust.x; }
+
+ // Make sure we haven't made things worse with the adjustment and return the adjusted difference
+ if(position.left < viewportScroll && -position.left > overflowRight) { position.left = posLeft; }
+ }
+
+ return position.left - posLeft;
+ },
+ top: function(posTop) {
+ var isShift = readjust.vertical === 'shift',
+ viewportScroll = viewport.offset.top + viewport.scrollTop,
+ myHeight = my.y === 'top' ? elemHeight : my.y === 'bottom' ? -elemHeight : -elemHeight / 2,
+ atHeight = at.y === 'top' ? targetHeight : at.y === 'bottom' ? -targetHeight : -targetHeight / 2,
+ tipHeight = tip && tip.size ? tip.size.height || 0 : 0,
+ tipAdjust = tip && tip.corner && tip.corner.precedance === 'y' && !isShift ? tipHeight : 0,
+ overflowTop = viewportScroll - posTop + tipAdjust,
+ overflowBottom = posTop + elemHeight - viewport.height - viewportScroll + tipAdjust,
+ offset = myHeight - (my.precedance === 'y' || my.x === my.y ? atHeight : 0),
+ isCenter = my.y === 'center';
+
+ // Optional 'shift' style repositioning
+ if(isShift) {
+ tipAdjust = tip && tip.corner && tip.corner.precedance === 'x' ? tipHeight : 0;
+ offset = (my.y === 'top' ? 1 : -1) * myHeight - tipAdjust;
+
+ // Adjust position but keep it within viewport dimensions
+ position.top += overflowTop > 0 ? overflowTop : overflowBottom > 0 ? -overflowBottom : 0;
+ position.top = Math.max(
+ viewport.offset.top + (tipAdjust && tip.corner.x === 'center' ? tip.offset : 0),
+ posTop - offset,
+ Math.min(
+ Math.max(viewport.offset.top + viewport.height, posTop + offset),
+ position.top
+ )
+ );
+ }
+
+ // Default 'flip' repositioning
+ else {
+ if(overflowTop > 0 && (my.y !== 'top' || overflowBottom > 0)) {
+ position.top -= offset + (isCenter ? 0 : 2 * adjust.y);
+ }
+ else if(overflowBottom > 0 && (my.y !== 'bottom' || overflowTop > 0) ) {
+ position.top -= isCenter ? -offset : offset + (2 * adjust.y);
+ }
+ if(position.top !== posTop && isCenter) { position.top -= adjust.y; }
+
+ // Make sure we haven't made things worse with the adjustment and return the adjusted difference
+ if(position.top < 0 && -position.top > overflowBottom) { position.top = posTop; }
+ }
+
+ return position.top - posTop;
+ }
+ };
+
+ // Check if absolute position was passed
+ if($.isArray(target) && target.length === 2) {
+ // Force left top and set position
+ at = { x: 'left', y: 'top' };
+ position = { left: target[0], top: target[1] };
+ }
+
+ // Check if mouse was the target
+ else if(target === 'mouse' && ((event && event.pageX) || cache.event.pageX)) {
+ // Force left top to allow flipping
+ at = { x: 'left', y: 'top' };
+
+ // Use cached event if one isn't available for positioning
+ event = (event && (event.type === 'resize' || event.type === 'scroll') ? cache.event :
+ event && event.pageX && event.type === 'mousemove' ? event :
+ MOUSE && MOUSE.pageX && (adjust.mouse || !event || !event.pageX) ? { pageX: MOUSE.pageX, pageY: MOUSE.pageY } :
+ !adjust.mouse && cache.origin && cache.origin.pageX ? cache.origin :
+ event) || event || cache.event || MOUSE || {};
+
+ // Use event coordinates for position
+ position = { top: event.pageY, left: event.pageX };
+ }
+
+ // Target wasn't mouse or absolute...
+ else {
+ // Check if event targetting is being used
+ if(target === 'event') {
+ if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
+ target = cache.target = $(event.target);
+ }
+ else {
+ target = cache.target;
+ }
+ }
+ else { cache.target = $(target); }
+
+ // Parse the target into a jQuery object and make sure there's an element present
+ target = $(target).eq(0);
+ if(target.length === 0) { return self; }
+
+ // Check if window or document is the target
+ else if(target[0] === document || target[0] === window) {
+ targetWidth = PLUGINS.iOS ? window.innerWidth : target.width();
+ targetHeight = PLUGINS.iOS ? window.innerHeight : target.height();
+
+ if(target[0] === window) {
+ position = {
+ top: !fixed || PLUGINS.iOS ? (viewport || target).scrollTop() : 0,
+ left: !fixed || PLUGINS.iOS ? (viewport || target).scrollLeft() : 0
+ };
+ }
+ }
+
+ // Use Imagemap/SVG plugins if needed
+ else if(target.is('area') && PLUGINS.imagemap) {
+ position = PLUGINS.imagemap(target, at);
+ }
+ else if(target[0].namespaceURI === 'http://www.w3.org/2000/svg' && PLUGINS.svg) {
+ position = PLUGINS.svg(target, at);
+ }
+
+ else {
+ targetWidth = target.outerWidth();
+ targetHeight = target.outerHeight();
+
+ position = PLUGINS.offset(target, posOptions.container, fixed);
+ }
+
+ // Parse returned plugin values into proper variables
+ if(position.offset) {
+ targetWidth = position.width;
+ targetHeight = position.height;
+ position = position.offset;
+ }
+
+ // Adjust position relative to target
+ position.left += at.x === 'right' ? targetWidth : at.x === 'center' ? targetWidth / 2 : 0;
+ position.top += at.y === 'bottom' ? targetHeight : at.y === 'center' ? targetHeight / 2 : 0;
+ }
+
+ // Adjust position relative to tooltip
+ position.left += adjust.x + (my.x === 'right' ? -elemWidth : my.x === 'center' ? -elemWidth / 2 : 0);
+ position.top += adjust.y + (my.y === 'bottom' ? -elemHeight : my.y === 'center' ? -elemHeight / 2 : 0);
+
+ // Calculate collision offset values if viewport positioning is enabled
+ if(viewport.jquery && target[0] !== window && target[0] !== docBody &&
+ readjust.vertical+readjust.horizontal !== 'nonenone')
+ {
+ // Cache our viewport details
+ viewport = {
+ elem: viewport,
+ height: viewport[ (viewport[0] === window ? 'h' : 'outerH') + 'eight' ](),
+ width: viewport[ (viewport[0] === window ? 'w' : 'outerW') + 'idth' ](),
+ scrollLeft: fixed ? 0 : viewport.scrollLeft(),
+ scrollTop: fixed ? 0 : viewport.scrollTop(),
+ offset: viewport.offset() || { left: 0, top: 0 }
+ };
+
+ // Adjust position based onviewport and adjustment options
+ position.adjusted = {
+ left: readjust.horizontal !== 'none' ? readjust.left(position.left) : 0,
+ top: readjust.vertical !== 'none' ? readjust.top(position.top) : 0
+ };
+ }
+
+ //Viewport adjustment is disabled, set values to zero
+ else { position.adjusted = { left: 0, top: 0 }; }
+
+ // Set tooltip position class
+ tooltip.attr('class', function(i, val) {
+ return $.attr(this, 'class').replace(/ui-tooltip-pos-\w+/i, '');
+ })
+ .addClass(uitooltip + '-pos-' + my.abbreviation());
+
+ // Call API method
+ callback.originalEvent = $.extend({}, event);
+ tooltip.trigger(callback, [self, position, viewport.elem || viewport]);
+ if(callback.isDefaultPrevented()){ return self; }
+ delete position.adjusted;
+
+ // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly
+ if(effect === FALSE || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
+ tooltip.css(position);
+ }
+
+ // Use custom function if provided
+ else if($.isFunction(posOptions.effect)) {
+ posOptions.effect.call(tooltip, self, $.extend({}, position));
+ tooltip.queue(function(next) {
+ // Reset attributes to avoid cross-browser rendering bugs
+ $(this).css({ opacity: '', height: '' });
+ if($.browser.msie) { this.style.removeAttribute('filter'); }
+
+ next();
+ });
+ }
+
+ // Set positioning flag
+ isPositioning = 0;
+
+ return self;
+ },
+
+ // Max/min width simulator function for all browsers.. yeaaah!
+ redraw: function()
+ {
+ if(self.rendered < 1 || isDrawing) { return self; }
+
+ var container = options.position.container,
+ perc, width, max, min;
+
+ // Set drawing flag
+ isDrawing = 1;
+
+ // If tooltip has a set height, just set it... like a boss!
+ if(options.style.height) { tooltip.css('height', options.style.height); }
+
+ // If tooltip has a set width, just set it... like a boss!
+ if(options.style.width) { tooltip.css('width', options.style.width); }
+
+ // Otherwise simualte max/min width...
+ else {
+ // Reset width and add fluid class
+ tooltip.css('width', '').addClass(fluidClass);
+
+ // Grab our tooltip width (add 1 so we don't get wrapping problems.. huzzah!)
+ width = tooltip.width() + 1;
+
+ // Grab our max/min properties
+ max = tooltip.css('max-width') || '';
+ min = tooltip.css('min-width') || '';
+
+ // Parse into proper pixel values
+ perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0;
+ max = ((max.indexOf('%') > -1 ? perc : 1) * parseInt(max, 10)) || width;
+ min = ((min.indexOf('%') > -1 ? perc : 1) * parseInt(min, 10)) || 0;
+
+ // Determine new dimension size based on max/min/current values
+ width = max + min ? Math.min(Math.max(width, min), max) : width;
+
+ // Set the newly calculated width and remvoe fluid class
+ tooltip.css('width', Math.round(width)).removeClass(fluidClass);
+ }
+
+ // Set drawing flag
+ isDrawing = 0;
+
+ return self;
+ },
+
+ disable: function(state)
+ {
+ if('boolean' !== typeof state) {
+ state = !(tooltip.hasClass(disabled) || cache.disabled);
+ }
+
+ if(self.rendered) {
+ tooltip.toggleClass(disabled, state);
+ $.attr(tooltip[0], 'aria-disabled', state);
+ }
+ else {
+ cache.disabled = !!state;
+ }
+
+ return self;
+ },
+
+ enable: function() { return self.disable(FALSE); },
+
+ destroy: function()
+ {
+ var t = target[0],
+ title = $.attr(t, oldtitle);
+
+ // Destroy tooltip and any associated plugins if rendered
+ if(self.rendered) {
+ tooltip.remove();
+
+ $.each(self.plugins, function() {
+ if(this.destroy) { this.destroy(); }
+ });
+ }
+
+ // Clear timers and remove bound events
+ clearTimeout(self.timers.show);
+ clearTimeout(self.timers.hide);
+ unassignEvents();
+
+ // Remove api object
+ $.removeData(t, 'qtip');
+
+ // Reset old title attribute if removed
+ if(options.suppress && title) {
+ $.attr(t, 'title', title);
+ target.removeAttr(oldtitle);
+ }
+
+ // Remove ARIA attributes and bound qtip events
+ target.removeAttr('aria-describedby').unbind('.qtip');
+
+ // Remove ID from sued id object
+ delete usedIDs[self.id];
+
+ return target;
+ }
+ });
+}
+
+// Initialization method
+function init(id, opts)
+{
+ var obj, posOptions, attr, config, title,
+
+ // Setup element references
+ elem = $(this),
+ docBody = $(document.body),
+
+ // Use document body instead of document element if needed
+ newTarget = this === document ? docBody : elem,
+
+ // Grab metadata from element if plugin is present
+ metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL,
+
+ // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise
+ metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL,
+
+ // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method,
+ html5 = elem.data(opts.metadata.name || 'qtipopts');
+
+ // If we don't get an object returned attempt to parse it manualyl without parseJSON
+ try { html5 = typeof html5 === 'string' ? (new Function("return " + html5))() : html5; }
+ catch(e) { log('Unable to parse HTML5 attribute data: ' + html5); }
+
+ // Merge in and sanitize metadata
+ config = $.extend(TRUE, {}, QTIP.defaults, opts,
+ typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
+ sanitizeOptions(metadata5 || metadata));
+
+ // Re-grab our positioning options now we've merged our metadata and set id to passed value
+ posOptions = config.position;
+ config.id = id;
+
+ // Setup missing content if none is detected
+ if('boolean' === typeof config.content.text) {
+ attr = elem.attr(config.content.attr);
+
+ // Grab from supplied attribute if available
+ if(config.content.attr !== FALSE && attr) { config.content.text = attr; }
+
+ // No valid content was found, abort render
+ else {
+ log('Unable to locate content for tooltip! Aborting render of tooltip on element: ', elem);
+ return FALSE;
+ }
+ }
+
+ // Setup target options
+ if(posOptions.container === FALSE) { posOptions.container = docBody; }
+ if(posOptions.target === FALSE) { posOptions.target = newTarget; }
+ if(config.show.target === FALSE) { config.show.target = newTarget; }
+ if(config.show.solo === TRUE) { config.show.solo = docBody; }
+ if(config.hide.target === FALSE) { config.hide.target = newTarget; }
+ if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; }
+
+ // Convert position corner values into x and y strings
+ posOptions.at = new PLUGINS.Corner(posOptions.at);
+ posOptions.my = new PLUGINS.Corner(posOptions.my);
+
+ // Destroy previous tooltip if overwrite is enabled, or skip element if not
+ if($.data(this, 'qtip')) {
+ if(config.overwrite) {
+ elem.qtip('destroy');
+ }
+ else if(config.overwrite === FALSE) {
+ return FALSE;
+ }
+ }
+
+ // Remove title attribute and store it if present
+ if(config.suppress && (title = $.attr(this, 'title'))) {
+ $(this).removeAttr('title').attr(oldtitle, title);
+ }
+
+ // Initialize the tooltip and add API reference
+ obj = new QTip(elem, config, id, !!attr);
+ $.data(this, 'qtip', obj);
+
+ // Catch remove events on target element to destroy redundant tooltip
+ elem.bind('remove.qtip', function(){ obj.destroy(); });
+
+ return obj;
+}
+
+// jQuery $.fn extension method
+QTIP = $.fn.qtip = function(options, notation, newValue)
+{
+ var command = ('' + options).toLowerCase(), // Parse command
+ returned = NULL,
+ args = command === 'disable' ? [TRUE] : $.makeArray(arguments).slice(1),
+ event = args[args.length - 1],
+ opts = this[0] ? $.data(this[0], 'qtip') : NULL;
+
+ // Check for API request
+ if((!arguments.length && opts) || command === 'api') {
+ return opts;
+ }
+
+ // Execute API command if present
+ else if('string' === typeof options)
+ {
+ this.each(function()
+ {
+ var api = $.data(this, 'qtip');
+ if(!api) { return TRUE; }
+
+ // Cache the event if possible
+ if(event && event.timeStamp) { api.cache.event = event; }
+
+ // Check for specific API commands
+ if((command === 'option' || command === 'options') && notation) {
+ if($.isPlainObject(notation) || newValue !== undefined) {
+ api.set(notation, newValue);
+ }
+ else {
+ returned = api.get(notation);
+ return FALSE;
+ }
+ }
+
+ // Execute API command
+ else if(api[command]) {
+ api[command].apply(api[command], args);
+ }
+ });
+
+ return returned !== NULL ? returned : this;
+ }
+
+ // No API commands. validate provided options and setup qTips
+ else if('object' === typeof options || !arguments.length)
+ {
+ opts = sanitizeOptions($.extend(TRUE, {}, options));
+
+ // Bind the qTips
+ return QTIP.bind.call(this, opts, event);
+ }
+};
+
+// $.fn.qtip Bind method
+QTIP.bind = function(opts, event)
+{
+ return this.each(function(i) {
+ var options, targets, events, namespace, api, id;
+
+ // Find next available ID, or use custom ID if provided
+ id = $.isArray(opts.id) ? opts.id[i] : opts.id;
+ id = !id || id === FALSE || id.length < 1 || usedIDs[id] ? QTIP.nextid++ : (usedIDs[id] = id);
+
+ // Setup events namespace
+ namespace = '.qtip-'+id+'-create';
+
+ // Initialize the qTip and re-grab newly sanitized options
+ api = init.call(this, id, opts);
+ if(api === FALSE) { return TRUE; }
+ options = api.options;
+
+ // Initialize plugins
+ $.each(PLUGINS, function() {
+ if(this.initialize === 'initialize') { this(api); }
+ });
+
+ // Determine hide and show targets
+ targets = { show: options.show.target, hide: options.hide.target };
+ events = {
+ show: $.trim('' + options.show.event).replace(/ /g, namespace+' ') + namespace,
+ hide: $.trim('' + options.hide.event).replace(/ /g, namespace+' ') + namespace
+ };
+
+ /*
+ * Make sure hoverIntent functions properly by using mouseleave as a hide event if
+ * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
+ */
+ if(/mouse(over|enter)/i.test(events.show) && !/mouse(out|leave)/i.test(events.hide)) {
+ events.hide += ' mouseleave' + namespace;
+ }
+
+ /*
+ * Also make sure initial mouse targetting works correctly by caching mousemove coords
+ * on show targets before the tooltip has rendered.
+ */
+ targets.show.bind('mousemove'+namespace, function(event) {
+ MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' };
+ });
+
+ // Define hoverIntent function
+ function hoverIntent(event) {
+ function render() {
+ // Cache mouse coords,render and render the tooltip
+ api.render(typeof event === 'object' || options.show.ready);
+
+ // Unbind show and hide events
+ targets.show.add(targets.hide).unbind(namespace);
+ }
+
+ // Only continue if tooltip isn't disabled
+ if(api.cache.disabled) { return FALSE; }
+
+ // Cache the event data
+ api.cache.event = $.extend({}, event);
+ api.cache.target = event ? $(event.target) : [undefined];
+
+ // Start the event sequence
+ if(options.show.delay > 0) {
+ clearTimeout(api.timers.show);
+ api.timers.show = setTimeout(render, options.show.delay);
+ if(events.show !== events.hide) {
+ targets.hide.bind(events.hide, function() { clearTimeout(api.timers.show); });
+ }
+ }
+ else { render(); }
+ }
+
+ // Bind show events to target
+ targets.show.bind(events.show, hoverIntent);
+
+ // Prerendering is enabled, create tooltip now
+ if(options.show.ready || options.prerender) { hoverIntent(event); }
+ });
+};
+
+// Setup base plugins
+PLUGINS = QTIP.plugins = {
+ // Corner object parser
+ Corner: function(corner) {
+ corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, 'center').toLowerCase();
+ this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase();
+ this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase();
+
+ this.precedance = (corner.charAt(0).search(/^(t|b)/) > -1) ? 'y' : 'x';
+ this.string = function() { return this.precedance === 'y' ? this.y+this.x : this.x+this.y; };
+ this.abbreviation = function() {
+ var x = this.x.substr(0,1), y = this.y.substr(0,1);
+ return x === y ? x : (x === 'c' || (x !== 'c' && y !== 'c')) ? y + x : x + y;
+ };
+ },
+
+ // Custom (more correct for qTip!) offset calculator
+ offset: function(elem, container, fixed) {
+ var pos = elem.offset(),
+ parent = container,
+ deep = 0,
+ docBody = document.body,
+ coffset;
+
+ function scroll(e, i) {
+ pos.left += i * e.scrollLeft();
+ pos.top += i * e.scrollTop();
+ }
+
+ if(parent) {
+ // Compensate for non-static containers offset
+ do {
+ if(parent.css('position') !== 'static') {
+ coffset = parent[0] === docBody ?
+ { left: parseInt(parent.css('left'), 10) || 0, top: parseInt(parent.css('top'), 10) || 0 } :
+ parent.position();
+
+ pos.left -= coffset.left + (parseInt(parent.css('borderLeftWidth'), 10) || 0) + (parseInt(parent.css('marginLeft'), 10) || 0);
+ pos.top -= coffset.top + (parseInt(parent.css('borderTopWidth'), 10) || 0);
+
+ deep++;
+ }
+ if(parent[0] === docBody) { break; }
+ }
+ while(parent = parent.offsetParent());
+
+ // Compensate for containers scroll if it also has an offsetParent
+ if(container[0] !== docBody && deep > 1) { scroll( container, 1 ); }
+
+ // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2 - v4.0)
+ if((PLUGINS.iOS < 4.1 && PLUGINS.iOS > 3.1) || (!PLUGINS.iOS && fixed)) { scroll( $(window), -1 ); }
+ }
+
+ return pos;
+ },
+
+ /*
+ * iOS 3.2 - 4.0 scroll fix detection used in offset() function.
+ */
+ iOS: parseFloat(
+ ('' + (/CPU.*OS ([0-9_]{1,3})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1])
+ .replace('undefined', '3_2').replace('_','.')
+ ) || FALSE,
+
+ /*
+ * jQuery-specific $.fn overrides
+ */
+ fn: {
+ /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */
+ attr: function(attr, val) {
+ if(this.length) {
+ var self = this[0],
+ title = 'title',
+ api = $.data(self, 'qtip');
+
+ if(attr === title && 'object' === typeof api && api.options.suppress) {
+ if(arguments.length < 2) {
+ return $.attr(self, oldtitle);
+ }
+ else {
+ // If qTip is rendered and title was originally used as content, update it
+ if(api && api.options.content.attr === title && api.cache.attr) {
+ api.set('content.text', val);
+ }
+
+ // Use the regular attr method to set, then cache the result
+ return this.attr(oldtitle, val);
+ }
+ }
+ }
+
+ return $.fn['attr'+replaceSuffix].apply(this, arguments);
+ },
+
+ /* Allow clone to correctly retrieve cached title attributes */
+ clone: function(keepData) {
+ var titles = $([]), title = 'title',
+
+ // Clone our element using the real clone method
+ elems = $.fn['clone'+replaceSuffix].apply(this, arguments);
+
+ // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false
+ if(!keepData) {
+ elems.filter('['+oldtitle+']').attr('title', function() {
+ return $.attr(this, oldtitle);
+ })
+ .removeAttr(oldtitle);
+ }
+
+ return elems;
+ },
+
+ /*
+ * Taken directly from jQuery 1.8.2 widget source code
+ * Trigger 'remove' event on all elements on removal if jQuery UI isn't present
+ */
+ remove: $.ui ? NULL : function( selector, keepData ) {
+ $(this).each(function() {
+ if (!keepData) {
+ if (!selector || $.filter( selector, [ this ] ).length) {
+ $('*', this).add(this).each(function() {
+ $(this).triggerHandler('remove');
+ });
+ }
+ }
+ });
+ }
+ }
+};
+
+// Apply the fn overrides above
+$.each(PLUGINS.fn, function(name, func) {
+ if(!func) { return TRUE; }
+
+ var old = $.fn[name+replaceSuffix] = $.fn[name];
+ $.fn[name] = function() {
+ return func.apply(this, arguments) || old.apply(this, arguments);
+ };
+});
+
+// Set global qTip properties
+QTIP.version = 'nightly';
+QTIP.nextid = 0;
+QTIP.inactiveEvents = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' ');
+QTIP.zindex = 15000;
+
+// Define configuration defaults
+QTIP.defaults = {
+ prerender: FALSE,
+ id: FALSE,
+ overwrite: TRUE,
+ suppress: TRUE,
+ content: {
+ text: TRUE,
+ attr: 'title',
+ title: {
+ text: FALSE,
+ button: FALSE
+ }
+ },
+ position: {
+ my: 'top left',
+ at: 'bottom right',
+ target: FALSE,
+ container: FALSE,
+ viewport: FALSE,
+ adjust: {
+ x: 0, y: 0,
+ mouse: TRUE,
+ resize: TRUE,
+ method: 'flip flip'
+ },
+ effect: function(api, pos, viewport) {
+ $(this).animate(pos, {
+ duration: 200,
+ queue: FALSE
+ });
+ }
+ },
+ show: {
+ target: FALSE,
+ event: 'mouseenter',
+ effect: TRUE,
+ delay: 90,
+ solo: FALSE,
+ ready: FALSE,
+ autofocus: FALSE
+ },
+ hide: {
+ target: FALSE,
+ event: 'mouseleave',
+ effect: TRUE,
+ delay: 0,
+ fixed: FALSE,
+ inactive: FALSE,
+ leave: 'window',
+ distance: FALSE
+ },
+ style: {
+ classes: '',
+ widget: FALSE,
+ width: FALSE,
+ height: FALSE
+ },
+ events: {
+ render: NULL,
+ move: NULL,
+ show: NULL,
+ hide: NULL,
+ toggle: NULL,
+ visible: NULL,
+ focus: NULL,
+ blur: NULL
+ }
+};
+
+function Ajax(api)
+{
+ var self = this,
+ tooltip = api.elements.tooltip,
+ opts = api.options.content.ajax,
+ namespace = '.qtip-ajax',
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ first = TRUE;
+
+ api.checks.ajax = {
+ '^content.ajax': function(obj, name, v) {
+ // If content.ajax object was reset, set our local var
+ if(name === 'ajax') { opts = v; }
+
+ if(name === 'once') {
+ self.init();
+ }
+ else if(opts && opts.url) {
+ self.load();
+ }
+ else {
+ tooltip.unbind(namespace);
+ }
+ }
+ };
+
+ $.extend(self, {
+ init: function()
+ {
+ // Make sure ajax options are enabled and bind event
+ if(opts && opts.url) {
+ tooltip.unbind(namespace)[ opts.once ? 'one' : 'bind' ]('tooltipshow'+namespace, self.load);
+ }
+
+ return self;
+ },
+
+ load: function(event, first)
+ {
+ // Make sure default event hasn't been prevented
+ if(event && event.isDefaultPrevented()) { return self; }
+
+ var hasSelector = opts.url.indexOf(' '),
+ url = opts.url,
+ selector,
+ hideFirst = opts.once && !opts.loading && first;
+
+ // If loading option is disabled, hide the tooltip until content is retrieved (first time only)
+ if(hideFirst) { tooltip.css('visibility', 'hidden'); }
+
+ // Check if user delcared a content selector like in .load()
+ if(hasSelector > -1) {
+ selector = url.substr(hasSelector);
+ url = url.substr(0, hasSelector);
+ }
+
+ // Define common after callback for both success/error handlers
+ function after() {
+ // Re-display tip if loading and first time, and reset first flag
+ if(hideFirst) { tooltip.css('visibility', ''); first = FALSE; }
+
+ // Call users complete if it was defined
+ if($.isFunction(opts.complete)) { opts.complete.apply(this, arguments); }
+ }
+
+ // Define success handler
+ function successHandler(content) {
+ if(selector) {
+ // Create a dummy div to hold the results and grab the selector element
+ content = $('<div/>')
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(content.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector);
+ }
+
+ // Set the content
+ api.set('content.text', content);
+ }
+
+ // Error handler
+ function errorHandler(xh, status, error){ api.set('content.text', status + ': ' + error); }
+
+ // Setup $.ajax option object and process the request
+ $.ajax( $.extend({ success: successHandler, error: errorHandler, context: api }, opts, { url: url, complete: after }) );
+
+ return self;
+ }
+ });
+
+ self.init();
+}
+
+
+PLUGINS.ajax = function(api)
+{
+ var self = api.plugins.ajax;
+
+ return 'object' === typeof self ? self : (api.plugins.ajax = new Ajax(api));
+};
+
+PLUGINS.ajax.initialize = 'render';
+
+// Setup plugin sanitization
+PLUGINS.ajax.sanitize = function(options)
+{
+ var content = options.content, opts;
+ if(content && 'ajax' in content) {
+ opts = content.ajax;
+ if(typeof opts !== 'object') { opts = options.content.ajax = { url: opts }; }
+ if('boolean' !== typeof opts.once && opts.once) { opts.once = !!opts.once; }
+ }
+};
+
+// Extend original api defaults
+$.extend(TRUE, QTIP.defaults, {
+ content: {
+ ajax: {
+ loading: TRUE,
+ once: TRUE
+ }
+ }
+});
+
+// Tip coordinates calculator
+function calculateTip(corner, width, height)
+{
+ var width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2),
+
+ // Define tip coordinates in terms of height and width values
+ tips = {
+ bottomright: [[0,0], [width,height], [width,0]],
+ bottomleft: [[0,0], [width,0], [0,height]],
+ topright: [[0,height], [width,0], [width,height]],
+ topleft: [[0,0], [0,height], [width,height]],
+ topcenter: [[0,height], [width2,0], [width,height]],
+ bottomcenter: [[0,0], [width,0], [width2,height]],
+ rightcenter: [[0,0], [width,height2], [0,height]],
+ leftcenter: [[width,0], [width,height], [0,height2]]
+ };
+
+ // Set common side shapes
+ tips.lefttop = tips.bottomright; tips.righttop = tips.bottomleft;
+ tips.leftbottom = tips.topright; tips.rightbottom = tips.topleft;
+
+ return tips[ corner.string() ];
+}
+
+
+function Tip(qTip, command)
+{
+ var self = this,
+ opts = qTip.options.style.tip,
+ elems = qTip.elements,
+ tooltip = elems.tooltip,
+ cache = {
+ top: 0,
+ left: 0,
+ corner: ''
+ },
+ size = {
+ width: opts.width,
+ height: opts.height
+ },
+ color = { },
+ border = opts.border || 0,
+ namespace = '.qtip-tip',
+ hasCanvas = !!($('<canvas />')[0] || {}).getContext;
+
+ self.corner = NULL;
+ self.mimic = NULL;
+ self.border = border;
+ self.offset = opts.offset;
+ self.size = size;
+
+ // Add new option checks for the plugin
+ qTip.checks.tip = {
+ '^position.my|style.tip.(corner|mimic|border)$': function() {
+ // Make sure a tip can be drawn
+ if(!self.init()) {
+ self.destroy();
+ }
+
+ // Reposition the tooltip
+ qTip.reposition();
+ },
+ '^style.tip.(height|width)$': function() {
+ // Re-set dimensions and redraw the tip
+ size = {
+ width: opts.width,
+ height: opts.height
+ };
+ self.create();
+ self.update();
+
+ // Reposition the tooltip
+ qTip.reposition();
+ },
+ '^content.title.text|style.(classes|widget)$': function() {
+ if(elems.tip) {
+ self.update();
+ }
+ }
+ };
+
+ function reposition(event, api, pos, viewport) {
+ if(!elems.tip) { return; }
+
+ var newCorner = $.extend({}, self.corner),
+ adjust = pos.adjusted,
+ method = qTip.options.position.adjust.method.split(' '),
+ horizontal = method[0],
+ vertical = method[1] || method[0],
+ shift = { left: FALSE, top: FALSE, x: 0, y: 0 },
+ offset, css = {}, props;
+
+ // Make sure our tip position isn't fixed e.g. doesn't adjust with viewport
+ if(self.corner.fixed !== TRUE) {
+ // Horizontal - Shift or flip method
+ if(horizontal === 'shift' && newCorner.precedance === 'x' && adjust.left && newCorner.y !== 'center') {
+ newCorner.precedance = newCorner.precedance === 'x' ? 'y' : 'x';
+ }
+ else if(horizontal === 'flip' && adjust.left){
+ newCorner.x = newCorner.x === 'center' ? (adjust.left > 0 ? 'left' : 'right') : (newCorner.x === 'left' ? 'right' : 'left');
+ }
+
+ // Vertical - Shift or flip method
+ if(vertical === 'shift' && newCorner.precedance === 'y' && adjust.top && newCorner.x !== 'center') {
+ newCorner.precedance = newCorner.precedance === 'y' ? 'x' : 'y';
+ }
+ else if(vertical === 'flip' && adjust.top) {
+ newCorner.y = newCorner.y === 'center' ? (adjust.top > 0 ? 'top' : 'bottom') : (newCorner.y === 'top' ? 'bottom' : 'top');
+ }
+
+ // Update and redraw the tip if needed (check cached details of last drawn tip)
+ if(newCorner.string() !== cache.corner && (cache.top !== adjust.top || cache.left !== adjust.left)) {
+ self.update(newCorner, FALSE);
+ }
+ }
+
+ // Setup tip offset properties
+ offset = self.position(newCorner, adjust);
+ if(offset.right !== undefined) { offset.left = -offset.right; }
+ if(offset.bottom !== undefined) { offset.top = -offset.bottom; }
+ offset.user = Math.max(0, opts.offset);
+
+ // Viewport "shift" specific adjustments
+ if(shift.left = (horizontal === 'shift' && !!adjust.left)) {
+ if(newCorner.x === 'center') {
+ css['margin-left'] = shift.x = offset['margin-left'] - adjust.left;
+ }
+ else {
+ props = offset.right !== undefined ?
+ [ adjust.left, -offset.left ] : [ -adjust.left, offset.left ];
+
+ if( (shift.x = Math.max(props[0], props[1])) > props[0] ) {
+ pos.left -= adjust.left;
+ shift.left = FALSE;
+ }
+
+ css[ offset.right !== undefined ? 'right' : 'left' ] = shift.x;
+ }
+ }
+ if(shift.top = (vertical === 'shift' && !!adjust.top)) {
+ if(newCorner.y === 'center') {
+ css['margin-top'] = shift.y = offset['margin-top'] - adjust.top;
+ }
+ else {
+ props = offset.bottom !== undefined ?
+ [ adjust.top, -offset.top ] : [ -adjust.top, offset.top ];
+
+ if( (shift.y = Math.max(props[0], props[1])) > props[0] ) {
+ pos.top -= adjust.top;
+ shift.top = FALSE;
+ }
+
+ css[ offset.bottom !== undefined ? 'bottom' : 'top' ] = shift.y;
+ }
+ }
+
+ /*
+ * If the tip is adjusted in both dimensions, or in a
+ * direction that would cause it to be anywhere but the
+ * outer border, hide it!
+ */
+ elems.tip.css(css).toggle(
+ !((shift.x && shift.y) || (newCorner.x === 'center' && shift.y) || (newCorner.y === 'center' && shift.x))
+ );
+
+ // Adjust position to accomodate tip dimensions
+ pos.left -= offset.left.charAt ? offset.user : horizontal !== 'shift' || shift.top || !shift.left && !shift.top ? offset.left : 0;
+ pos.top -= offset.top.charAt ? offset.user : vertical !== 'shift' || shift.left || !shift.left && !shift.top ? offset.top : 0;
+
+ // Cache details
+ cache.left = adjust.left; cache.top = adjust.top;
+ cache.corner = newCorner.string();
+ }
+
+ /* border width calculator */
+ function borderWidth(corner, side, backup) {
+ side = !side ? corner[corner.precedance] : side;
+
+ var isFluid = tooltip.hasClass(fluidClass),
+ isTitleTop = elems.titlebar && corner.y === 'top',
+ elem = isTitleTop ? elems.titlebar : elems.content,
+ css = 'border-' + side + '-width',
+ val;
+
+ // Grab the border-width value (add fluid class if needed)
+ tooltip.addClass(fluidClass);
+ val = parseInt(elem.css(css), 10);
+ val = (backup ? val || parseInt(tooltip.css(css), 10) : val) || 0;
+ tooltip.toggleClass(fluidClass, isFluid);
+
+ return val;
+ }
+
+ function borderRadius(corner) {
+ var isTitleTop = elems.titlebar && corner.y === 'top',
+ elem = isTitleTop ? elems.titlebar : elems.content,
+ moz = $.browser.mozilla,
+ prefix = moz ? '-moz-' : $.browser.webkit ? '-webkit-' : '',
+ side = corner.y + (moz ? '' : '-') + corner.x,
+ css = prefix + (moz ? 'border-radius-' + side : 'border-' + side + '-radius');
+
+ return parseInt(elem.css(css), 10) || parseInt(tooltip.css(css), 10) || 0;
+ }
+
+ function calculateSize(corner) {
+ var y = corner.precedance === 'y',
+ width = size [ y ? 'width' : 'height' ],
+ height = size [ y ? 'height' : 'width' ],
+ isCenter = corner.string().indexOf('center') > -1,
+ base = width * (isCenter ? 0.5 : 1),
+ pow = Math.pow,
+ round = Math.round,
+ bigHyp, ratio, result,
+
+ smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ),
+
+ hyp = [
+ (border / base) * smallHyp, (border / height) * smallHyp
+ ];
+ hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(border, 2) );
+ hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(border, 2) );
+
+ bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]);
+ ratio = bigHyp / smallHyp;
+
+ result = [ round(ratio * height), round(ratio * width) ];
+ return { height: result[ y ? 0 : 1 ], width: result[ y ? 1 : 0 ] };
+ }
+
+ $.extend(self, {
+ init: function()
+ {
+ var enabled = self.detectCorner() && (hasCanvas || $.browser.msie);
+
+ // Determine tip corner and type
+ if(enabled) {
+ // Create a new tip and draw it
+ self.create();
+ self.update();
+
+ // Bind update events
+ tooltip.unbind(namespace).bind('tooltipmove'+namespace, reposition);
+ }
+
+ return enabled;
+ },
+
+ detectCorner: function()
+ {
+ var corner = opts.corner,
+ posOptions = qTip.options.position,
+ at = posOptions.at,
+ my = posOptions.my.string ? posOptions.my.string() : posOptions.my;
+
+ // Detect corner and mimic properties
+ if(corner === FALSE || (my === FALSE && at === FALSE)) {
+ return FALSE;
+ }
+ else {
+ if(corner === TRUE) {
+ self.corner = new PLUGINS.Corner(my);
+ }
+ else if(!corner.string) {
+ self.corner = new PLUGINS.Corner(corner);
+ self.corner.fixed = TRUE;
+ }
+ }
+
+ return self.corner.string() !== 'centercenter';
+ },
+
+ detectColours: function() {
+ var i, fill, border,
+ tip = elems.tip.css({ backgroundColor: '', border: '' }),
+ corner = self.corner,
+ precedance = corner[ corner.precedance ],
+
+ borderSide = 'border-' + precedance + '-color',
+ borderSideCamel = 'border' + precedance.charAt(0) + precedance.substr(1) + 'Color',
+
+ invalid = /rgba?\(0, 0, 0(, 0)?\)|transparent/i,
+ backgroundColor = 'background-color',
+ transparent = 'transparent',
+
+ bodyBorder = $(document.body).css('color'),
+ contentColour = qTip.elements.content.css('color'),
+
+ useTitle = elems.titlebar && (corner.y === 'top' || (corner.y === 'center' && tip.position().top + (size.height / 2) + opts.offset < elems.titlebar.outerHeight(1))),
+ colorElem = useTitle ? elems.titlebar : elems.content;
+
+ // Apply the fluid class so we can see our CSS values properly
+ tooltip.addClass(fluidClass);
+
+ // Detect tip colours from CSS styles
+ color.fill = fill = tip.css(backgroundColor);
+ color.border = border = tip[0].style[ borderSideCamel ] || tip.css(borderSide) || tooltip.css(borderSide);
+
+ // Make sure colours are valid
+ if(!fill || invalid.test(fill)) {
+ color.fill = colorElem.css(backgroundColor) || transparent;
+ if(invalid.test(color.fill)) {
+ color.fill = tooltip.css(backgroundColor) || fill;
+ }
+ }
+ if(!border || invalid.test(border) || border === bodyBorder) {
+ color.border = colorElem.css(borderSide) || transparent;
+ if(invalid.test(color.border) || color.border === contentColour) {
+ color.border = border;
+ }
+ }
+
+ // Reset background and border colours
+ $('*', tip).add(tip).css(backgroundColor, transparent).css('border', '');
+
+ // Remove fluid class
+ tooltip.removeClass(fluidClass);
+ },
+
+ create: function()
+ {
+ var width = size.width,
+ height = size.height,
+ vml;
+
+ // Remove previous tip element if present
+ if(elems.tip) { elems.tip.remove(); }
+
+ // Create tip element and prepend to the tooltip
+ elems.tip = $('<div />', { 'class': 'ui-tooltip-tip' }).css({ width: width, height: height }).prependTo(tooltip);
+
+ // Create tip drawing element(s)
+ if(hasCanvas) {
+ // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()!
+ $('<canvas />').appendTo(elems.tip)[0].getContext('2d').save();
+ }
+ else {
+ vml = '<vml:shape coordorigin="0,0" style="display:inline-block; position:absolute; behavior:url(#default#VML);"></vml:shape>';
+ elems.tip.html(vml + vml);
+ }
+ },
+
+ update: function(corner, position)
+ {
+ var tip = elems.tip,
+ inner = tip.children(),
+ width = size.width,
+ height = size.height,
+ regular = 'px solid ',
+ transparent = 'px dashed transparent', // Dashed IE6 border-transparency hack. Awesome!
+ mimic = opts.mimic,
+ round = Math.round,
+ precedance, context, coords, translate, newSize;
+
+ // Re-determine tip if not already set
+ if(!corner) { corner = self.corner; }
+
+ // Use corner property if we detect an invalid mimic value
+ if(mimic === FALSE) { mimic = corner; }
+
+ // Otherwise inherit mimic properties from the corner object as necessary
+ else {
+ mimic = new PLUGINS.Corner(mimic);
+ mimic.precedance = corner.precedance;
+
+ if(mimic.x === 'inherit') { mimic.x = corner.x; }
+ else if(mimic.y === 'inherit') { mimic.y = corner.y; }
+ else if(mimic.x === mimic.y) {
+ mimic[ corner.precedance ] = corner[ corner.precedance ];
+ }
+ }
+ precedance = mimic.precedance;
+
+ // Update our colours
+ self.detectColours();
+
+ // Detect border width, taking into account colours
+ if(color.border !== 'transparent' && color.border !== '#123456') {
+ // Grab border width
+ border = borderWidth(corner, NULL, TRUE);
+
+ // If border width isn't zero, use border color as fill (1.0 style tips)
+ if(opts.border === 0 && border > 0) { color.fill = color.border; }
+
+ // Set border width (use detected border width if opts.border is true)
+ self.border = border = opts.border !== TRUE ? opts.border : border;
+ }
+
+ // Border colour was invalid, set border to zero
+ else { self.border = border = 0; }
+
+ // Calculate coordinates
+ coords = calculateTip(mimic, width , height);
+
+ // Determine tip size
+ self.size = newSize = calculateSize(corner);
+ tip.css(newSize);
+
+ // Calculate tip translation
+ if(corner.precedance === 'y') {
+ translate = [
+ round(mimic.x === 'left' ? border : mimic.x === 'right' ? newSize.width - width - border : (newSize.width - width) / 2),
+ round(mimic.y === 'top' ? newSize.height - height : 0)
+ ];
+ }
+ else {
+ translate = [
+ round(mimic.x === 'left' ? newSize.width - width : 0),
+ round(mimic.y === 'top' ? border : mimic.y === 'bottom' ? newSize.height - height - border : (newSize.height - height) / 2)
+ ];
+ }
+
+ // Canvas drawing implementation
+ if(hasCanvas) {
+ // Set the canvas size using calculated size
+ inner.attr(newSize);
+
+ // Grab canvas context and clear/save it
+ context = inner[0].getContext('2d');
+ context.restore(); context.save();
+ context.clearRect(0,0,3000,3000);
+
+ // Translate origin
+ context.translate(translate[0], translate[1]);
+
+ // Draw the tip
+ context.beginPath();
+ context.moveTo(coords[0][0], coords[0][1]);
+ context.lineTo(coords[1][0], coords[1][1]);
+ context.lineTo(coords[2][0], coords[2][1]);
+ context.closePath();
+ context.fillStyle = color.fill;
+ context.strokeStyle = color.border;
+ context.lineWidth = border * 2;
+ context.lineJoin = 'miter';
+ context.miterLimit = 100;
+ if(border) { context.stroke(); }
+ context.fill();
+ }
+
+ // VML (IE Proprietary implementation)
+ else {
+ // Setup coordinates string
+ coords = 'm' + coords[0][0] + ',' + coords[0][1] + ' l' + coords[1][0] +
+ ',' + coords[1][1] + ' ' + coords[2][0] + ',' + coords[2][1] + ' xe';
+
+ // Setup VML-specific offset for pixel-perfection
+ translate[2] = border && /^(r|b)/i.test(corner.string()) ?
+ parseFloat($.browser.version, 10) === 8 ? 2 : 1 : 0;
+
+ // Set initial CSS
+ inner.css({
+ antialias: ''+(mimic.string().indexOf('center') > -1),
+ left: translate[0] - (translate[2] * Number(precedance === 'x')),
+ top: translate[1] - (translate[2] * Number(precedance === 'y')),
+ width: width + border,
+ height: height + border
+ })
+ .each(function(i) {
+ var $this = $(this);
+
+ // Set shape specific attributes
+ $this[ $this.prop ? 'prop' : 'attr' ]({
+ coordsize: (width+border) + ' ' + (height+border),
+ path: coords,
+ fillcolor: color.fill,
+ filled: !!i,
+ stroked: !!!i
+ })
+ .css({ display: border || i ? 'block' : 'none' });
+
+ // Check if border is enabled and add stroke element
+ if(!i && $this.html() === '') {
+ $this.html(
+ '<vml:stroke weight="'+(border*2)+'px" color="'+color.border+'" miterlimit="1000" joinstyle="miter" ' +
+ ' style="behavior:url(#default#VML); display:inline-block;" />'
+ );
+ }
+ });
+ }
+
+ // Position if needed
+ if(position !== FALSE) { self.position(corner); }
+ },
+
+ // Tip positioning method
+ position: function(corner)
+ {
+ var tip = elems.tip,
+ position = {},
+ userOffset = Math.max(0, opts.offset),
+ precedance, dimensions, corners;
+
+ // Return if tips are disabled or tip is not yet rendered
+ if(opts.corner === FALSE || !tip) { return FALSE; }
+
+ // Inherit corner if not provided
+ corner = corner || self.corner;
+ precedance = corner.precedance;
+
+ // Determine which tip dimension to use for adjustment
+ dimensions = calculateSize(corner);
+
+ // Setup corners and offset array
+ corners = [ corner.x, corner.y ];
+ if(precedance === 'x') { corners.reverse(); }
+
+ // Calculate tip position
+ $.each(corners, function(i, side) {
+ var b, br;
+
+ if(side === 'center') {
+ b = precedance === 'y' ? 'left' : 'top';
+ position[ b ] = '50%';
+ position['margin-' + b] = -Math.round(dimensions[ precedance === 'y' ? 'width' : 'height' ] / 2) + userOffset;
+ }
+ else {
+ b = borderWidth(corner, side, TRUE);
+ br = borderRadius(corner);
+
+ position[ side ] = i ?
+ border ? borderWidth(corner, side) : 0 :
+ userOffset + (br > b ? br : 0);
+ }
+ });
+
+ // Adjust for tip dimensions
+ position[ corner[precedance] ] -= dimensions[ precedance === 'x' ? 'width' : 'height' ];
+
+ // Set and return new position
+ tip.css({ top: '', bottom: '', left: '', right: '', margin: '' }).css(position);
+ return position;
+ },
+
+ destroy: function()
+ {
+ // Remov tip and bound events
+ if(elems.tip) { elems.tip.remove(); }
+ tooltip.unbind(namespace);
+ }
+ });
+
+ self.init();
+}
+
+PLUGINS.tip = function(api)
+{
+ var self = api.plugins.tip;
+
+ return 'object' === typeof self ? self : (api.plugins.tip = new Tip(api));
+};
+
+// Initialize tip on render
+PLUGINS.tip.initialize = 'render';
+
+// Setup plugin sanitization options
+PLUGINS.tip.sanitize = function(options)
+{
+ var style = options.style, opts;
+ if(style && 'tip' in style) {
+ opts = options.style.tip;
+ if(typeof opts !== 'object'){ options.style.tip = { corner: opts }; }
+ if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; }
+ if(typeof opts.width !== 'number'){ delete opts.width; }
+ if(typeof opts.height !== 'number'){ delete opts.height; }
+ if(typeof opts.border !== 'number' && opts.border !== TRUE){ delete opts.border; }
+ if(typeof opts.offset !== 'number'){ delete opts.offset; }
+ }
+};
+
+// Extend original qTip defaults
+$.extend(TRUE, QTIP.defaults, {
+ style: {
+ tip: {
+ corner: TRUE,
+ mimic: FALSE,
+ width: 6,
+ height: 6,
+ border: TRUE,
+ offset: 0
+ }
+ }
+});
+
+/*
+ * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe)
+ * Special thanks to Brandon Aaron
+ */
+function BGIFrame(api)
+{
+ var self = this,
+ elems = api.elements,
+ tooltip = elems.tooltip,
+ namespace = '.bgiframe-' + api.id;
+
+ $.extend(self, {
+ init: function()
+ {
+ // Create the BGIFrame element
+ elems.bgiframe = $('<iframe class="ui-tooltip-bgiframe" frameborder="0" tabindex="-1" src="javascript:\'\';" ' +
+ ' style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=0); ' +
+ '-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";"></iframe>');
+
+ // Append the new element to the tooltip
+ elems.bgiframe.appendTo(tooltip);
+
+ // Update BGIFrame on tooltip move
+ tooltip.bind('tooltipmove'+namespace, self.adjust);
+ },
+
+ adjust: function()
+ {
+ var dimensions = api.get('dimensions'), // Determine current tooltip dimensions
+ plugin = api.plugins.tip,
+ tip = elems.tip,
+ tipAdjust, offset;
+
+ // Adjust border offset
+ offset = parseInt(tooltip.css('border-left-width'), 10) || 0;
+ offset = { left: -offset, top: -offset };
+
+ // Adjust for tips plugin
+ if(plugin && tip) {
+ tipAdjust = (plugin.corner.precedance === 'x') ? ['width', 'left'] : ['height', 'top'];
+ offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ]();
+ }
+
+ // Update bgiframe
+ elems.bgiframe.css(offset).css(dimensions);
+ },
+
+ destroy: function()
+ {
+ // Remove iframe
+ elems.bgiframe.remove();
+
+ // Remove bound events
+ tooltip.unbind(namespace);
+ }
+ });
+
+ self.init();
+}
+
+PLUGINS.bgiframe = function(api)
+{
+ var browser = $.browser,
+ self = api.plugins.bgiframe;
+
+ // Proceed only if the browser is IE6 and offending elements are present
+ if($('select, object').length < 1 || !(browser.msie && browser.version.charAt(0) === '6')) {
+ return FALSE;
+ }
+
+ return 'object' === typeof self ? self : (api.plugins.bgiframe = new BGIFrame(api));
+};
+
+// Plugin needs to be initialized on render
+PLUGINS.bgiframe.initialize = 'render';
+
+
+}(jQuery, window));
Property changes on: platform\inc\jquery\qtip\jquery.qtip.js
___________________________________________________________________
Added: svn:eol-style
+ LF
Index: platform/inc/jquery/qtip/jquery.qtip.min.js
===================================================================
--- platform/inc/jquery/qtip/jquery.qtip.min.js (revision 0)
+++ platform/inc/jquery/qtip/jquery.qtip.min.js (revision 0)
@@ -0,0 +1,13 @@
+/*
+* qTip2 - Pretty powerful tooltips
+* http://craigsworks.com/projects/qtip2/
+*
+* Version: nightly
+* Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com
+*
+* Dual licensed under MIT or GPLv2 licenses
+* http://en.wikipedia.org/wiki/MIT_License
+* http://en.wikipedia.org/wiki/GNU_General_Public_License
+*
+* Date: Sun Aug 14 05:10:00 PDT 2011
+*//*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true *//*global window: false, jQuery: false, console: false */(function(a,b,c){function D(b){var c=this,d=b.elements,e=d.tooltip,f=".bgiframe-"+b.id;a.extend(c,{init:function(){d.bgiframe=a('<iframe class="ui-tooltip-bgiframe" frameborder="0" tabindex="-1" src="javascript:\'\';" style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=0); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";"></iframe>'),d.bgiframe.appendTo(e),e.bind("tooltipmove"+f,c.adjust)},adjust:function(){var a=b.get("dimensions"),c=b.plugins.tip,f=d.tip,g,h;h=parseInt(e.css("border-left-width"),10)||0,h={left:-h,top:-h},c&&f&&(g=c.corner.precedance==="x"?["width","left"]:["height","top"],h[g[1]]-=f[g[0]]()),d.bgiframe.css(h).css(a)},destroy:function(){d.bgiframe.remove(),e.unbind(f)}}),c.init()}function C(b,g){function w(a){var b=a.precedance==="y",c=n[b?"width":"height"],d=n[b?"height":"width"],e=a.string().indexOf("center")>-1,f=c*(e?.5:1),g=Math.pow,h=Math.round,i,j,k,l=Math.sqrt(g(f,2)+g(d,2)),m=[p/f*l,p/d*l];m[2]=Math.sqrt(g(m[0],2)-g(p,2)),m[3]=Math.sqrt(g(m[1],2)-g(p,2)),i=l+m[2]+m[3]+(e?0:m[0]),j=i/l,k=[h(j*d),h(j*c)];return{height:k[b?0:1],width:k[b?1:0]}}function v(b){var c=k.titlebar&&b.y==="top",d=c?k.titlebar:k.content,e=a.browser.mozilla,f=e?"-moz-":a.browser.webkit?"-webkit-":"",g=b.y+(e?"":"-")+b.x,h=f+(e?"border-radius-"+g:"border-"+g+"-radius");return parseInt(d.css(h),10)||parseInt(l.css(h),10)||0}function u(a,b,c){b=b?b:a[a.precedance];var d=l.hasClass(r),e=k.titlebar&&a.y==="top",f=e?k.titlebar:k.content,g="border-"+b+"-width",h;l.addClass(r),h=parseInt(f.css(g),10),h=(c?h||parseInt(l.css(g),10):h)||0,l.toggleClass(r,d);return h}function t(f,g,h,l){if(k.tip){var n=a.extend({},i.corner),o=h.adjusted,p=b.options.position.adjust.method.split(" "),q=p[0],r=p[1]||p[0],s={left:e,top:e,x:0,y:0},t,u={},v;i.corner.fixed!==d&&(q==="shift"&&n.precedance==="x"&&o.left&&n.y!=="center"?n.precedance=n.precedance==="x"?"y":"x":q==="flip"&&o.left&&(n.x=n.x==="center"?o.left>0?"left":"right":n.x==="left"?"right":"left"),r==="shift"&&n.precedance==="y"&&o.top&&n.x!=="center"?n.precedance=n.precedance==="y"?"x":"y":r==="flip"&&o.top&&(n.y=n.y==="center"?o.top>0?"top":"bottom":n.y==="top"?"bottom":"top"),n.string()!==m.corner&&(m.top!==o.top||m.left!==o.left)&&i.update(n,e)),t=i.position(n,o),t.right!==c&&(t.left=-t.right),t.bottom!==c&&(t.top=-t.bottom),t.user=Math.max(0,j.offset);if(s.left=q==="shift"&&!!o.left)n.x==="center"?u["margin-left"]=s.x=t["margin-left"]-o.left:(v=t.right!==c?[o.left,-t.left]:[-o.left,t.left],(s.x=Math.max(v[0],v[1]))>v[0]&&(h.left-=o.left,s.left=e),u[t.right!==c?"right":"left"]=s.x);if(s.top=r==="shift"&&!!o.top)n.y==="center"?u["margin-top"]=s.y=t["margin-top"]-o.top:(v=t.bottom!==c?[o.top,-t.top]:[-o.top,t.top],(s.y=Math.max(v[0],v[1]))>v[0]&&(h.top-=o.top,s.top=e),u[t.bottom!==c?"bottom":"top"]=s.y);k.tip.css(u).toggle(!(s.x&&s.y||n.x==="center"&&s.y||n.y==="center"&&s.x)),h.left-=t.left.charAt?t.user:q!=="shift"||s.top||!s.left&&!s.top?t.left:0,h.top-=t.top.charAt?t.user:r!=="shift"||s.left||!s.left&&!s.top?t.top:0,m.left=o.left,m.top=o.top,m.corner=n.string()}}var i=this,j=b.options.style.tip,k=b.elements,l=k.tooltip,m={top:0,left:0,corner:""},n={width:j.width,height:j.height},o={},p=j.border||0,q=".qtip-tip",s=!!(a("<canvas />")[0]||{}).getContext;i.corner=f,i.mimic=f,i.border=p,i.offset=j.offset,i.size=n,b.checks.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){i.init()||i.destroy(),b.reposition()},"^style.tip.(height|width)$":function(){n={width:j.width,height:j.height},i.create(),i.update(),b.reposition()},"^content.title.text|style.(classes|widget)$":function(){k.tip&&i.update()}},a.extend(i,{init:function(){var b=i.detectCorner()&&(s||a.browser.msie);b&&(i.create(),i.update(),l.unbind(q).bind("tooltipmove"+q,t));return b},detectCorner:function(){var a=j.corner,c=b.options.position,f=c.at,g=c.my.string?c.my.string():c.my;if(a===e||g===e&&f===e)return e;a===d?i.corner=new h.Corner(g):a.string||(i.corner=new h.Corner(a),i.corner.fixed=d);return i.corner.string()!=="centercenter"},detectColours:function(){var c,d,e,f=k.tip.css({backgroundColor:"",border:""}),g=i.corner,h=g[g.precedance],m="border-"+h+"-color",p="border"+h.charAt(0)+h.substr(1)+"Color",q=/rgba?\(0, 0, 0(, 0)?\)|transparent/i,s="background-color",t="transparent",u=a(document.body).css("color"),v=b.elements.content.css("color"),w=k.titlebar&&(g.y==="top"||g.y==="center"&&f.position().top+n.height/2+j.offset<k.titlebar.outerHeight(1)),x=w?k.titlebar:k.content;l.addClass(r),o.fill=d=f.css(s),o.border=e=f[0].style[p]||f.css(m)||l.css(m);if(!d||q.test(d))o.fill=x.css(s)||t,q.test(o.fill)&&(o.fill=l.css(s)||d);if(!e||q.test(e)||e===u){o.border=x.css(m)||t;if(q.test(o.border)||o.border===v)o.border=e}a("*",f).add(f).css(s,t).css("border",""),l.removeClass(r)},create:function(){var b=n.width,c=n.height,d;k.tip&&k.tip.remove(),k.tip=a("<div />",{"class":"ui-tooltip-tip"}).css({width:b,height:c}).prependTo(l),s?a("<canvas />").appendTo(k.tip)[0].getContext("2d").save():(d='<vml:shape coordorigin="0,0" style="display:inline-block; position:absolute; behavior:url(#default#VML);"></vml:shape>',k.tip.html(d+d))},update:function(b,c){var g=k.tip,l=g.children(),m=n.width,q=n.height,r="px solid ",t="px dashed transparent",v=j.mimic,x=Math.round,y,z,A,C,D;b||(b=i.corner),v===e?v=b:(v=new h.Corner(v),v.precedance=b.precedance,v.x==="inherit"?v.x=b.x:v.y==="inherit"?v.y=b.y:v.x===v.y&&(v[b.precedance]=b[b.precedance])),y=v.precedance,i.detectColours(),o.border!=="transparent"&&o.border!=="#123456"?(p=u(b,f,d),j.border===0&&p>0&&(o.fill=o.border),i.border=p=j.border!==d?j.border:p):i.border=p=0,A=B(v,m,q),i.size=D=w(b),g.css(D),b.precedance==="y"?C=[x(v.x==="left"?p:v.x==="right"?D.width-m-p:(D.width-m)/2),x(v.y==="top"?D.height-q:0)]:C=[x(v.x==="left"?D.width-m:0),x(v.y==="top"?p:v.y==="bottom"?D.height-q-p:(D.height-q)/2)],s?(l.attr(D),z=l[0].getContext("2d"),z.restore(),z.save(),z.clearRect(0,0,3e3,3e3),z.translate(C[0],C[1]),z.beginPath(),z.moveTo(A[0][0],A[0][1]),z.lineTo(A[1][0],A[1][1]),z.lineTo(A[2][0],A[2][1]),z.closePath(),z.fillStyle=o.fill,z.strokeStyle=o.border,z.lineWidth=p*2,z.lineJoin="miter",z.miterLimit=100,p&&z.stroke(),z.fill()):(A="m"+A[0][0]+","+A[0][1]+" l"+A[1][0]+","+A[1][1]+" "+A[2][0]+","+A[2][1]+" xe",C[2]=p&&/^(r|b)/i.test(b.string())?parseFloat(a.browser.version,10)===8?2:1:0,l.css({antialias:""+(v.string().indexOf("center")>-1),left:C[0]-C[2]*Number(y==="x"),top:C[1]-C[2]*Number(y==="y"),width:m+p,height:q+p}).each(function(b){var c=a(this);c[c.prop?"prop":"attr"]({coordsize:m+p+" "+(q+p),path:A,fillcolor:o.fill,filled:!!b,stroked:!b}).css({display:p||b?"block":"none"}),!b&&c.html()===""&&c.html('<vml:stroke weight="'+p*2+'px" color="'+o.border+'" miterlimit="1000" joinstyle="miter" style="behavior:url(#default#VML); display:inline-block;" />')})),c!==e&&i.position(b)},position:function(b){var c=k.tip,f={},g=Math.max(0,j.offset),h,l,m;if(j.corner===e||!c)return e;b=b||i.corner,h=b.precedance,l=w(b),m=[b.x,b.y],h==="x"&&m.reverse(),a.each(m,function(a,c){var e,i;c==="center"?(e=h==="y"?"left":"top",f[e]="50%",f["margin-"+e]=-Math.round(l[h==="y"?"width":"height"]/2)+g):(e=u(b,c,d),i=v(b),f[c]=a?p?u(b,c):0:g+(i>e?i:0))}),f[b[h]]-=l[h==="x"?"width":"height"],c.css({top:"",bottom:"",left:"",right:"",margin:""}).css(f);return f},destroy:function(){k.tip&&k.tip.remove(),l.unbind(q)}}),i.init()}function B(a,b,c){var d=Math.ceil(b/2),e=Math.ceil(c/2),f={bottomright:[[0,0],[b,c],[b,0]],bottomleft:[[0,0],[b,0],[0,c]],topright:[[0,c],[b,0],[b,c]],topleft:[[0,0],[0,c],[b,c]],topcenter:[[0,c],[d,0],[b,c]],bottomcenter:[[0,0],[b,0],[d,c]],rightcenter:[[0,0],[b,e],[0,c]],leftcenter:[[b,0],[b,c],[0,e]]};f.lefttop=f.bottomright,f.righttop=f.bottomleft,f.leftbottom=f.topright,f.rightbottom=f.topleft;return f[a.string()]}function A(b){var c=this,f=b.elements.tooltip,g=b.options.content.ajax,h=".qtip-ajax",i=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,j=d;b.checks.ajax={"^content.ajax":function(a,b,d){b==="ajax"&&(g=d),b==="once"?c.init():g&&g.url?c.load():f.unbind(h)}},a.extend(c,{init:function(){g&&g.url&&f.unbind(h)[g.once?"one":"bind"]("tooltipshow"+h,c.load);return c},load:function(d,h){function p(a,c,d){b.set("content.text",c+": "+d)}function o(c){l&&(c=a("<div/>").append(c.replace(i,"")).find(l)),b.set("content.text",c)}function n(){m&&(f.css("visibility",""),h=e),a.isFunction(g.complete)&&g.complete.apply(this,arguments)}if(d&&d.isDefaultPrevented())return c;var j=g.url.indexOf(" "),k=g.url,l,m=g.once&&!g.loading&&h;m&&f.css("visibility","hidden"),j>-1&&(l=k.substr(j),k=k.substr(0,j)),a.ajax(a.extend({success:o,error:p,context:b},g,{url:k,complete:n}));return c}}),c.init()}function z(b,c){var i,j,k,l,m,n=a(this),o=a(document.body),p=this===document?o:n,q=n.metadata?n.metadata(c.metadata):f,r=c.metadata.type==="html5"&&q?q[c.metadata.name]:f,s=n.data(c.metadata.name||"qtipopts");try{s=typeof s==="string"?(new Function("return "+s))():s}catch(t){w("Unable to parse HTML5 attribute data: "+s)}l=a.extend(d,{},g.defaults,c,typeof s==="object"?x(s):f,x(r||q)),j=l.position,l.id=b;if("boolean"===typeof l.content.text){k=n.attr(l.content.attr);if(l.content.attr!==e&&k)l.content.text=k;else{w("Unable to locate content for tooltip! Aborting render of tooltip on element: ",n);return e}}j.container===e&&(j.container=o),j.target===e&&(j.target=p),l.show.target===e&&(l.show.target=p),l.show.solo===d&&(l.show.solo=o),l.hide.target===e&&(l.hide.target=p),l.position.viewport===d&&(l.position.viewport=j.container),j.at=new h.Corner(j.at),j.my=new h.Corner(j.my);if(a.data(this,"qtip"))if(l.overwrite)n.qtip("destroy");else if(l.overwrite===e)return e;l.suppress&&(m=a.attr(this,"title"))&&a(this).removeAttr("title").attr(u,m),i=new y(n,l,b,!!k),a.data(this,"qtip",i),n.bind("remove.qtip",function(){i.destroy()});return i}function y(s,t,w,y){function R(){var c=[t.show.target[0],t.hide.target[0],z.rendered&&G.tooltip[0],t.position.container[0],t.position.viewport[0],b,document];z.rendered?a([]).pushStack(a.grep(c,function(a){return typeof a==="object"})).unbind(F):t.show.target.unbind(F+"-create")}function Q(){function p(a){E.is(":visible")&&z.reposition(a)}function o(a){if(E.hasClass(m))return e;clearTimeout(z.timers.inactive),z.timers.inactive=setTimeout(function(){z.hide(a)},t.hide.inactive)}function l(b){if(E.hasClass(m)||C||D)return e;var d=a(b.relatedTarget||b.target),g=d.closest(n)[0]===E[0],h=d[0]===f.show[0];clearTimeout(z.timers.show),clearTimeout(z.timers.hide);c.target==="mouse"&&g||t.hide.fixed&&(/mouse(out|leave|move)/.test(b.type)&&(g||h))?(b.preventDefault(),b.stopImmediatePropagation()):t.hide.delay>0?z.timers.hide=setTimeout(function(){z.hide(b)},t.hide.delay):z.hide(b)}function k(a){if(E.hasClass(m))return e;f.show.trigger("qtip-"+w+"-inactive"),clearTimeout(z.timers.show),clearTimeout(z.timers.hide);var b=function(){z.toggle(d,a)};t.show.delay>0?z.timers.show=setTimeout(b,t.show.delay):b()}var c=t.position,f={show:t.show.target,hide:t.hide.target,viewport:a(c.viewport),document:a(document),window:a(b)},h={show:a.trim(""+t.show.event).split(" "),hide:a.trim(""+t.hide.event).split(" ")},j=a.browser.msie&&parseInt(a.browser.version,10)===6;E.bind("mouseenter"+F+" mouseleave"+F,function(a){var b=a.type==="mouseenter";b&&z.focus(a),E.toggleClass(q,b)}),t.hide.fixed&&(f.hide=f.hide.add(E),E.bind("mouseover"+F,function(){E.hasClass(m)||clearTimeout(z.timers.hide)})),/mouse(out|leave)/i.test(t.hide.event)?t.hide.leave==="window"&&f.window.bind("mouseout"+F,function(a){/select|option/.test(a.target)&&!a.relatedTarget&&z.hide(a)}):/mouse(over|enter)/i.test(t.show.event)&&f.hide.bind("mouseleave"+F,function(a){clearTimeout(z.timers.show)}),(""+t.hide.event).indexOf("unfocus")>-1&&f.document.bind("mousedown"+F,function(b){var c=a(b.target),d=!E.hasClass(m)&&E.is(":visible");c[0]!==E[0]&&c.parents(n).length===0&&c.add(s).length>1&&z.hide(b)}),"number"===typeof t.hide.inactive&&(f.show.bind("qtip-"+w+"-inactive",o),a.each(g.inactiveEvents,function(a,b){f.hide.add(G.tooltip).bind(b+F+"-inactive",o)})),a.each(h.hide,function(b,c){var d=a.inArray(c,h.show),e=a(f.hide);d>-1&&e.add(f.show).length===e.length||c==="unfocus"?(f.show.bind(c+F,function(a){E.is(":visible")?l(a):k(a)}),delete h.show[d]):f.hide.bind(c+F,l)}),a.each(h.show,function(a,b){f.show.bind(b+F,k)}),"number"===typeof t.hide.distance&&f.show.add(E).bind("mousemove"+F,function(a){var b=H.origin||{},c=t.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&z.hide(a)}),c.target==="mouse"&&(f.show.bind("mousemove"+F,function(a){i={pageX:a.pageX,pageY:a.pageY,type:"mousemove"}}),c.adjust.mouse&&(t.hide.event&&E.bind("mouseleave"+F,function(a){(a.relatedTarget||a.target)!==f.show[0]&&z.hide(a)}),f.document.bind("mousemove"+F,function(a){!E.hasClass(m)&&E.is(":visible")&&z.reposition(a||i)}))),(c.adjust.resize||f.viewport.length)&&(a.event.special.resize?f.viewport:f.window).bind("resize"+F,p),(f.viewport.length||j&&E.css("position")==="fixed")&&f.viewport.bind("scroll"+F,p)}function P(b,d){function g(b){function i(c){c&&(delete h[c.src],clearTimeout(z.timers.img[c.src]),a(c).unbind(F)),a.isEmptyObject(h)&&(z.redraw(),d!==e&&z.reposition(H.event),b())}var g,h={};if((g=f.find("img:not([height]):not([width])")).length===0)return i();g.each(function(b,d){h[d.src]===c&&(function e(){if(d.height||d.width)return i(d);z.timers.img[d.src]=setTimeout(e,700)}(),a(d).bind("error"+F+" load"+F,function(){i(this)}),h[d.src]=d)})}var f=G.content;if(!z.rendered||!b)return e;a.isFunction(b)&&(b=b.call(s,H.event,z)||""),b.jquery&&b.length>0?f.empty().append(b.css({display:"block"})):f.html(b),z.rendered<0?E.queue("fx",g):(D=0,g(a.noop));return z}function O(b,c){var d=G.title;if(!z.rendered||!b)return e;a.isFunction(b)&&(b=b.call(s,H.event,z));if(b===e)return K(e);b.jquery&&b.length>0?d.empty().append(b.css({display:"block"})):d.html(b),z.redraw(),c!==e&&z.rendered&&E.is(":visible")&&z.reposition(H.event)}function N(a){var b=G.button,c=G.title;if(!z.rendered)return e;a?(c||M(),L()):b.remove()}function M(){var b=B+"-title";G.titlebar&&K(),G.titlebar=a("<div />",{"class":k+"-titlebar "+(t.style.widget?"ui-widget-header":"")}).append(G.title=a("<div />",{id:b,"class":k+"-title","aria-atomic":d})).insertBefore(G.content),t.content.title.button?L():z.rendered&&z.redraw()}function L(){var b=t.content.title.button,c=typeof b==="string",d=c?b:"Close tooltip";G.button&&G.button.remove(),b.jquery?G.button=b:G.button=a("<a />",{"class":"ui-state-default "+(t.style.widget?"":k+"-icon"),title:d,"aria-label":d}).prepend(a("<span />",{"class":"ui-icon ui-icon-close",html:"×"})),G.button.appendTo(G.titlebar).attr("role","button").hover(function(b){a(this).toggleClass("ui-state-hover",b.type==="mouseenter")}).click(function(a){E.hasClass(m)||z.hide(a);return e}).bind("mousedown keydown mouseup keyup mouseout",function(b){a(this).toggleClass("ui-state-active ui-state-focus",b.type.substr(-4)==="down")}),z.redraw()}function K(a){G.title&&(G.titlebar.remove(),G.titlebar=G.title=G.button=f,a!==e&&z.reposition())}function J(){var a=t.style.widget;E.toggleClass(l,a).toggleClass(o,!a),G.content.toggleClass(l+"-content",a),G.titlebar&&G.titlebar.toggleClass(l+"-header",a),G.button&&G.button.toggleClass(k+"-icon",!a)}function I(a){var b=0,c,d=t,e=a.split(".");while(d=d[e[b++]])b<e.length&&(c=d);return[c||t,e.pop()]}var z=this,A=document.body,B=k+"-"+w,C=0,D=0,E=a(),F=".qtip-"+w,G,H;z.id=w,z.rendered=e,z.elements=G={target:s},z.timers={img:{}},z.options=t,z.checks={},z.plugins={},z.cache=H={event:{},target:a(),disabled:e,attr:y},z.checks.builtin={"^id$":function(b,c,f){var h=f===d?g.nextid:f,i=k+"-"+h;h!==e&&h.length>0&&!a("#"+i).length&&(E[0].id=i,G.content[0].id=i+"-content",G.title[0].id=i+"-title")},"^content.text$":function(a,b,c){P(c)},"^content.title.text$":function(a,b,c){if(!c)return K();!G.title&&c&&M(),O(c)},"^content.title.button$":function(a,b,c){N(c)},"^position.(my|at)$":function(a,b,c){"string"===typeof c&&(a[b]=new h.Corner(c))},"^position.container$":function(a,b,c){z.rendered&&E.appendTo(c)},"^show.ready$":function(){z.rendered?z.toggle(d):z.render(1)},"^style.classes$":function(a,b,c){E.attr("class",k+" qtip ui-helper-reset "+c)},"^style.widget|content.title":J,"^events.(render|show|move|hide|focus|blur)$":function(b,c,d){E[(a.isFunction(d)?"":"un")+"bind"]("tooltip"+c,d)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){var a=t.position;E.attr("tracking",a.target==="mouse"&&a.adjust.mouse),R(),Q()}},a.extend(z,{render:function(b){if(z.rendered)return z;var c=t.content.title.text,f=t.position,g=a.Event("tooltiprender");a.attr(s[0],"aria-describedby",B),E=G.tooltip=a("<div/>",{id:B,"class":k+" qtip ui-helper-reset "+o+" "+t.style.classes,width:t.style.width||"",height:t.style.height||"",tracking:f.target==="mouse"&&f.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":e,"aria-describedby":B+"-content","aria-hidden":d}).toggleClass(m,H.disabled).data("qtip",z).appendTo(t.position.container).append(G.content=a("<div />",{"class":k+"-content",id:B+"-content","aria-atomic":d})),z.rendered=-1,D=1,C=1,c&&(M(),O(c,e)),P(t.content.text,e),z.rendered=d,J(),a.each(t.events,function(b,c){a.isFunction(c)&&E.bind(b==="toggle"?"tooltipshow tooltiphide":"tooltip"+b,c)}),a.each(h,function(){this.initialize==="render"&&this(z)}),Q(),E.queue("fx",function(a){g.originalEvent=H.event,E.trigger(g,[z]),D=0,C=0,z.redraw(),(t.show.ready||b)&&z.toggle(d,H.event),a()});return z},get:function(a){var b,c;switch(a.toLowerCase()){case"dimensions":b={height:E.outerHeight(),width:E.outerWidth()};break;case"offset":b=h.offset(E,t.position.container);break;default:c=I(a.toLowerCase()),b=c[0][c[1]],b=b.precedance?b.string():b}return b},set:function(b,c){function m(a,b){var c,d,e;for(c in k)for(d in k[c])if(e=(new RegExp(d,"i")).exec(a))b.push(e),k[c][d].apply(z,b)}var g=/^position\.(my|at|adjust|target|container)|style|content|show\.ready/i,h=/^content\.(title|attr)|style/i,i=e,j=e,k=z.checks,l;"string"===typeof b?(l=b,b={},b[l]=c):b=a.extend(d,{},b),a.each(b,function(c,d){var e=I(c.toLowerCase()),f;f=e[0][e[1]],e[0][e[1]]="object"===typeof d&&d.nodeType?a(d):d,b[c]=[e[0],e[1],d,f],i=g.test(c)||i,j=h.test(c)||j}),x(t),C=D=1,a.each(b,m),C=D=0,E.is(":visible")&&z.rendered&&(i&&z.reposition(t.position.target==="mouse"?f:H.event),j&&z.redraw());return z},toggle:function(b,c){function q(){b?(a.browser.msie&&E[0].style.removeAttribute("filter"),E.css("overflow",""),"string"===typeof h.autofocus&&a(h.autofocus,E).focus(),p=a.Event("tooltipvisible"),p.originalEvent=c?H.event:f,E.trigger(p,[z])):E.css({display:"",visibility:"",opacity:"",left:"",top:""})}if(!z.rendered)if(b)z.render(1);else return z;var g=b?"show":"hide",h=t[g],j=E.is(":visible"),k=!c||t[g].target.length<2||H.target[0]===c.target,l=t.position,m=t.content,o,p;(typeof b).search("boolean|number")&&(b=!j);if(!E.is(":animated")&&j===b&&k)return z;if(c){if(/over|enter/.test(c.type)&&/out|leave/.test(H.event.type)&&c.target===t.show.target[0]&&E.has(c.relatedTarget).length)return z;H.event=a.extend({},c)}p=a.Event("tooltip"+g),p.originalEvent=c?H.event:f,E.trigger(p,[z,90]);if(p.isDefaultPrevented())return z;a.attr(E[0],"aria-hidden",!b),b?(H.origin=a.extend({},i),z.focus(c),a.isFunction(m.text)&&P(m.text,e),a.isFunction(m.title.text)&&O(m.title.text,e),!v&&l.target==="mouse"&&l.adjust.mouse&&(a(document).bind("mousemove.qtip",function(a){i={pageX:a.pageX,pageY:a.pageY,type:"mousemove"}}),v=d),z.reposition(c),h.solo&&a(n,h.solo).not(E).qtip("hide",p)):(clearTimeout(z.timers.show),delete H.origin,v&&!a(n+'[tracking="true"]:visible',h.solo).not(E).length&&(a(document).unbind("mousemove.qtip"),v=e),z.blur(c)),k&&E.stop(0,1),h.effect===e?(E[g](),q.call(E)):a.isFunction(h.effect)?(h.effect.call(E,z),E.queue("fx",function(a){q(),a()})):E.fadeTo(90,b?1:0,q),b&&h.target.trigger("qtip-"+w+"-inactive");return z},show:function(a){return z.toggle(d,a)},hide:function(a){return z.toggle(e,a)},focus:function(b){if(!z.rendered)return z;var c=a(n),d=parseInt(E[0].style.zIndex,10),e=g.zindex+c.length,f=a.extend({},b),h,i;E.hasClass(p)||(i=a.Event("tooltipfocus"),i.originalEvent=f,E.trigger(i,[z,e]),i.isDefaultPrevented()||(d!==e&&(c.each(function(){this.style.zIndex>d&&(this.style.zIndex=this.style.zIndex-1)}),c.filter("."+p).qtip("blur",f)),E.addClass(p)[0].style.zIndex=e));return z},blur:function(b){var c=a.extend({},b),d;E.removeClass(p),d=a.Event("tooltipblur"),d.originalEvent=c,E.trigger(d,[z]);return z},reposition:function(c,d){if(!z.rendered||C)return z;C=1;var f=t.position.target,g=t.position,j=g.my,l=g.at,m=g.adjust,n=m.method.split(" "),o=E.outerWidth(),p=E.outerHeight(),q=0,r=0,s=a.Event("tooltipmove"),u=E.css("position")==="fixed",v=g.viewport,w={left:0,top:0},x=z.plugins.tip,y={horizontal:n[0],vertical:n[1]||n[0],left:function(a){var b=y.horizontal==="shift",c=v.offset.left+v.scrollLeft,d=j.x==="left"?o:j.x==="right"?-o:-o/2,e=l.x==="left"?q:l.x==="right"?-q:-q/2,f=x&&x.size?x.size.width||0:0,g=x&&x.corner&&x.corner.precedance==="x"&&!b?f:0,h=c-a+g,i=a+o-v.width-c+g,k=d-(j.precedance==="x"||j.x===j.y?e:0),n=j.x==="center";b?(g=x&&x.corner&&x.corner.precedance==="y"?f:0,k=(j.x==="left"?1:-1)*d-g,w.left+=h>0?h:i>0?-i:0,w.left=Math.max(v.offset.left+(g&&x.corner.x==="center"?x.offset:0),a-k,Math.min(Math.max(v.offset.left+v.width,a+k),w.left))):(h>0&&(j.x!=="left"||i>0)?w.left-=k+(n?0:2*m.x):i>0&&(j.x!=="right"||h>0)&&(w.left-=n?-k:k+2*m.x),w.left!==a&&n&&(w.left-=m.x),w.left<c&&-w.left>i&&(w.left=a));return w.left-a},top:function(a){var b=y.vertical==="shift",c=v.offset.top+v.scrollTop,d=j.y==="top"?p:j.y==="bottom"?-p:-p/2,e=l.y==="top"?r:l.y==="bottom"?-r:-r/2,f=x&&x.size?x.size.height||0:0,g=x&&x.corner&&x.corner.precedance==="y"&&!b?f:0,h=c-a+g,i=a+p-v.height-c+g,k=d-(j.precedance==="y"||j.x===j.y?e:0),n=j.y==="center";b?(g=x&&x.corner&&x.corner.precedance==="x"?f:0,k=(j.y==="top"?1:-1)*d-g,w.top+=h>0?h:i>0?-i:0,w.top=Math.max(v.offset.top+(g&&x.corner.x==="center"?x.offset:0),a-k,Math.min(Math.max(v.offset.top+v.height,a+k),w.top))):(h>0&&(j.y!=="top"||i>0)?w.top-=k+(n?0:2*m.y):i>0&&(j.y!=="bottom"||h>0)&&(w.top-=n?-k:k+2*m.y),w.top!==a&&n&&(w.top-=m.y),w.top<0&&-w.top>i&&(w.top=a));return w.top-a}};if(a.isArray(f)&&f.length===2)l={x:"left",y:"top"},w={left:f[0],top:f[1]};else if(f==="mouse"&&(c&&c.pageX||H.event.pageX))l={x:"left",y:"top"},c=(c&&(c.type==="resize"||c.type==="scroll")?H.event:c&&c.pageX&&c.type==="mousemove"?c:i&&i.pageX&&(m.mouse||!c||!c.pageX)?{pageX:i.pageX,pageY:i.pageY}:!m.mouse&&H.origin&&H.origin.pageX?H.origin:c)||c||H.event||i||{},w={top:c.pageY,left:c.pageX};else{f==="event"?c&&c.target&&c.type!=="scroll"&&c.type!=="resize"?f=H.target=a(c.target):f=H.target:H.target=a(f),f=a(f).eq(0);if(f.length===0)return z;f[0]===document||f[0]===b?(q=h.iOS?b.innerWidth:f.width(),r=h.iOS?b.innerHeight:f.height(),f[0]===b&&(w={top:!u||h.iOS?(v||f).scrollTop():0,left:!u||h.iOS?(v||f).scrollLeft():0})):f.is("area")&&h.imagemap?w=h.imagemap(f,l):f[0].namespaceURI==="http://www.w3.org/2000/svg"&&h.svg?w=h.svg(f,l):(q=f.outerWidth(),r=f.outerHeight(),w=h.offset(f,g.container,u)),w.offset&&(q=w.width,r=w.height,w=w.offset),w.left+=l.x==="right"?q:l.x==="center"?q/2:0,w.top+=l.y==="bottom"?r:l.y==="center"?r/2:0}w.left+=m.x+(j.x==="right"?-o:j.x==="center"?-o/2:0),w.top+=m.y+(j.y==="bottom"?-p:j.y==="center"?-p/2:0),v.jquery&&f[0]!==b&&f[0]!==A&&y.vertical+y.horizontal!=="nonenone"?(v={elem:v,height:v[(v[0]===b?"h":"outerH")+"eight"](),width:v[(v[0]===b?"w":"outerW")+"idth"](),scrollLeft:u?0:v.scrollLeft(),scrollTop:u?0:v.scrollTop(),offset:v.offset()||{left:0,top:0}},w.adjusted={left:y.horizontal!=="none"?y.left(w.left):0,top:y.vertical!=="none"?y.top(w.top):0}):w.adjusted={left:0,top:0},E.attr("class",function(b,c){return a.attr(this,"class").replace(/ui-tooltip-pos-\w+/i,"")}).addClass(k+"-pos-"+j.abbreviation()),s.originalEvent=a.extend({},c),E.trigger(s,[z,w,v.elem||v]);if(s.isDefaultPrevented())return z;delete w.adjusted,d===e||isNaN(w.left)||isNaN(w.top)||f==="mouse"||!a.isFunction(g.effect)?E.css(w):a.isFunction(g.effect)&&(g.effect.call(E,z,a.extend({},w)),E.queue(function(b){a(this).css({opacity:"",height:""}),a.browser.msie&&this.style.removeAttribute("filter"),b()})),C=0;return z},redraw:function(){if(z.rendered<1||D)return z;var a=t.position.container,b,c,d,e;D=1,t.style.height&&E.css("height",t.style.height),t.style.width?E.css("width",t.style.width):(E.css("width","").addClass(r),c=E.width()+1,d=E.css("max-width")||"",e=E.css("min-width")||"",b=(d+e).indexOf("%")>-1?a.width()/100:0,d=(d.indexOf("%")>-1?b:1)*parseInt(d,10)||c,e=(e.indexOf("%")>-1?b:1)*parseInt(e,10)||0,c=d+e?Math.min(Math.max(c,e),d):c,E.css("width",Math.round(c)).removeClass(r)),D=0;return z},disable:function(b){"boolean"!==typeof b&&(b=!E.hasClass(m)&&!H.disabled),z.rendered?(E.toggleClass(m,b),a.attr(E[0],"aria-disabled",b)):H.disabled=!!b;return z},enable:function(){return z.disable(e)},destroy:function(){var b=s[0],c=a.attr(b,u);z.rendered&&(E.remove(),a.each(z.plugins,function(){this.destroy&&this.destroy()})),clearTimeout(z.timers.show),clearTimeout(z.timers.hide),R(),a.removeData(b,"qtip"),t.suppress&&c&&(a.attr(b,"title",c),s.removeAttr(u)),s.removeAttr("aria-describedby").unbind(".qtip"),delete j[z.id];return s}})}function x(b){var c;if(!b||"object"!==typeof b)return e;"object"!==typeof b.metadata&&(b.metadata={type:b.metadata});if("content"in b){if("object"!==typeof b.content||b.content.jquery)b.content={text:b.content};c=b.content.text||e,!a.isFunction(c)&&(!c&&!c.attr||c.length<1||"object"===typeof c&&!c.jquery)&&(b.content.text=e),"title"in b.content&&("object"!==typeof b.content.title&&(b.content.title={text:b.content.title}),c=b.content.title.text||e,!a.isFunction(c)&&(!c&&!c.attr||c.length<1||"object"===typeof c&&!c.jquery)&&(b.content.title.text=e))}"position"in b&&("object"!==typeof b.position&&(b.position={my:b.position,at:b.position})),"show"in b&&("object"!==typeof b.show&&(b.show.jquery?b.show={target:b.show}:b.show={event:b.show})),"hide"in b&&("object"!==typeof b.hide&&(b.hide.jquery?b.hide={target:b.hide}:b.hide={event:b.hide})),"style"in b&&("object"!==typeof b.style&&(b.style={classes:b.style})),a.each(h,function(){this.sanitize&&this.sanitize(b)});return b}function w(){w.history=w.history||[],w.history.push(arguments);if("object"===typeof console){var a=console[console.warn?"warn":"log"],b=Array.prototype.slice.call(arguments),c;typeof arguments[0]==="string"&&(b[0]="qTip2: "+b[0]),c=a.apply?a.apply(console,b):a(b)}}"use strict";var d=!0,e=!1,f=null,g,h,i,j={},k="ui-tooltip",l="ui-widget",m="ui-state-disabled",n="div.qtip."+k,o=k+"-default",p=k+"-focus",q=k+"-hover",r=k+"-fluid",s="-31000px",t="_replacedByqTip",u="oldtitle",v;g=a.fn.qtip=function(b,h,i){var j=(""+b).toLowerCase(),k=f,l=j==="disable"?[d]:a.makeArray(arguments).slice(1),m=l[l.length-1],n=this[0]?a.data(this[0],"qtip"):f;if(!arguments.length&&n||j==="api")return n;if("string"===typeof b){this.each(function(){var b=a.data(this,"qtip");if(!b)return d;m&&m.timeStamp&&(b.cache.event=m);if(j!=="option"&&j!=="options"||!h)b[j]&&b[j].apply(b[j],l);else if(a.isPlainObject(h)||i!==c)b.set(h,i);else{k=b.get(h);return e}});return k!==f?k:this}if("object"===typeof b||!arguments.length){n=x(a.extend(d,{},b));return g.bind.call(this,n,m)}},g.bind=function(b,f){return this.each(function(k){function r(b){function d(){p.render(typeof b==="object"||l.show.ready),m.show.add(m.hide).unbind(o)}if(p.cache.disabled)return e;p.cache.event=a.extend({},b),p.cache.target=b?a(b.target):[c],l.show.delay>0?(clearTimeout(p.timers.show),p.timers.show=setTimeout(d,l.show.delay),n.show!==n.hide&&m.hide.bind(n.hide,function(){clearTimeout(p.timers.show)})):d()}var l,m,n,o,p,q;q=a.isArray(b.id)?b.id[k]:b.id,q=!q||q===e||q.length<1||j[q]?g.nextid++:j[q]=q,o=".qtip-"+q+"-create",p=z.call(this,q,b);if(p===e)return d;l=p.options,a.each(h,function(){this.initialize==="initialize"&&this(p)}),m={show:l.show.target,hide:l.hide.target},n={show:a.trim(""+l.show.event).replace(/ /g,o+" ")+o,hide:a.trim(""+l.hide.event).replace(/ /g,o+" ")+o},/mouse(over|enter)/i.test(n.show)&&!/mouse(out|leave)/i.test(n.hide)&&(n.hide+=" mouseleave"+o),m.show.bind("mousemove"+o,function(a){i={pageX:a.pageX,pageY:a.pageY,type:"mousemove"}}),m.show.bind(n.show,r),(l.show.ready||l.prerender)&&r(f)})},h=g.plugins={Corner:function(a){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,"center").toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase(),this.precedance=a.charAt(0).search(/^(t|b)/)>-1?"y":"x",this.string=function(){return this.precedance==="y"?this.y+this.x:this.x+this.y},this.abbreviation=function(){var a=this.x.substr(0,1),b=this.y.substr(0,1);return a===b?a:a==="c"||a!=="c"&&b!=="c"?b+a:a+b}},offset:function(c,d,e){function l(a,b){f.left+=b*a.scrollLeft(),f.top+=b*a.scrollTop()}var f=c.offset(),g=d,i=0,j=document.body,k;if(g){do{g.css("position")!=="static"&&(k=g[0]===j?{left:parseInt(g.css("left"),10)||0,top:parseInt(g.css("top"),10)||0}:g.position(),f.left-=k.left+(parseInt(g.css("borderLeftWidth"),10)||0)+(parseInt(g.css("marginLeft"),10)||0),f.top-=k.top+(parseInt(g.css("borderTopWidth"),10)||0),i++);if(g[0]===j)break}while(g=g.offsetParent());d[0]!==j&&i>1&&l(d,1),(h.iOS<4.1&&h.iOS>3.1||!h.iOS&&e)&&l(a(b),-1)}return f},iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,3})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_","."))||e,fn:{attr:function(b,c){if(this.length){var d=this[0],e="title",f=a.data(d,"qtip");if(b===e&&"object"===typeof f&&f.options.suppress){if(arguments.length<2)return a.attr(d,u);f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",c);return this.attr(u,c)}}return a.fn["attr"+t].apply(this,arguments)},clone:function(b){var c=a([]),d="title",e=a.fn["clone"+t].apply(this,arguments);b||e.filter("["+u+"]").attr("title",function(){return a.attr(this,u)}).removeAttr(u);return e},remove:a.ui?f:function(b,c){a(this).each(function(){c||(!b||a.filter(b,[this]).length)&&a("*",this).add(this).each(function(){a(this).triggerHandler("remove")})})}}},a.each(h.fn,function(b,c){if(!c)return d;var e=a.fn[b+t]=a.fn[b];a.fn[b]=function(){return c.apply(this,arguments)||e.apply(this,arguments)}}),g.version="nightly",g.nextid=0,g.inactiveEvents="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),g.zindex=15e3,g.defaults={prerender:e,id:e,overwrite:d,suppress:d,content:{text:d,attr:"title",title:{text:e,button:e}},position:{my:"top left",at:"bottom right",target:e,container:e,viewport:e,adjust:{x:0,y:0,mouse:d,resize:d,method:"flip flip"},effect:function(b,c,d){a(this).animate(c,{duration:200,queue:e})}},show:{target:e,event:"mouseenter",effect:d,delay:90,solo:e,ready:e,autofocus:e},hide:{target:e,event:"mouseleave",effect:d,delay:0,fixed:e,inactive:e,leave:"window",distance:e},style:{classes:"",widget:e,width:e,height:e},events:{render:f,move:f,show:f,hide:f,toggle:f,visible:f,focus:f,blur:f}},h.ajax=function(a){var b=a.plugins.ajax;return"object"===typeof b?b:a.plugins.ajax=new A(a)},h.ajax.initialize="render",h.ajax.sanitize=function(a){var b=a.content,c;b&&"ajax"in b&&(c=b.ajax,typeof c!=="object"&&(c=a.content.ajax={url:c}),"boolean"!==typeof c.once&&c.once&&(c.once=!!c.once))},a.extend(d,g.defaults,{content:{ajax:{loading:d,once:d}}}),h.tip=function(a){var b=a.plugins.tip;return"object"===typeof b?b:a.plugins.tip=new C(a)},h.tip.initialize="render",h.tip.sanitize=function(a){var b=a.style,c;b&&"tip"in b&&(c=a.style.tip,typeof c!=="object"&&(a.style.tip={corner:c}),/string|boolean/i.test(typeof c.corner)||(c.corner=d),typeof c.width!=="number"&&delete c.width,typeof c.height!=="number"&&delete c.height,typeof c.border!=="number"&&c.border!==d&&delete c.border,typeof c.offset!=="number"&&delete c.offset)},a.extend(d,g.defaults,{style:{tip:{corner:d,mimic:e,width:6,height:6,border:d,offset:0}}}),h.bgiframe=function(b){var c=a.browser,d=b.plugins.bgiframe;if(a("select, object").length<1||(!c.msie||c.version.charAt(0)!=="6"))return e;return"object"===typeof d?d:b.plugins.bgiframe=new D(b)},h.bgiframe.initialize="render"})(jQuery,window)
Property changes on: platform\inc\jquery\qtip\jquery.qtip.min.js
___________________________________________________________________
Added: svn:eol-style
+ LF
Index: platform/inc/script.js
===================================================================
--- platform/inc/script.js (revision 14590)
+++ platform/inc/script.js (working copy)
@@ -214,3 +214,24 @@
this._controls.push($id);
}
+function in_array(needle, haystack)
+{
+ return array_search(needle, haystack) != -1;
+}
+
+function array_search(needle, haystack)
+{
+ for (var i=0; i<haystack.length; i++)
+ {
+ if (haystack[i] == needle) return i;
+ }
+ return -1;
+}
+
+Array.prototype.diff = function(a) {
+ return this.filter(
+ function (i) {
+ return a.indexOf(i) == -1;
+ }
+ );
+};
Index: platform/inc/styles.css
===================================================================
--- platform/inc/styles.css (revision 14590)
+++ platform/inc/styles.css (working copy)
@@ -639,4 +639,8 @@
list-style-position: outside;
list-style-type: disc;
padding: 5px 0 0;
+}
+
+.ui-tooltip, .qtip {
+ font-size: 13px;
}
\ No newline at end of file