/* Prototype JavaScript framework, version 1.6.0.3
* (c) 2005-2008 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
*
*--------------------------------------------------------------------------*/
var Prototype = {
Version: '1.6.0.3',
Browser: {
IE: !!(window.attachEvent &&
navigator.userAgent.indexOf('Opera') === -1),
Opera: navigator.userAgent.indexOf('Opera') > -1,
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
Gecko: navigator.userAgent.indexOf('Gecko') > -1 &&
navigator.userAgent.indexOf('KHTML') === -1,
MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
},
BrowserFeatures: {
XPath: !!document.evaluate,
SelectorsAPI: !!document.querySelector,
ElementExtensions: !!window.HTMLElement,
SpecificElementExtensions:
document.createElement('div')['__proto__'] &&
document.createElement('div')['__proto__'] !==
document.createElement('form')['__proto__']
},
ScriptFragment: '');
},
REQUIRED_PROTOTYPE: '1.5.1',
load: function() {
function convertVersionString(versionString){
var r = versionString.split('.');
return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
}
if((typeof Prototype=='undefined') ||
(typeof Element == 'undefined') ||
(typeof Element.Methods=='undefined') ||
(convertVersionString(Prototype.Version) <
convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
throw("script.aculo.us requires the Prototype JavaScript framework >= " +
Scriptaculous.REQUIRED_PROTOTYPE);
$A(document.getElementsByTagName("script")).findAll( function(s) {
return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
}).each( function(s) {
var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
var includes = s.src.match(/\?.*load=([a-z,]*)/);
(includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
function(include) { Scriptaculous.require(path+include+'.js') });
});
}
}
Scriptaculous.load();
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE_AFL.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
*/
if(typeof Product=='undefined') {
var Product = {};
}
/********************* IMAGE ZOOMER ***********************/
Product.Zoom = Class.create();
/**
* Image zoom control
*
* @author Magento Core Team
*/
Product.Zoom.prototype = {
initialize: function(imageEl, trackEl, handleEl, zoomInEl, zoomOutEl, hintEl){
this.containerEl = $(imageEl).parentNode;
this.imageEl = $(imageEl);
this.handleEl = $(handleEl);
this.trackEl = $(trackEl);
this.hintEl = $(hintEl);
this.containerDim = Element.getDimensions(this.containerEl);
this.imageDim = Element.getDimensions(this.imageEl);
this.imageDim.ratio = this.imageDim.width/this.imageDim.height;
this.floorZoom = 1;
if (this.imageDim.width > this.imageDim.height) {
this.ceilingZoom = this.imageDim.width / this.containerDim.width;
} else {
this.ceilingZoom = this.imageDim.height / this.containerDim.height;
}
if (this.imageDim.width <= this.containerDim.width
&& this.imageDim.height <= this.containerDim.height) {
this.trackEl.up().hide();
this.hintEl.hide();
this.containerEl.removeClassName('product-image-zoom');
return;
}
this.imageX = 0;
this.imageY = 0;
this.imageZoom = 1;
this.sliderSpeed = 0;
this.sliderAccel = 0;
this.zoomBtnPressed = false;
this.showFull = false;
this.selects = document.getElementsByTagName('select');
this.draggable = new Draggable(imageEl, {
starteffect:false,
reverteffect:false,
endeffect:false,
snap:this.contain.bind(this)
});
this.slider = new Control.Slider(handleEl, trackEl, {
axis:'horizontal',
minimum:0,
maximum:Element.getDimensions(this.trackEl).width,
alignX:0,
increment:1,
sliderValue:0,
onSlide:this.scale.bind(this),
onChange:this.scale.bind(this)
});
this.scale(0);
Event.observe(this.imageEl, 'dblclick', this.toggleFull.bind(this));
Event.observe($(zoomInEl), 'mousedown', this.startZoomIn.bind(this));
Event.observe($(zoomInEl), 'mouseup', this.stopZooming.bind(this));
Event.observe($(zoomInEl), 'mouseout', this.stopZooming.bind(this));
Event.observe($(zoomOutEl), 'mousedown', this.startZoomOut.bind(this));
Event.observe($(zoomOutEl), 'mouseup', this.stopZooming.bind(this));
Event.observe($(zoomOutEl), 'mouseout', this.stopZooming.bind(this));
},
toggleFull: function () {
this.showFull = !this.showFull;
//TODO: hide selects for IE only
for (i=0; ixMin ? xMin : x;
x = xyMin ? yMin : y;
y = y=0;i--){
var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
if(i==0){
this.fillSelect(this.settings[i])
}
else {
this.settings[i].disabled=true;
}
$(this.settings[i]).childSettings = childSettings.clone();
$(this.settings[i]).prevSetting = prevSetting;
$(this.settings[i]).nextSetting = nextSetting;
childSettings.push(this.settings[i]);
}
// try retireve options from url
var separatorIndex = window.location.href.indexOf('#');
if (separatorIndex!=-1) {
var paramsStr = window.location.href.substr(separatorIndex+1);
this.values = paramsStr.toQueryParams();
this.settings.each(function(element){
var attributeId = element.attributeId;
element.value = this.values[attributeId];
this.configureElement(element);
}.bind(this));
}
},
configure: function(event){
var element = Event.element(event);
this.configureElement(element);
},
configureElement : function(element) {
this.reloadOptionLabels(element);
if(element.value){
this.state[element.config.id] = element.value;
if(element.nextSetting){
element.nextSetting.disabled = false;
this.fillSelect(element.nextSetting);
this.resetChildren(element.nextSetting);
}
}
else {
this.resetChildren(element);
}
this.reloadPrice();
// Calculator.updatePrice();
},
reloadOptionLabels: function(element){
var selectedPrice;
if(element.options[element.selectedIndex].config){
selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
}
else{
selectedPrice = 0;
}
for(var i=0;i-1){
allowedProducts.push(options[i].products[j]);
}
}
} else {
allowedProducts = options[i].products.clone();
}
if(allowedProducts.size()>0){
options[i].allowedProducts = allowedProducts;
element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
element.options[index].config = options[i];
index++;
}
}
}
},
getOptionLabel: function(option, price){
var price = parseFloat(price);
var str = option.label;
if(price){
str+= ' (' + this.formatPrice(price, true) + ')';
}
return str;
},
formatPrice: function(price, showSign){
var str = '';
price = parseFloat(price);
if(showSign){
if(price<0){
str+= '-';
price = -price;
}
else{
str+= '+';
}
}
var roundedPrice = (Math.round(price*100)/100).toString();
if (this.prices && this.prices[roundedPrice]) {
str+= this.prices[roundedPrice];
}
else {
str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
}
return str;
},
clearSelect: function(element){
for(var i=element.options.length-1;i>=0;i--){
element.remove(i);
}
},
getAttributeOptions: function(attributeId){
if(this.config.attributes[attributeId]){
return this.config.attributes[attributeId].options;
}
},
reloadPrice: function(){
var price = 0;
for(var i=this.settings.length-1;i>=0;i--){
var selected = this.settings[i].options[this.settings[i].selectedIndex];
if(selected.config){
price += parseFloat(selected.config.price);
}
}
optionsPrice.changePrice('config', price);
optionsPrice.reload();
return price;
if($('product-price-'+this.config.productId)){
$('product-price-'+this.config.productId).innerHTML = price;
}
this.reloadOldPrice();
},
reloadOldPrice: function(){
if ($('old-price-'+this.config.productId)) {
var price = parseFloat(this.config.oldPrice);
for(var i=this.settings.length-1;i>=0;i--){
var selected = this.settings[i].options[this.settings[i].selectedIndex];
if(selected.config){
price+= parseFloat(selected.config.price);
}
}
if (price < 0)
price = 0;
price = this.formatPrice(price);
if($('old-price-'+this.config.productId)){
$('old-price-'+this.config.productId).innerHTML = price;
}
}
}
}
/**************************** SUPER PRODUCTS ********************************/
Product.Super = {};
Product.Super.Configurable = Class.create();
Product.Super.Configurable.prototype = {
initialize: function(container, observeCss, updateUrl, updatePriceUrl, priceContainerId) {
this.container = $(container);
this.observeCss = observeCss;
this.updateUrl = updateUrl;
this.updatePriceUrl = updatePriceUrl;
this.priceContainerId = priceContainerId;
this.registerObservers();
},
registerObservers: function() {
var elements = this.container.getElementsByClassName(this.observeCss);
elements.each(function(element){
Event.observe(element, 'change', this.update.bindAsEventListener(this));
}.bind(this));
return this;
},
update: function(event) {
var elements = this.container.getElementsByClassName(this.observeCss);
var parameters = Form.serializeElements(elements, true);
new Ajax.Updater(this.container, this.updateUrl + '?ajax=1', {
parameters:parameters,
onComplete:this.registerObservers.bind(this)
});
var priceContainer = $(this.priceContainerId);
if(priceContainer) {
new Ajax.Updater(priceContainer, this.updatePriceUrl + '?ajax=1', {
parameters:parameters
});
}
}
}
/**************************** PRICE RELOADER ********************************/
Product.OptionsPrice = Class.create();
Product.OptionsPrice.prototype = {
initialize: function(config) {
this.productId = config.productId;
this.priceFormat = config.priceFormat;
this.includeTax = config.includeTax;
this.defaultTax = config.defaultTax;
this.currentTax = config.currentTax;
this.productPrice = config.productPrice;
this.showIncludeTax = config.showIncludeTax;
this.showBothPrices = config.showBothPrices;
this.productPrice = config.productPrice;
this.productOldPrice = config.productOldPrice;
this.skipCalculate = config.skipCalculate;
this.duplicateIdSuffix = config.idSuffix;
this.oldPlusDisposition = config.oldPlusDisposition;
this.plusDisposition = config.plusDisposition;
this.oldMinusDisposition = config.oldMinusDisposition;
this.minusDisposition = config.minusDisposition;
this.optionPrices = {};
this.containers = {};
this.initPrices();
},
setDuplicateIdSuffix: function(idSuffix) {
this.duplicateIdSuffix = idSuffix;
},
initPrices: function() {
this.containers[0] = 'product-price-' + this.productId;
this.containers[1] = 'bundle-price-' + this.productId;
this.containers[2] = 'price-including-tax-' + this.productId;
this.containers[3] = 'price-excluding-tax-' + this.productId;
this.containers[4] = 'old-price-' + this.productId;
},
changePrice: function(key, price) {
this.optionPrices[key] = parseFloat(price);
},
getOptionPrices: function() {
var result = 0;
var nonTaxable = 0;
$H(this.optionPrices).each(function(pair) {
if (pair.key == 'nontaxable') {
nonTaxable = pair.value;
} else {
result += pair.value;
}
});
var r = new Array(result, nonTaxable);
return r;
},
reload: function() {
var price;
var formattedPrice;
var optionPrices = this.getOptionPrices();
var nonTaxable = optionPrices[1];
optionPrices = optionPrices[0];
$H(this.containers).each(function(pair) {
var _productPrice;
var _plusDisposition;
var _minusDisposition;
if ($(pair.value)) {
if (pair.value == 'old-price-'+this.productId && this.productOldPrice != this.productPrice) {
_productPrice = this.productOldPrice;
_plusDisposition = this.oldPlusDisposition;
_minusDisposition = this.oldMinusDisposition;
} else {
_productPrice = this.productPrice;
_plusDisposition = this.plusDisposition;
_minusDisposition = this.minusDisposition;
}
var price = optionPrices+parseFloat(_productPrice)
if (this.includeTax == 'true') {
// tax = tax included into product price by admin
var tax = price / (100 + this.defaultTax) * this.defaultTax;
var excl = price - tax;
var incl = excl*(1+(this.currentTax/100));
} else {
var tax = price * (this.defaultTax / 100);
var excl = price;
var incl = excl + tax;
}
excl += parseFloat(_plusDisposition);
incl += parseFloat(_plusDisposition);
excl -= parseFloat(_minusDisposition);
incl -= parseFloat(_minusDisposition);
//adding nontaxlable part of options
excl += parseFloat(nonTaxable);
incl += parseFloat(nonTaxable);
if (pair.value == 'price-including-tax-'+this.productId) {
price = incl;
} else if (pair.value == 'old-price-'+this.productId) {
if (this.showIncludeTax || this.showBothPrices) {
price = incl;
} else {
price = excl;
}
} else {
if (this.showIncludeTax) {
price = incl;
} else {
if (!this.skipCalculate || _productPrice == 0) {
price = excl;
} else {
price = optionPrices+parseFloat(_productPrice);
}
}
}
if (price < 0) price = 0;
formattedPrice = this.formatPrice(price);
if ($(pair.value).select('.price')[0]) {
$(pair.value).select('.price')[0].innerHTML = formattedPrice;
if ($(pair.value+this.duplicateIdSuffix) && $(pair.value+this.duplicateIdSuffix).select('.price')[0]) {
$(pair.value+this.duplicateIdSuffix).select('.price')[0].innerHTML = formattedPrice;
}
} else {
$(pair.value).innerHTML = formattedPrice;
if ($(pair.value+this.duplicateIdSuffix)) {
$(pair.value+this.duplicateIdSuffix).innerHTML = formattedPrice;
}
}
};
}.bind(this));
},
formatPrice: function(price) {
return formatCurrency(price, this.priceFormat);
}
}