Convert ES6 javascript file to ES5 online - javascript

I'm trying to convert a ES6 javascript file to ES5 as I'm need to target an old browser (ie: A webview on Android 4.4.2).
I've seen that Babeljs.io provide a tool to do a conversion, but the output code don't seems valid... (see here)
Any idea how to achieve this conversion (just once) ?
The file concerned is siiimple-toast.js (a toast notification plugin)
/* success + alert + warning + message */
var setStyles = (el, styles) => {
Object.keys(styles).forEach((key) => {
el.style[key] = styles[key];
});
};
const setAttrs = (el, attrs) => {
Object.keys(attrs).forEach((key) => {
el.setAttribute(key, attrs[key]);
});
};
const getAttr = (el, attr) => el.getAttribute(attr);
const privateKeys = {
defaultOptions: Symbol('defaultOptions'),
render: Symbol('render'),
show: Symbol('show'),
hide: Symbol('hide'),
removeDOM: Symbol('removeDOM'),
};
const siiimpleToast = {
[privateKeys.defaultOptions]: {
container: 'body',
class: 'siiimpleToast',
position: 'top|center',
margin: 15,
delay: 0,
duration: 3000,
style: {},
},
setOptions(options = {}) {
return {
...siiimpleToast,
[privateKeys.defaultOptions]: {
...this[privateKeys.defaultOptions],
...options,
},
};
},
[privateKeys.render](state, message, options = {}) {
const mergedOptions = {
...this[privateKeys.defaultOptions],
...options,
};
const {
class: className,
position,
delay,
duration,
style,
} = mergedOptions;
const newToast = document.createElement('div');
// logging via attrs
newToast.className = className;
var toatsLoaded=1;
newToast.innerHTML = '<span class="toastIcon '+state+'">';
setAttrs(newToast, {
'data-position': position,
'data-state': state,
});
setStyles(newToast, style);
// use .setTimeout() instead of $.queue()
let time = 0;
setTimeout(() => {
this[privateKeys.show](newToast, mergedOptions);
}, time += delay);
setTimeout(() => {
this[privateKeys.hide](newToast, mergedOptions);
}, time += temps);
// support method chaining
return this;
},
[privateKeys.show](el, { container, class: className, margin }) {
const hasPos = (v, pos) => getAttr(v, 'data-position').indexOf(pos) > -1;
const root = document.querySelector(container);
root.insertBefore(el, root.firstChild);
// set initial position
setStyles(el, {
position: container === 'body' ? 'fixed' : 'absolute',
[hasPos(el, 'top') ? 'top' : 'bottom']: '-100px',
[hasPos(el, 'left') && 'left']: '15px',
[hasPos(el, 'center') && 'left']: `${(root.clientWidth / 2) - (el.clientWidth / 2)}px`,
[hasPos(el, 'right') && 'right']: '15px',
});
setStyles(el, {
transform: 'scale(1)',
opacity: 1,
});
// distance de départ
let pushStack = 20;
Array
.from(document.querySelectorAll(`.${className}[data-position="${getAttr(el, 'data-position')}"]`))
.filter(toast => toast.parentElement === el.parentElement)// matching container
.forEach((toast) => {
setStyles(toast, {
[hasPos(toast, 'top') ? 'top' : 'bottom']: `${pushStack}px`,
});
pushStack += toast.offsetHeight + margin;
});
},
[privateKeys.hide](el) {
const hasPos = (v, pos) => getAttr(v, 'data-position').indexOf(pos) > -1;
const { left, width } = el.getBoundingClientRect();
setStyles(el, {
[hasPos(el, 'left') && 'left']: `${width}px`,
[hasPos(el, 'center') && 'left']: `${left + width}px`,
[hasPos(el, 'right') && 'right']: `-${width}px`,
opacity: 0,
});
const whenTransitionEnd = () => {
this[privateKeys.removeDOM](el);
el.removeEventListener('transitionend', whenTransitionEnd);
};
el.addEventListener('transitionend', whenTransitionEnd);
},
[privateKeys.removeDOM](el) {// eslint-disable-line
const parent = el.parentElement;
parent.removeChild(el);
},
default(message, options) {
return this[privateKeys.render]('default', message, options);
}
};
$(document).on('click', '.toastClose', function(e){
e.preventDefault();
$(this).parent('.siiimpleToast').remove();
});
Thanks a lot for your feedbacks 🙏
Ben

Related

Go JS Tree view equivalent in React

I need to achieve the tree view (Go JS Tree View). The respective tree view sample source code without React JS is at (Tree View Source Code). I'm trying to do the same using React JS and have the following code written. But somehow I'm missing something and the diagram/tree view is not rendering. Can you please help me to figure out the issue?
import React from 'react';
import * as go from 'gojs';
import { ReactDiagram } from 'gojs-react';
import '../../../App.css';
go.Shape.defineFigureGenerator("ExpandedLine", function(shape, w, h) {
return new go.Geometry()
.add(new go.PathFigure(0, 0.25*h, false)
.add(new go.PathSegment(go.PathSegment.Line, .5 * w, 0.75*h))
.add(new go.PathSegment(go.PathSegment.Line, w, 0.25*h)));
});
// use a sideways V figure instead of PlusLine in the TreeExpanderButton
go.Shape.defineFigureGenerator("CollapsedLine", function(shape, w, h) {
return new go.Geometry()
.add(new go.PathFigure(0.25*w, 0, false)
.add(new go.PathSegment(go.PathSegment.Line, 0.75*w, .5 * h))
.add(new go.PathSegment(go.PathSegment.Line, 0.25*w, h)));
});
let nodeDataArray = [{ key: 0 }];
const initDiagram = () => {
let $ = go.GraphObject.make;
const diagram =
$(go.Diagram, "myDiagramDiv",
{
allowMove: false,
allowCopy: false,
allowDelete: false,
allowHorizontalScroll: false,
layout:
$(go.TreeLayout,
{
alignment: go.TreeLayout.AlignmentStart,
angle: 0,
compaction: go.TreeLayout.CompactionNone,
layerSpacing: 16,
layerSpacingParentOverlap: 1,
nodeIndentPastParent: 1.0,
nodeSpacing: 0,
setsPortSpot: false,
setsChildPortSpot: false
})
});
diagram.nodeTemplate =
$(go.Node,
{ // no Adornment: instead change panel background color by binding to Node.isSelected
selectionAdorned: false,
// a custom function to allow expanding/collapsing on double-click
// this uses similar logic to a TreeExpanderButton
doubleClick: function(e, node) {
let cmd = diagram.commandHandler;
if (node.isTreeExpanded) {
if (!cmd.canCollapseTree(node)) return;
} else {
if (!cmd.canExpandTree(node)) return;
}
e.handled = true;
if (node.isTreeExpanded) {
cmd.collapseTree(node);
} else {
cmd.expandTree(node);
}
}
},
$("TreeExpanderButton",
{ // customize the button's appearance
"_treeExpandedFigure": "ExpandedLine",
"_treeCollapsedFigure": "CollapsedLine",
"ButtonBorder.fill": "whitesmoke",
"ButtonBorder.stroke": null,
"_buttonFillOver": "rgba(0,128,255,0.25)",
"_buttonStrokeOver": null
}),
$(go.Panel, "Horizontal",
{ position: new go.Point(18, 0) },
new go.Binding("background", "isSelected",
s => (s ? 'lightblue' : 'white')).ofObject(),
$(go.Picture,
{
width: 18, height: 18,
margin: new go.Margin(0, 4, 0, 0),
imageStretch: go.GraphObject.Uniform
},
// bind the picture source on two properties of the Node
// to display open folder, closed folder, or document
new go.Binding("source", "isTreeExpanded", imageConverter).ofObject(),
new go.Binding("source", "isTreeLeaf", imageConverter).ofObject()),
$(go.TextBlock,
{ font: '9pt Verdana, sans-serif' },
new go.Binding("text", "key", function(s) { return "item " + s; }))
) // end Horizontal Panel
); // end Node
diagram.linkTemplate = $(go.Link);
let max = 499;
let count = 0;
while (count < max) {
count = makeTree(3, count, max, nodeDataArray, nodeDataArray[0]);
}
diagram.model = new go.TreeModel(nodeDataArray);
return diagram;
}
function makeTree(level, count, max, nodeDataArray, parentData) {
let numChildren = Math.floor(Math.random() * 10);
for (let i = 0; i < numChildren; i++) {
if (count >= max) return count;
count++;
let childData = { key: count, parent: parentData.key };
nodeDataArray.push(childData);
if (level > 0 && Math.random() > 0.5) {
count = makeTree(level - 1, count, max, nodeDataArray, childData);
}
}
return count;
}
function imageConverter(prop, picture) {
let node = picture.part;
if (node.isTreeLeaf) {
return "images/document.svg";
} else {
if (node.isTreeExpanded) {
return "images/openFolder.svg";
} else {
return "images/closedFolder.svg";
}
}
}
window.addEventListener('DOMContentLoaded', initDiagram);
const TreeView = () => {
return (
<>
GO JS
<div id="myDiagramDiv">
<ReactDiagram
initDiagram={initDiagram}
divClassName='diagram-component'
nodeDataArray={nodeDataArray}
skipsDiagramUpdate={false}
/>
</div>
</>
);
}
export default TreeView;
When React start executing, the DOMContentLoaded event have already been fired. Instead try to call initDiagram in a useEffect hook
const TreeView = () => {
useEffect(initDiagram);
return (
<>
GO JS
<div id="myDiagramDiv">
<ReactDiagram
initDiagram={initDiagram}
divClassName='diagram-component'
nodeDataArray={nodeDataArray}
skipsDiagramUpdate={false}
/>
</div>
</>
);
}

Cannot read property 'push' of undefined in React with Google charts

I have a bit of a weird error with react and my google charts, when i first login to my page that shows my chart everything shows fine, but there's a place where i import data for new values to show on my chart and the chart disappears when i import new values and i get the following errors:
Uncaught TypeError: processedData[(index + 1)] is undefined
This shows in the browser dev tools console, and when i run my debugger it shows this:
Uncaught TypeError: Cannot read property 'push' of undefined
/src/components/Charts/DoubleColumnChart/DoubleColumnChart.js:48
The above error occurred in the <DoubleColumnChart> component:
in DoubleColumnChart
The error seems to be in this part of my code:
data.datasets.forEach(function (dataset) {
processedData[0].push(dataset.label);
dataset.data.forEach(function (data, index) {
processedData[index + 1].push(data);
});
});
I read some documentation on withRouter but i dont know if that would work here. Here is my full code:
import React from 'react';
import { Chart } from "react-google-charts";
import { withRouter } from "react-router";
export const DoubleColumnChart = (props) => {
const processData = (data) => {
if (data == null) return [[]];
if (data.labels == null) return [[]];
var processedData = [[]];
processedData[0].push('Category');
data.labels.forEach(function (label) {
var finalLabel = label[0];
if (label.length > 1) {
for (var i = 1; i < label.length; i++) {
if (finalLabel.length > parseInt(160 / data.labels.length, 10)) {
finalLabel = finalLabel + '...';
break;
}
finalLabel = finalLabel + '\n' + label[i];
}
}
processedData.push([finalLabel]);
});
console.log(data.datasets);
data.datasets.forEach(function (dataset) {
processedData[0].push(dataset.label);
dataset.data.forEach(function (data, index) {
processedData[index + 1].push(data);
});
});
return processedData;
}
const processColors = (data) => {
if (data == null) return [];
if (data.datasets == null) return [[]];
var processedColors = [];
data.datasets.forEach(function (dataset) {
processedColors.push(dataset.backgroundColor);
});
return processedColors
}
if (props.isVisible == false) {
return <div></div>;
}
return (
<Chart
width={'99%'}
height={'375px'}
chartType="ColumnChart"
loader={<div>Loading Chart</div>}
data={processData(props.data)}
options={{
animation: {
duration: 1500,
easing: 'out',
startup: true,
},
legend: { position: 'bottom', textStyle: { color: 'gray' } },
vAxis: { textStyle: { color: 'gray' } },
hAxis: { textStyle: { fontSize: 10, color: 'gray' } },
tooltip: { trigger: 'hover', showColorCode: true },
chartArea: {
top: '2%',
left: '5%',
height: "77%",
width: "100%",
},
colors: processColors(props.data),
dataOpacity: '0.9',
}}
chartEvents={[
{
eventName: 'select',
callback: ({ chartWrapper }) => {
const chart = chartWrapper.getChart()
const selection = chart.getSelection()
if (selection.length === 1) {
const [selectedItem] = selection;
const { row } = selectedItem;
var labelData = props.data.labels[row];
var finalLabel = '';
for (var i = 0; i < labelData.length; i++) {
finalLabel = finalLabel + labelData[i];
}
finalLabel = finalLabel.replace(/ /g, '');
if (props.onSegmentClick) props.onSegmentClick(finalLabel);
}
},
},
]}
rootProps={{ 'data-testid': '1' }}
/>
);
}
Can anyone help me with this? Thanks.
When you are pushing data to an array with index+1 logic, so you should check that the next index of the array exists and then push data to that or convert the next index to an array and then push.
So, the typesafe way is something like this:
if(Array.isArray(processedData[index + 1])) {
processedData[index + 1].push(data);
}else {
processedData[index + 1] = [data]
}
In javascript push method can be used on array.
For example:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi");
But in the below method you are using processedData[0].push(dataset.label) which is like acessing the first element of the array and pushing into it which is wrong. You can do like processedData.push(dataset.label).
data.datasets.forEach(function (dataset) {
processedData[0].push(dataset.label);
dataset.data.forEach(function (data, index) {
processedData[index + 1].push(data);
});

Uncaught TypeError: this.timestamp is not a function

I'm a bit confused, don't know what is going wrong.
Maybe a bit of an explanation about this and it's usage in object methods would be awesome.
I saw that i should use this as global variable but that gives me more errors.
Here is my code:
$(function () {
var options = {
seeking: false,
stopped: true,
sliderOptions: {
imagesLoaded: true,
contain: true,
wrapAround: true,
cellAlign: 'left',
setGallerySize: false,
accessibility: true,
prevNextButtons: false,
pageDots: false,
selectedAttraction: 0.02,
hash: true
}
}
var CH = {
init: function () {
this.playerEvents()
this.bind()
this.progress()
},
playerEvents: function () {
slider.on('select.flickity', function (event, index) {
$('#audio').attr('src', 'assets/mp3/' + $('.slide').eq(index).attr('id') + '.mp3')
$('#id div, #title div').hide()
$('#id div').eq(index).show()
$('#title div').eq(index).show()
$('#playpause').text('PLAY')
}).on('change.flickity', function (event, index) {
options.stopped == false ? (audio.play(), $('#playpause').text('PAUSE')) : (audio.pause(), $('#playpause').text('PLAY'))
}).on('staticClick.flickity', function (event, pointer, cellElement, cellIndex) {
if (typeof cellIndex == 'number') {
slider.flickity('selectCell', cellIndex);
}
})
$(window).on('load resize', function () {
if (matchMedia('screen and (max-width: 600px)').matches) {
slider.flickity({
cellAlign: 'center'
})
} else {
slider.flickity({
cellAlign: 'left'
})
}
slider.flickity('resize')
})
},
addZero: function (i) {
return i < 10 ? '0' + i : i;
},
timestamp: function (t) {
t = Math.floor(t)
var s = t % 60
var m = Math.floor(t / 60)
return this.addZero(m) + ':' + this.addZero(s)
},
progress: function () {
console.log(this.timestamp(audio.currentTime))
var dur = (audio.currentTime / audio.duration) * 100
$('#a').css('width', dur + '%')
$('#time').html(this.timestamp(audio.currentTime))
audio.paused ? options.stopped = true : options.stopped = false
window.requestAnimationFrame(this.progress)
},
seek: function (e) {
if (e.type === 'click') {
options.seeking = true;
$('#playpause').text('PAUSE')
audio.play()
}
if (options.seeking && (e.buttons > 0 || e.type == 'click') && !audio.paused) {
var percent = e.offsetX / $(this).width()
audio.currentTime = percent * audio.duration
audio.volume = 0
} else {
audio.volume = 1
}
},
playPause: function () {
audio.paused ? (audio.play(), $('#playpause').text('PAUSE')) : (audio.pause(), $('#playpause').text('PLAY'));
},
menu: function () {
if ($('#menu').hasClass('open')) {
$('#menu').removeClass('open');
$('#menu').css({
right: '-100%',
opacity: '0'
});
audio.animate({ volume: 1 })
$('#menu-btn').removeClass('active')
} else {
$('#menu').addClass('open');
$('#menu').css({
right: '0',
opacity: '1'
});
audio.animate({ volume: 0.5 })
$('#menu-btn').addClass('active')
}
},
bind: function () {
$('#progress').on('click', this.seek)
$('#progress').on('mousemove', this.seek)
$('#progress').on('mouseleave', function () {
options.seeking = false
})
$('#playpause').on('click', this.playPause)
audio.onended = () => {
slider.flickity('next')
$('#playpause').text('PAUSE')
audio.play()
}
$('#menu-btn, #close').on('click', this.menu)
$('#nav a').on('click', function () {
$(this).addClass('active').siblings('.active').removeClass('active');
$('#content div').eq($(this).index()).fadeIn(250).siblings(this).hide();
})
}
}
var audio = $('#audio')[0]
var slider = $('#hae').flickity(options.sliderOptions)
CH.init()
});
Any help would be much appreciated.
Thanks!
When you call window.requestAnimationFrame(this.progress) the function will be called later with this pointing to the window object. Try changing
window.requestAnimationFrame(this.progress);
to
let self = this;
window.requestAnimationFrame(function(){
self.progress()
});

Using Classes in Vue.js

I'm relatively new to Vue, so if this is a stupid question I apologize.
Is it possible to use either ES6 classes or a class function in a Vue object? I'm trying to implement an AI for my Tic-Tac-Toe project using the Minimax algorithm, and I need to make a constructor for my States. But in the Vue object, references to 'this' refer to the Vue object itself, even when wrapped in a class function it would seem. So I'm wondering how I could get around this, or if there is an easier way to accomplish this. Thanks!
Here is the link I'm using for the Minimax algo.
And the link to my Codepen.
console.clear();
const log = console.log.bind(console);
const game = new Vue({
el: '#app',
data: {
turn: 'X',
counter: 0,
winner: '',
started: false,
over: false,
header: {
X: 'color',
O: ''
},
sound() {
const tick = new Audio('https://dl.getdropbox.com/s/kgqqnei0yhv3r8n/219069__annabloom__click1.wav')
if(this.over)
tick.play();
},
board: [[{val:'',bg:''}, {val:'',bg:''}, {val:'',bg:''}],
[{val:'',bg:''}, {val:'',bg:''}, {val:'',bg:''}],
[{val:'',bg:''}, {val:'',bg:''}, {val:'',bg:''}]],
windex: [[[0,0], [0,1], [0,2]],
[[1,0], [1,1], [1,2]],
[[2,0], [2,1], [2,2]],
[[0,0], [1,0], [2,0]],
[[0,1], [1,1], [2,1]],
[[0,2], [1,2], [2,2]],
[[0,0], [1,1], [2,2]],
[[0,2], [1,1], [2,0]]],
arr() {
return this.board.map( x => x.map( y => y.val ));
},
winArr() {
return this.windex.map( x => x.map( y => this.board[y[0]][y[1]].val ));
},
check() {
const winArr = this.winArr();
const checkWindex = winArr.map( (x,ind) => {
if( x.every( y => y == 'X' )) return 'X';
if( x.every( y => y == 'O' )) return 'O';
});
if(checkWindex.includes('X'))
this.setWin('X',checkWindex)
else if(checkWindex.includes('O'))
this.setWin('O',checkWindex)
else if(this.counter == 9) {
this.winner = 'DRAW';
setTimeout(() => this.over = true, 0);
};
}
},
methods: {
mark(box) {
this.header[this.turn] = 'color';
if(this.over) return
if(box.val === ''){
box.val = this.turn;
this.turn = this.turn == 'X' ? 'O' : 'X';
}
this.counter++;
this.check();
this.header.X = this.turn == 'X' ? 'color' : '';
this.header.O = this.turn == 'O' ? 'color' : '';
},
setWin(val,arr) {
const inds = this.windex[arr.indexOf(val)];
inds.forEach( x => {
this.board[x[0]][x[1]].bg = 'active';
});
this.winner = val;
setTimeout(() => this.over = true, 0);
},
start(mode) {
this.started = true;
this.counter = 0;
this.board.map( x => x.map( y => { y.val = ''; y.bg = '' }));
this.over = false;
}
}
});

How does the new Apple page fade in the image?

Apple changed their home page with a fade in effect that loads fast. Is this HTML 5 or jQuery?
Does anyone know how they did this?
It is JavaScript. HTML5 is a markup language - it doesn't do dynamic things. But the way people are throwing around the term, you'd think it could cure world hunger.
It looks like they use the Prototype library - probably for legacy reasons, now that jQuery has gained more traction. Or maybe they just prefer that library.
In plain JavaScript, you can fade a div with window.setInterval() and animating style.opacity.
With this bit of javascript --> http://images.apple.com/global/scripts/ac_blackout.js.
Here it is after a run through http://jsbeautifier.org/:
AC.Blackout = Class.create({
defaultOptions: {
duration: 1.25,
delay: 2,
showOnce: false,
showWhenReferredByApple: true
},
initialize: function (c, a, b) {
this.uniqueIdentifier = a || Math.floor(Math.random() * 1000000);
this.options = Object.extend(Object.clone(this.defaultOptions), b);
if (!this.shouldShow()) {
return false
}
this._addBodyClass();
Event.onDOMReady(function () {
this.og = {};
this.og.element = $(c);
this.bo = {};
this.bo.offsets = this.og.element ? this.og.element.cumulativeOffset() : [0, 0];
this.images = [];
if (this.options.showOnce) {
this._setHasShown()
}
this._create();
this.fade.bind(this).delay(this.options.delay)
}.bind(this))
},
addImage: function (b, a) {
this.preloadImage(b);
if ( !! this._acceptImages) {
this._addImage(false, b, a)
} else {
this._boundAddImage = this._addImage.bindAsEventListener(this, b, a);
Event.observe(document.body, "ACBlackout:acceptImages", this._boundAddImage)
}
},
preloadImage: function (c) {
var b = function (d) {
delete a
};
var a = new Image();
a.onload = b;
a.src = c
},
_addImage: function (a, c, b) {
if (typeof this.images == "undefined") {
return false
}
this.images.push(new AC.Blackout.Image(this.bo, c, b))
},
wasReferredByApple: function () {
if (typeof this._wasReferredByApple !== "undefined") {
return this._wasReferredByApple
}
this._wasReferredByApple = document.referrer.match(/^\w*:\/\/[^\.]*.apple.com/);
if ( !! document.referrer.match(/\/home/)) {
return false
}
return this._wasReferredByApple
},
shouldShow: function () {
if (typeof this._shouldShow !== "undefined") {
return this._shouldShow
}
if (/msie|MSIE 6/.test(navigator.userAgent)) {
return this._shouldShow = false
}
this._shouldShow = true;
if (this.options.showOnce) {
if (!this.options.showWhenReferredByApple) {
if (!this.wasReferredByApple()) {
return this._shouldShow = true
}
}
try {
typeof localStorage
} catch (b) {
return this._shouldShow = false
}
if (typeof localStorage !== "undefined") {
try {
var a = localStorage.getItem("ACBlackout-" + this.uniqueIdentifier);
this._shouldShow = (a == null) ? true : false
} catch (b) {
return this._shouldShow = false
}
} else {
if ("addBehavior" in document.body) {
document.body.addBehavior("#default#userData");
document.body.load("ACBlackout");
this._shouldShow = document.body.getAttribute("ACBlackout-" + this.uniqueIdentifier) == null ? true : false
}
}
} else {
if (!this.options.showWhenReferredByApple) {
if ( !! this.wasReferredByApple()) {
this._shouldShow = false
}
}
}
return this._shouldShow
},
_addBodyClass: function () {
document.body.className += " ACBlackoutBody"
},
_setHasShown: function () {
var a = new Date;
a = a.getTime();
try {
typeof localStorage
} catch (b) {
return true
}
if (typeof localStorage !== "undefined") {
try {
localStorage.setItem("ACBlackout-" + this.uniqueIdentifier, a)
} catch (b) {
return true
}
} else {
if ("addBehavior" in document.body) {
document.body.addBehavior("#default#userData");
document.body.setAttribute("ACBlackout-" + this.uniqueIdentifier, a);
document.body.save("ACBlackout");
return true
} else {
return true
}
}
},
_create: function () {
this.bo.height = document.documentElement.clientHeight > document.body.scrollHeight ? document.documentElement.clientHeight : document.body.scrollHeight;
if ($("ACBlackout")) {
this.bo.element = $("ACBlackout")
} else {
this.bo.element = new Element("div", {
id: "ACBlackout",
"class": "ACBlackout",
style: "height: " + this.bo.height + "px;"
})
}
this._acceptImages = true;
Event.fire(document.body, "ACBlackout:acceptImages", true);
if (AC.Detector.isCSSAvailable("transition")) {
this.bo.element.setVendorPrefixStyle("transition", this.options.duration + "s opacity ease-in")
}
if (AC.Detector.isIE()) {
Element.insert(document.body, {
bottom: this.bo.element
})
} else {
Element.insert(document.body, {
top: this.bo.element
})
}
Element.removeClassName(document.body, "ACBlackoutBody")
},
fade: function () {
if (AC.Detector.isCSSAvailable("transition")) {
var b = function (c) {
c.target.hide();
c.target.removeVendorEventListener("transitionEnd", a)
};
var a = b.bindAsEventListener(this);
this.bo.element.addVendorEventListener("transitionEnd", a);
this.bo.element.setStyle("opacity: 0;")
} else {
this.bo.element.fade({
duration: this.options.duration
})
}
}
});
AC.Blackout.Image = Class.create({
defaultOptions: {
offsets: [0, 0],
dimensions: false,
duration: 0.75,
delay: 0
},
initialize: function (b, c, a) {
this.options = Object.extend(Object.clone(this.defaultOptions), a);
this.bo = b;
this.src = c;
this._create();
this.fadeIn.bind(this).delay(this.options.delay)
},
_create: function () {
this.left = this.options.offsets[0];
this.top = this.bo.offsets[1] + this.options.offsets[1];
this.main = new Element("div", {
"class": "ACBlackoutMain"
});
this.img = new Element("img", {
src: this.src,
"class": "ACBlackoutImg",
style: "top: " + this.top + "px; left: " + this.left + "px;"
});
if (this.options.dimensions) {
this.img.setStyle("width: " + this.options.dimensions[0] + "px; height: " + this.options.dimensions[1] + "px;")
}
if (AC.Detector.isCSSAvailable("transition")) {
this.img.setStyle("opacity: 0");
this.img.setVendorPrefixStyle("transition", this.options.duration + "s opacity ease-in")
} else {
this.img.hide()
}
this.bo.element.insert(this.main);
this.main.insert(this.img)
},
fadeIn: function () {
if (AC.Detector.isCSSAvailable("transition")) {
this.img.setStyle("opacity: 1;")
} else {
this.img.appear({
duration: this.options.duration
})
}
}
});

Categories