Version 3.0.5
This commit is contained in:
1 parent
19b38c7c74
commit
1d4720f3e2
3755 files changed
+508378
-664541
No files matched your search
@@ -0,0 +1,438 @@
|
||||
// CalendarDateSelect version 1.10.11 - a prototype based date picker
|
||||
// Questions, comments, bugs? - see the project page: http://code.google.com/p/calendardateselect
|
||||
if (typeof Prototype == 'undefined') alert("CalendarDateSelect ошибка: Класс-прототип не найден. Пожалуйста убедитесь, что ваше приложение подключает prototype.js (.g. <%= javascript_include_tag :defaults %>) *перед* подключен calendar_date_select.js (.g. <%= calendar_date_select_includes %>).");
|
||||
if (Prototype.Version < "1.6") alert("Требуется класс-прототип 1.6.0. Если используются ранние версии класса- прототипа, используйте calendar_date_select версии 1.8.3");
|
||||
|
||||
Element.addMethods({
|
||||
purgeChildren: function(element) { $A(element.childNodes).each(function(e){$(e).remove();}); },
|
||||
build: function(element, type, options, style) {
|
||||
var newElement = Element.buildAndAppend(type, options, style);
|
||||
element.appendChild(newElement);
|
||||
return newElement;
|
||||
}
|
||||
});
|
||||
|
||||
Element.buildAndAppend = function(type, options, style)
|
||||
{
|
||||
var e = $(document.createElement(type));
|
||||
$H(options).each(function(pair) { eval("e." + pair.key + " = pair.value" ); });
|
||||
if (style)
|
||||
$H(style).each(function(pair) { eval("e.style." + pair.key + " = pair.value" ); });
|
||||
return e;
|
||||
};
|
||||
nil = null;
|
||||
|
||||
Date.one_day = 24*60*60*1000;
|
||||
Date.weekdays = $w("П В С Ч П С В");
|
||||
Date.first_day_of_week = 1;
|
||||
Date.months = $w("Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь" );
|
||||
Date.padded2 = function(hour) { var padded2 = parseInt(hour, 10); if (hour < 10) padded2 = "0" + padded2; return padded2; }
|
||||
Date.prototype.getPaddedMinutes = function() { return Date.padded2(this.getMinutes()); }
|
||||
Date.prototype.getAMPMHour = function() { var hour = this.getHours(); return (hour == 0) ? 12 : (hour > 12 ? hour - 12 : hour ) }
|
||||
Date.prototype.getAMPM = function() { return (this.getHours() < 12) ? "AM" : "PM"; }
|
||||
Date.prototype.stripTime = function() { return new Date(this.getFullYear(), this.getMonth(), this.getDate());};
|
||||
Date.prototype.daysDistance = function(compare_date) { return Math.round((compare_date - this) / Date.one_day); };
|
||||
|
||||
/*Date.prototype.toFormattedString = function(include_time){
|
||||
var hour, str;
|
||||
str = Date.months[this.getMonth()] + " " + this.getDate() + ", " + this.getFullYear();
|
||||
|
||||
if (include_time) { hour = this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() + " " + this.getAMPM() }
|
||||
return str;
|
||||
}*/
|
||||
Date.prototype.toFormattedString = function(include_time)
|
||||
{
|
||||
str = Date.padded2(this.getDate()) + "." + Date.padded2(this.getMonth()+1) + "." + this.getFullYear();
|
||||
if (include_time) { str += " " + this.getHours() + ":" + this.getPaddedMinutes() }
|
||||
return str;
|
||||
}
|
||||
|
||||
Date.parseFormattedString = function(string) { return new Date(string);}
|
||||
Math.floor_to_interval = function(n, i) { return Math.floor(n/i) * i;}
|
||||
window.f_height = function() { return( [window.innerHeight ? window.innerHeight : null, document.documentElement ? document.documentElement.clientHeight : null, document.body ? document.body.clientHeight : null].select(function(x){return x>0}).first()||0); }
|
||||
window.f_scrollTop = function() { return ([window.pageYOffset ? window.pageYOffset : null, document.documentElement ? document.documentElement.scrollTop : null, document.body ? document.body.scrollTop : null].select(function(x){return x>0}).first()||0 ); }
|
||||
|
||||
_translations = {
|
||||
"OK": "OK",
|
||||
"Now": "Сейчас",
|
||||
"Today": "Сегодня"
|
||||
}
|
||||
SelectBox = Class.create();
|
||||
SelectBox.prototype = {
|
||||
initialize: function(parent_element, values, html_options, style_options) {
|
||||
this.element = $(parent_element).build("select", html_options, style_options);
|
||||
this.populate(values);
|
||||
},
|
||||
populate: function(values) {
|
||||
this.element.purgeChildren();
|
||||
var that = this; $A(values).each(function(pair) { if (typeof(pair)!="object") {pair = [pair, pair]}; that.element.build("option", { value: pair[1], innerHTML: pair[0]}) });
|
||||
},
|
||||
setValue: function(value) {
|
||||
var e = this.element;
|
||||
var matched = false;
|
||||
$R(0, e.options.length - 1 ).each(function(i) { if(e.options[i].value==value.toString()) {e.selectedIndex = i; matched = true;}; } );
|
||||
return matched;
|
||||
},
|
||||
getValue: function() { return $F(this.element)}
|
||||
}
|
||||
CalendarDateSelect = Class.create();
|
||||
CalendarDateSelect.prototype = {
|
||||
initialize: function(target_element, options) {
|
||||
this.target_element = $(target_element); // make sure it's an element, not a string
|
||||
if (!this.target_element) { alert("Выбранный элемент " + target_element + " не найден!"); return false;}
|
||||
if (this.target_element.tagName != "INPUT") this.target_element = this.target_element.down("INPUT")
|
||||
|
||||
this.target_element.calendar_date_select = this;
|
||||
this.last_click_at = 0;
|
||||
// initialize the date control
|
||||
this.options = $H({
|
||||
embedded: false,
|
||||
popup: nil,
|
||||
time: false,
|
||||
buttons: true,
|
||||
year_range: 10,
|
||||
close_on_click: nil,
|
||||
minute_interval: 5,
|
||||
popup_by: this.target_element,
|
||||
month_year: "dropdowns",
|
||||
onchange: this.target_element.onchange,
|
||||
valid_date_check: nil
|
||||
}).merge(options || {});
|
||||
this.use_time = this.options.get("time");
|
||||
this.parseDate();
|
||||
this.callback("before_show")
|
||||
this.initCalendarDiv();
|
||||
if(!this.options.get("embedded")) {
|
||||
this.positionCalendarDiv()
|
||||
// set the click handler to check if a user has clicked away from the document
|
||||
Event.observe(document, "mousedown", this.closeIfClickedOut_handler = this.closeIfClickedOut.bindAsEventListener(this));
|
||||
Event.observe(document, "keypress", this.keyPress_handler = this.keyPress.bindAsEventListener(this));
|
||||
}
|
||||
this.callback("after_show")
|
||||
},
|
||||
positionCalendarDiv: function() {
|
||||
var above = false;
|
||||
var c_pos = this.calendar_div.cumulativeOffset(), c_left = c_pos[0], c_top = c_pos[1], c_dim = this.calendar_div.getDimensions(), c_height = c_dim.height, c_width = c_dim.width;
|
||||
var w_top = window.f_scrollTop(), w_height = window.f_height();
|
||||
var e_dim = $(this.options.get("popup_by")).cumulativeOffset(), e_top = e_dim[1], e_left = e_dim[0], e_height = $(this.options.get("popup_by")).getDimensions().height, e_bottom = e_top + e_height;
|
||||
|
||||
if ( (( e_bottom + c_height ) > (w_top + w_height)) && ( e_bottom - c_height > w_top )) above = true;
|
||||
var left_px = e_left.toString() + "px", top_px = (above ? (e_top - c_height ) : ( e_top + e_height )).toString() + "px";
|
||||
|
||||
this.calendar_div.style.left = left_px; this.calendar_div.style.top = top_px;
|
||||
|
||||
this.calendar_div.setStyle({visibility:""});
|
||||
|
||||
// draw an iframe behind the calendar -- ugly hack to make IE 6 happy
|
||||
if(navigator.appName=="Microsoft Internet Explorer") this.iframe = $(document.body).build("iframe", {src: "javascript:false", className: "ie6_blocker"}, { left: left_px, top: top_px, height: c_height.toString()+"px", width: c_width.toString()+"px", border: "0px"})
|
||||
},
|
||||
initCalendarDiv: function() {
|
||||
if (this.options.get("embedded")) {
|
||||
var parent = this.target_element.parentNode;
|
||||
var style = {}
|
||||
} else {
|
||||
var parent = document.body
|
||||
var style = { position:"absolute", visibility: "hidden", left:0, top:0 }
|
||||
}
|
||||
this.calendar_div = $(parent).build('div', {className: "calendar_date_select"}, style);
|
||||
|
||||
var that = this;
|
||||
// create the divs
|
||||
$w("top header body buttons footer bottom").each(function(name) {
|
||||
eval("var " + name + "_div = that." + name + "_div = that.calendar_div.build('div', { className: 'cds_"+name+"' }, { clear: 'left'} ); ");
|
||||
});
|
||||
|
||||
this.initHeaderDiv();
|
||||
this.initButtonsDiv();
|
||||
this.initCalendarGrid();
|
||||
this.updateFooter(" ");
|
||||
|
||||
this.refresh();
|
||||
this.setUseTime(this.use_time);
|
||||
},
|
||||
initHeaderDiv: function() {
|
||||
var header_div = this.header_div;
|
||||
this.close_button = header_div.build("a", { innerHTML: "x", href:"#", onclick:function () { this.close(); return false; }.bindAsEventListener(this), className: "close" });
|
||||
this.next_month_button = header_div.build("a", { innerHTML: ">", href:"#", onclick:function () { this.navMonth(this.date.getMonth() + 1 ); return false; }.bindAsEventListener(this), className: "next" });
|
||||
this.prev_month_button = header_div.build("a", { innerHTML: "<", href:"#", onclick:function () { this.navMonth(this.date.getMonth() - 1 ); return false; }.bindAsEventListener(this), className: "prev" });
|
||||
|
||||
if (this.options.get("month_year")=="dropdowns") {
|
||||
this.month_select = new SelectBox(header_div, $R(0,11).map(function(m){return [Date.months[m], m]}), {className: "month", onchange: function () { this.navMonth(this.month_select.getValue()) }.bindAsEventListener(this)});
|
||||
this.year_select = new SelectBox(header_div, [], {className: "year", onchange: function () { this.navYear(this.year_select.getValue()) }.bindAsEventListener(this)});
|
||||
this.populateYearRange();
|
||||
} else {
|
||||
this.month_year_label = header_div.build("span")
|
||||
}
|
||||
},
|
||||
initCalendarGrid: function() {
|
||||
var body_div = this.body_div;
|
||||
this.calendar_day_grid = [];
|
||||
var days_table = body_div.build("table", { cellPadding: "0px", cellSpacing: "0px", width: "100%" })
|
||||
// make the weekdays!
|
||||
var weekdays_row = days_table.build("thead").build("tr");
|
||||
Date.weekdays.each( function(weekday) {
|
||||
weekdays_row.build("th", {innerHTML: weekday});
|
||||
});
|
||||
|
||||
var days_tbody = days_table.build("tbody")
|
||||
// Make the days!
|
||||
var row_number = 0, weekday;
|
||||
for(var cell_index = 0; cell_index<42; cell_index++)
|
||||
{
|
||||
weekday = (cell_index+Date.first_day_of_week ) % 7;
|
||||
if ( cell_index % 7==0 ) days_row = days_tbody.build("tr", {className: 'row_'+row_number++});
|
||||
(this.calendar_day_grid[cell_index] = days_row.build("td", {
|
||||
calendar_date_select: this,
|
||||
onmouseover: function () { this.calendar_date_select.dayHover(this); },
|
||||
onmouseout: function () { this.calendar_date_select.dayHoverOut(this) },
|
||||
onclick: function() { this.calendar_date_select.updateSelectedDate(this, true); },
|
||||
className: (weekday==0) || (weekday==6) ? " weekend" : "" //clear the class
|
||||
},
|
||||
{ cursor: "pointer" }
|
||||
)).build("div");
|
||||
this.calendar_day_grid[cell_index];
|
||||
}
|
||||
},
|
||||
initButtonsDiv: function()
|
||||
{
|
||||
var buttons_div = this.buttons_div;
|
||||
if (this.options.get("time"))
|
||||
{
|
||||
var blank_time = $A(this.options.get("time")=="mixed" ? [[" - ", ""]] : []);
|
||||
buttons_div.build("span", {innerHTML:"@", className: "at_sign"});
|
||||
|
||||
var t = new Date();
|
||||
this.hour_select = new SelectBox(buttons_div,
|
||||
blank_time.concat($R(0,23).map(function(x) {t.setHours(x); return $A([t.getHours(),x])} )),
|
||||
{
|
||||
calendar_date_select: this,
|
||||
onchange: function() { this.calendar_date_select.updateSelectedDate( { hour: this.value });},
|
||||
className: "hour"
|
||||
}
|
||||
);
|
||||
buttons_div.build("span", {innerHTML:":", className: "seperator"});
|
||||
var that = this;
|
||||
this.minute_select = new SelectBox(buttons_div,
|
||||
blank_time.concat($R(0,59).select(function(x){return (x % that.options.get('minute_interval')==0)}).map(function(x){ return $A([ Date.padded2(x), x]); } ) ),
|
||||
{
|
||||
calendar_date_select: this,
|
||||
onchange: function() { this.calendar_date_select.updateSelectedDate( {minute: this.value }) },
|
||||
className: "minute"
|
||||
}
|
||||
);
|
||||
|
||||
} else if (! this.options.get("buttons")) buttons_div.remove();
|
||||
|
||||
if (this.options.get("buttons")) {
|
||||
buttons_div.build("span", {innerHTML: " "});
|
||||
if (this.options.get("time")=="mixed" || !this.options.get("time")) b = buttons_div.build("a", {
|
||||
innerHTML: _translations["Today"],
|
||||
href: "#",
|
||||
onclick: function() {this.today(false); return false;}.bindAsEventListener(this)
|
||||
});
|
||||
|
||||
if (this.options.get("time")=="mixed") buttons_div.build("span", {innerHTML: " | ", className:"button_seperator"})
|
||||
|
||||
if (this.options.get("time")) b = buttons_div.build("a", {
|
||||
innerHTML: _translations["Now"],
|
||||
href: "#",
|
||||
onclick: function() {this.today(true); return false}.bindAsEventListener(this)
|
||||
});
|
||||
|
||||
if (!this.options.get("embedded"))
|
||||
{
|
||||
buttons_div.build("span", {innerHTML: " "});
|
||||
buttons_div.build("a", { innerHTML: _translations["OK"], href: "#", onclick: function() {this.close(); return false;}.bindAsEventListener(this) });
|
||||
}
|
||||
}
|
||||
},
|
||||
refresh: function ()
|
||||
{
|
||||
this.refreshMonthYear();
|
||||
this.refreshCalendarGrid();
|
||||
|
||||
this.setSelectedClass();
|
||||
this.updateFooter();
|
||||
},
|
||||
refreshCalendarGrid: function () {
|
||||
this.beginning_date = new Date(this.date).stripTime();
|
||||
this.beginning_date.setDate(1);
|
||||
this.beginning_date.setHours(12); // Prevent daylight savings time boundaries from showing a duplicate day
|
||||
var pre_days = this.beginning_date.getDay() // draw some days before the fact
|
||||
if (pre_days < 3) pre_days += 7;
|
||||
this.beginning_date.setDate(1 - pre_days + Date.first_day_of_week);
|
||||
|
||||
var iterator = new Date(this.beginning_date);
|
||||
|
||||
var today = new Date().stripTime();
|
||||
var this_month = this.date.getMonth();
|
||||
vdc = this.options.get("valid_date_check");
|
||||
for (var cell_index = 0;cell_index<42; cell_index++)
|
||||
{
|
||||
day = iterator.getDate(); month = iterator.getMonth();
|
||||
cell = this.calendar_day_grid[cell_index];
|
||||
Element.remove(cell.childNodes[0]); div = cell.build("div", {innerHTML:day});
|
||||
if (month!=this_month) div.className = "other";
|
||||
cell.day = day; cell.month = month; cell.year = iterator.getFullYear();
|
||||
if (vdc) { if (vdc(iterator.stripTime())) cell.removeClassName("disabled"); else cell.addClassName("disabled") };
|
||||
iterator.setDate( day + 1);
|
||||
}
|
||||
|
||||
if (this.today_cell) this.today_cell.removeClassName("today");
|
||||
|
||||
if ( $R( 0, 41 ).include(days_until = this.beginning_date.stripTime().daysDistance(today)) ) {
|
||||
this.today_cell = this.calendar_day_grid[days_until];
|
||||
this.today_cell.addClassName("today");
|
||||
}
|
||||
},
|
||||
refreshMonthYear: function() {
|
||||
var m = this.date.getMonth();
|
||||
var y = this.date.getFullYear();
|
||||
// set the month
|
||||
if (this.options.get("month_year") == "dropdowns")
|
||||
{
|
||||
this.month_select.setValue(m, false);
|
||||
|
||||
var e = this.year_select.element;
|
||||
if (this.flexibleYearRange() && (!(this.year_select.setValue(y, false)) || e.selectedIndex <= 1 || e.selectedIndex >= e.options.length - 2 )) this.populateYearRange();
|
||||
|
||||
this.year_select.setValue(y);
|
||||
|
||||
} else {
|
||||
this.month_year_label.update( Date.months[m] + " " + y.toString() );
|
||||
}
|
||||
},
|
||||
populateYearRange: function() {
|
||||
this.year_select.populate(this.yearRange().toArray());
|
||||
},
|
||||
yearRange: function() {
|
||||
if (!this.flexibleYearRange())
|
||||
return $R(this.options.get("year_range")[0], this.options.get("year_range")[1]);
|
||||
|
||||
var y = this.date.getFullYear();
|
||||
return $R(y - this.options.get("year_range"), y + this.options.get("year_range"));
|
||||
},
|
||||
flexibleYearRange: function() { return (typeof(this.options.get("year_range")) == "number"); },
|
||||
validYear: function(year) { if (this.flexibleYearRange()) { return true;} else { return this.yearRange().include(year);} },
|
||||
dayHover: function(element) {
|
||||
var hover_date = new Date(this.selected_date);
|
||||
hover_date.setYear(element.year); hover_date.setMonth(element.month); hover_date.setDate(element.day);
|
||||
this.updateFooter(hover_date.toFormattedString(this.use_time));
|
||||
},
|
||||
dayHoverOut: function(element) { this.updateFooter(); },
|
||||
clearSelectedClass: function() {if (this.selected_cell) this.selected_cell.removeClassName("selected");},
|
||||
setSelectedClass: function() {
|
||||
if (!this.selection_made) return;
|
||||
this.clearSelectedClass()
|
||||
if ($R(0,42).include( days_until = this.beginning_date.stripTime().daysDistance(this.selected_date.stripTime()) )) {
|
||||
this.selected_cell = this.calendar_day_grid[days_until];
|
||||
this.selected_cell.addClassName("selected");
|
||||
}
|
||||
},
|
||||
reparse: function() { this.parseDate(); this.refresh(); },
|
||||
dateString: function() {
|
||||
return (this.selection_made) ? this.selected_date.toFormattedString(this.use_time) : " ";
|
||||
},
|
||||
parseDate: function()
|
||||
{
|
||||
var value = $F(this.target_element).strip()
|
||||
this.selection_made = (value != "");
|
||||
this.date = value=="" ? NaN : Date.parseFormattedString(this.options.get("date") || value);
|
||||
if (isNaN(this.date)) this.date = new Date();
|
||||
if (!this.validYear(this.date.getFullYear())) this.date.setYear( (this.date.getFullYear() < this.yearRange().start) ? this.yearRange().start : this.yearRange().end);
|
||||
this.selected_date = new Date(this.date);
|
||||
this.use_time = /[0-9]:[0-9]{2}/.exec(value) ? true : false;
|
||||
this.date.setDate(1);
|
||||
},
|
||||
updateFooter:function(text) { if (!text) text = this.dateString(); this.footer_div.purgeChildren(); this.footer_div.build("span", {innerHTML: text }); },
|
||||
updateSelectedDate:function(partsOrElement, via_click) {
|
||||
var parts = $H(partsOrElement);
|
||||
if ((this.target_element.disabled || this.target_element.readOnly) && this.options.get("popup") != "force") return false;
|
||||
if (parts.get("day")) {
|
||||
var t_selected_date = this.selected_date, vdc = this.options.get("valid_date_check");
|
||||
for (var x = 0; x<=3; x++) t_selected_date.setDate(parts.get("day"));
|
||||
t_selected_date.setYear(parts.get("year"));
|
||||
t_selected_date.setMonth(parts.get("month"));
|
||||
|
||||
if (vdc && ! vdc(t_selected_date.stripTime())) { return false; }
|
||||
this.selected_date = t_selected_date;
|
||||
this.selection_made = true;
|
||||
}
|
||||
|
||||
if (!isNaN(parts.get("hour"))) this.selected_date.setHours(parts.get("hour"));
|
||||
if (!isNaN(parts.get("minute"))) this.selected_date.setMinutes( Math.floor_to_interval(parts.get("minute"), this.options.get("minute_interval")) );
|
||||
if (parts.get("hour") === "" || parts.get("minute") === "")
|
||||
this.setUseTime(false);
|
||||
else if (!isNaN(parts.get("hour")) || !isNaN(parts.get("minute")))
|
||||
this.setUseTime(true);
|
||||
|
||||
this.updateFooter();
|
||||
this.setSelectedClass();
|
||||
|
||||
if (this.selection_made) this.updateValue();
|
||||
if (this.closeOnClick()) { this.close(); }
|
||||
if (via_click && !this.options.get("embedded")) {
|
||||
if ((new Date() - this.last_click_at) < 333) this.close();
|
||||
this.last_click_at = new Date();
|
||||
}
|
||||
},
|
||||
closeOnClick: function() {
|
||||
if (this.options.get("embedded")) return false;
|
||||
if (this.options.get("close_on_click")===nil )
|
||||
return (this.options.get("time")) ? false : true
|
||||
else
|
||||
return (this.options.get("close_on_click"))
|
||||
},
|
||||
navMonth: function(month) { (target_date = new Date(this.date)).setMonth(month); return (this.navTo(target_date)); },
|
||||
navYear: function(year) { (target_date = new Date(this.date)).setYear(year); return (this.navTo(target_date)); },
|
||||
navTo: function(date) {
|
||||
if (!this.validYear(date.getFullYear())) return false;
|
||||
this.date = date;
|
||||
this.date.setDate(1);
|
||||
this.refresh();
|
||||
this.callback("after_navigate", this.date);
|
||||
return true;
|
||||
},
|
||||
setUseTime: function(turn_on) {
|
||||
this.use_time = this.options.get("time") && (this.options.get("time")=="mixed" ? turn_on : true) // force use_time to true if time==true && time!="mixed"
|
||||
if (this.use_time && this.selected_date) { // only set hour/minute if a date is already selected
|
||||
var minute = Math.floor_to_interval(this.selected_date.getMinutes(), this.options.get("minute_interval"));
|
||||
var hour = this.selected_date.getHours();
|
||||
|
||||
this.hour_select.setValue(hour);
|
||||
this.minute_select.setValue(minute)
|
||||
} else if (this.options.get("time")=="mixed") {
|
||||
this.hour_select.setValue(""); this.minute_select.setValue("");
|
||||
}
|
||||
},
|
||||
updateValue: function() {
|
||||
var last_value = this.target_element.value;
|
||||
this.target_element.value = this.dateString();
|
||||
if (last_value!=this.target_element.value) this.callback("onchange");
|
||||
},
|
||||
today: function(now) {
|
||||
var d = new Date(); this.date = new Date();
|
||||
var o = $H({ day: d.getDate(), month: d.getMonth(), year: d.getFullYear(), hour: d.getHours(), minute: d.getMinutes()});
|
||||
if ( ! now ) o = o.merge({hour: "", minute:""});
|
||||
this.updateSelectedDate(o, true);
|
||||
this.refresh();
|
||||
},
|
||||
close: function() {
|
||||
if (this.closed) return false;
|
||||
this.callback("before_close");
|
||||
this.target_element.calendar_date_select = nil;
|
||||
Event.stopObserving(document, "mousedown", this.closeIfClickedOut_handler);
|
||||
Event.stopObserving(document, "keypress", this.keyPress_handler);
|
||||
this.calendar_div.remove(); this.closed = true;
|
||||
if (this.iframe) this.iframe.remove();
|
||||
if (this.target_element.type!="hidden") this.target_element.focus();
|
||||
this.callback("after_close");
|
||||
},
|
||||
closeIfClickedOut: function(e) {
|
||||
if (! $(Event.element(e)).descendantOf(this.calendar_div) ) this.close();
|
||||
},
|
||||
keyPress: function(e) {
|
||||
if (e.keyCode==Event.KEY_ESC) this.close();
|
||||
},
|
||||
callback: function(name, param) { if (this.options.get(name)) { this.options.get(name).bind(this.target_element)(param); } }
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// American Format: 12/31/2000 5:00 pm
|
||||
// Thanks, Wes Hays
|
||||
Date.prototype.toFormattedString = function(include_time){
|
||||
str = Date.padded2(this.getMonth() + 1) + '/' +Date.padded2(this.getDate()) + '/' + this.getFullYear();
|
||||
|
||||
if (include_time) { hour=this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() + " " + this.getAMPM() }
|
||||
return str;
|
||||
}
|
||||
|
||||
Date.parseFormattedString = function (string) {
|
||||
// Test these with and without the time
|
||||
// 11/11/1111 12pm
|
||||
// 11/11/1111 1pm
|
||||
// 1/11/1111 10:10pm
|
||||
// 11/1/1111 01pm
|
||||
// 1/1/1111 01:11pm
|
||||
// 1/1/1111 1:11pm
|
||||
var regexp = "(([0-1]?[0-9])\/[0-3]?[0-9]\/[0-9]{4}) *([0-9]{1,2}(:[0-9]{2})? *(am|pm))?";
|
||||
var d = string.match(new RegExp(regexp, "i"));
|
||||
if (d==null) {
|
||||
return Date.parse(string); // Give javascript a chance to parse it.
|
||||
}
|
||||
|
||||
mdy = d[1].split('/');
|
||||
hrs = 0;
|
||||
mts = 0;
|
||||
if(d[3] != null) {
|
||||
hrs = parseInt(d[3].split('')[0], 10);
|
||||
if(d[5].toLowerCase() == 'pm') { hrs += 12; } // Add 12 more to hrs
|
||||
mts = d[4].split(':')[1];
|
||||
}
|
||||
|
||||
return new Date(mdy[2], parseInt(mdy[0], 10)-1, mdy[1], hrs, mts, 0);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// DB No Seconds Format: 2007-12-05 12:00
|
||||
|
||||
Date.padded2 = function(hour) { padded2 = hour.toString(); if ((parseInt(hour) < 10) || (parseInt(hour) == null)) padded2="0" + padded2; return padded2; }
|
||||
Date.prototype.getAMPMHour = function() { hour=Date.padded2(this.getHours()); return (hour == null) ? 00 : (hour > 24 ? hour - 24 : hour ) }
|
||||
Date.prototype.getAMPM = function() { return (this.getHours() < 12) ? "" : ""; }
|
||||
|
||||
Date.prototype.toFormattedString = function(include_time){
|
||||
str = this.getFullYear() + "-" + (this.getMonth() + 1) + "-" + Date.padded2(this.getDate());
|
||||
if (include_time) { hour=this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() }
|
||||
return str;
|
||||
}
|
||||
|
||||
Date.parseFormattedString = function (string) {
|
||||
var regexp = '([0-9]{4})-(([0-9]{1,2})-(([0-9]{1,2})( ([0-9]{1,2}):([0-9]{2})? *)?)?)?';
|
||||
var d = string.match(new RegExp(regexp, "i"));
|
||||
if (d==null) return Date.parse(string); // at least give javascript a crack at it.
|
||||
var offset = 0;
|
||||
var date = new Date(d[1], 0, 1);
|
||||
if (d[3]) { date.setMonth(d[3] - 1); }
|
||||
if (d[5]) { date.setDate(d[5]); }
|
||||
if (d[7]) {
|
||||
date.setHours(parseInt(d[7], 10));
|
||||
}
|
||||
if (d[8]) { date.setMinutes(d[8]); }
|
||||
if (d[10]) { date.setSeconds(d[10]); }
|
||||
return date;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Formats date and time as "01 January 2000 17:00"
|
||||
Date.prototype.toFormattedString = function(include_time)
|
||||
{
|
||||
str = Date.padded2(this.getDate()) + " " + Date.months[this.getMonth()] + " " + this.getFullYear();
|
||||
if (include_time) { str += " " + this.getHours() + ":" + this.getPaddedMinutes() }
|
||||
return str;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Formats date and time as "2000.01.20 17:00"
|
||||
Date.prototype.toFormattedString = function(include_time)
|
||||
{
|
||||
str = this.getFullYear() + "." + Date.padded2(this.getMonth()+1) + "." + Date.padded2(this.getDate());
|
||||
if (include_time) { str += " " + this.getHours() + ":" + this.getPaddedMinutes() }
|
||||
return str;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
Date.padded2 = function(hour) { padded2 = hour.toString(); if ((parseInt(hour) < 10) || (parseInt(hour) == null)) padded2="0" + padded2; return padded2; }
|
||||
Date.prototype.getAMPMHour = function() { hour=Date.padded2(this.getHours()); return (hour == null) ? 00 : (hour > 24 ? hour - 24 : hour ) }
|
||||
Date.prototype.getAMPM = function() { return (this.getHours() < 12) ? "" : ""; }
|
||||
|
||||
Date.prototype.toFormattedString = function(include_time){
|
||||
str = this.getDate() + "." + (this.getMonth() + 1) + "." + this.getFullYear();
|
||||
if (include_time) { hour=this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() }
|
||||
return str;
|
||||
}
|
||||
Date.parseFormattedString = function (string) {
|
||||
var regexp = '([0-9]{1,2})\.(([0-9]{1,2})\.(([0-9]{4})( ([0-9]{1,2}):([0-9]{2})? *)?)?)?';
|
||||
var d = string.match(new RegExp(regexp, "i"));
|
||||
if (d==null) return Date.parse(string); // at least give javascript a crack at it.
|
||||
var offset = 0;
|
||||
var date = new Date(d[5], 0, 1);
|
||||
if (d[3]) { date.setMonth(d[3] - 1); }
|
||||
if (d[5]) { date.setDate(d[1]); }
|
||||
if (d[7]) {
|
||||
date.setHours(parseInt(d[7], 10));
|
||||
}
|
||||
if (d[8]) { date.setMinutes(d[8]); }
|
||||
if (d[10]) { date.setSeconds(d[10]); }
|
||||
return date;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
Date.prototype.toFormattedString = function(include_time){
|
||||
str = this.getFullYear() + "-" + Date.padded2(this.getMonth() + 1) + "-" +Date.padded2(this.getDate());
|
||||
|
||||
if (include_time) { hour=this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() + " " + this.getAMPM() }
|
||||
return str;
|
||||
}
|
||||
|
||||
Date.parseFormattedString = function (string) {
|
||||
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
|
||||
"( ([0-9]{1,2}):([0-9]{2})? *(pm|am)" +
|
||||
"?)?)?)?";
|
||||
var d = string.match(new RegExp(regexp, "i"));
|
||||
if (d==null) return Date.parse(string); // at least give javascript a crack at it.
|
||||
var offset = 0;
|
||||
var date = new Date(d[1], 0, 1);
|
||||
if (d[3]) { date.setMonth(d[3] - 1); }
|
||||
if (d[5]) { date.setDate(d[5]); }
|
||||
if (d[7]) {
|
||||
hours = parseInt(d[7], 10);
|
||||
offset=0;
|
||||
is_pm = (d[9].toLowerCase()=="pm")
|
||||
if (is_pm && hours <= 11) hours+=12;
|
||||
if (!is_pm && hours == 12) hours=0;
|
||||
date.setHours(hours);
|
||||
|
||||
}
|
||||
if (d[8]) { date.setMinutes(d[8]); }
|
||||
if (d[10]) { date.setSeconds(d[10]); }
|
||||
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
|
||||
if (d[14]) {
|
||||
offset = (Number(d[16]) * 60) + Number(d[17]);
|
||||
offset *= ((d[15] == '-') ? 1 : -1);
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
Date.prototype.toFormattedString = function(include_time) {
|
||||
var hour;
|
||||
var str = this.getFullYear() + "-" + Date.padded2(this.getMonth() + 1) + "-" +Date.padded2(this.getDate());
|
||||
if (include_time) {
|
||||
hour = this.getHours();
|
||||
str += " " + this.getHours() + ":" + this.getPaddedMinutes();
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
Date.parseFormattedString = function (string) {
|
||||
|
||||
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
|
||||
"( ([0-9]{1,2}):([0-9]{2})?" +
|
||||
"?)?)?)?";
|
||||
|
||||
var d = string.match(new RegExp(regexp, "i"));
|
||||
if (d === null) {
|
||||
return Date.parse(string); // at least give javascript a crack at it.
|
||||
}
|
||||
var offset = 0;
|
||||
var date = new Date(d[1], 0, 1);
|
||||
if (d[3]) {
|
||||
date.setMonth(d[3] - 1);
|
||||
}
|
||||
if (d[5]) {
|
||||
date.setDate(d[5]);
|
||||
}
|
||||
if (d[7]) {
|
||||
date.setHours(d[7]);
|
||||
}
|
||||
if (d[8]) {
|
||||
date.setMinutes(d[8]);
|
||||
}
|
||||
if (d[0]) {
|
||||
date.setSeconds(d[0]);
|
||||
}
|
||||
if (d[2]) {
|
||||
date.setMilliseconds(Number("0." + d[2]));
|
||||
}
|
||||
if (d[4]) {
|
||||
offset = (Number(d[6])) + Number(d[8]);
|
||||
offset = ((d[5] == '-') ? 1 : -1);
|
||||
}
|
||||
return date;
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
// Italian Format: 31/12/2000 23:00
|
||||
// Thanks, Bigonazzi!
|
||||
|
||||
Date.prototype.toFormattedString = function(include_time){
|
||||
str = this.getDate() + "/" + (this.getMonth() + 1) + "/" + this.getFullYear();
|
||||
if (include_time) { hour=this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() }
|
||||
return str;
|
||||
}
|
||||
|
||||
Date.parseFormattedString = function (string) {
|
||||
var regexp = '([0-9]{1,2})/(([0-9]{1,2})/(([0-9]{4})( ([0-9]{1,2}):([0-9]{2})? *)?)?)?';
|
||||
var d = string.match(new RegExp(regexp, "i"));
|
||||
if (d==null) return Date.parse(string); // at least give javascript a crack at it.
|
||||
var offset = 0;
|
||||
var date = new Date(d[5], 0, 1);
|
||||
if (d[3]) { date.setMonth(d[3] - 1); }
|
||||
if (d[5]) { date.setDate(d[1]); }
|
||||
if (d[7]) {
|
||||
date.setHours(parseInt(d[7], 10));
|
||||
}
|
||||
if (d[8]) { date.setMinutes(d[8]); }
|
||||
if (d[10]) { date.setSeconds(d[10]); }
|
||||
return date;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -0,0 +1,10 @@
|
||||
Date.weekdays = $w("Ma Ti Ke To Pe La Su");
|
||||
Date.months = $w("Tammikuu Helmikuu Maaliskuu Huhtikuu Toukokuu Kesäkuu Heinäkuu Elokuu Syyskuu Lokakuu Marraskuu Joulukuu" );
|
||||
|
||||
Date.first_day_of_week = 1
|
||||
|
||||
_translations = {
|
||||
"OK": "OK",
|
||||
"Now": "Nyt",
|
||||
"Today": "Tänään"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
Date.weekdays = $w('L Ma Me J V S D');
|
||||
Date.months = $w('Janvier Février Mars Avril Mai Juin Juillet Août Septembre Octobre Novembre Décembre');
|
||||
|
||||
Date.first_day_of_week = 1;
|
||||
|
||||
_translations = {
|
||||
"OK": "OK",
|
||||
"Now": "Maintenant",
|
||||
"Today": "Aujourd'hui"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
@@ -0,0 +1,10 @@
|
||||
Date.weekdays = $w('P W Ś C P S N');
|
||||
Date.months = $w('Styczeń Luty Marzec Kwiecień Maj Czerwiec Lipiec Sierpień Wrzesień Październik Listopad Grudzień');
|
||||
|
||||
Date.first_day_of_week = 1
|
||||
|
||||
_translations = {
|
||||
"OK": "OK",
|
||||
"Now": "Teraz",
|
||||
"Today": "Dziś"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
Date.weekdays = $w('D S T Q Q S S');
|
||||
Date.months = $w('Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Novembro Dezembro');
|
||||
|
||||
Date.first_day_of_week = 0
|
||||
|
||||
_translations = {
|
||||
"OK": "OK",
|
||||
"Now": "Agora",
|
||||
"Today": "Hoje"
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// -----------------------------------------------------------------------------------
|
||||
//
|
||||
// Lightbox v2.04
|
||||
// by Lokesh Dhakar - http://www.lokeshdhakar.com
|
||||
// Last Modification: 2/9/08
|
||||
//
|
||||
// For more information, visit:
|
||||
// http://lokeshdhakar.com/projects/lightbox2/
|
||||
//
|
||||
// Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
|
||||
// - Free for use in both personal and commercial projects
|
||||
// - Attribution requires leaving author name, author link, and the license info intact.
|
||||
//
|
||||
// Thanks: Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), and Thomas Fuchs(mir.aculo.us) for ideas, libs, and snippets.
|
||||
// Artemy Tregubenko (arty.name) for cleanup and help in updating to latest ver of proto-aculous.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------
|
||||
var Lightbox=Class.create();Lightbox.prototype={imageArray:[],activeImage:undefined,initialize:function(){this.updateImageList();this.keyboardAction=this.keyboardAction.bindAsEventListener(this);if(LightboxOptions.resizeSpeed>10)LightboxOptions.resizeSpeed=10;if(LightboxOptions.resizeSpeed<1)LightboxOptions.resizeSpeed=1;this.resizeDuration=LightboxOptions.animate?((11-LightboxOptions.resizeSpeed)*0.15):0;this.overlayDuration=LightboxOptions.animate?0.2:0;var size=(LightboxOptions.animate?250:1)+'px';var objBody=$$('body')[0];objBody.appendChild(Builder.node('div',{id:'overlay'}));objBody.appendChild(Builder.node('div',{id:'lightbox'},[Builder.node('div',{id:'outerImageContainer'},Builder.node('div',{id:'imageContainer'},[Builder.node('img',{id:'lightboxImage'}),Builder.node('div',{id:'hoverNav'},[Builder.node('a',{id:'prevLink',href:'#'}),Builder.node('a',{id:'nextLink',href:'#'})]),Builder.node('div',{id:'loading'},Builder.node('a',{id:'loadingLink',href:'#'},Builder.node('img',{src:LightboxOptions.fileLoadingImage})))])),Builder.node('div',{id:'imageDataContainer'},Builder.node('div',{id:'imageData'},[Builder.node('div',{id:'imageDetails'},[Builder.node('span',{id:'caption'}),Builder.node('span',{id:'numberDisplay'})]),Builder.node('div',{id:'bottomNav'},Builder.node('a',{id:'bottomNavClose',href:'#'},Builder.node('img',{src:LightboxOptions.fileBottomNavCloseImage})))]))]));$('overlay').hide().observe('click',(function(){this.end();}).bind(this));$('lightbox').hide().observe('click',(function(event){if(event.element().id=='lightbox')this.end();}).bind(this));$('outerImageContainer').setStyle({width:size,height:size});$('prevLink').observe('click',(function(event){event.stop();this.changeImage(this.activeImage-1);}).bindAsEventListener(this));$('nextLink').observe('click',(function(event){event.stop();this.changeImage(this.activeImage+1);}).bindAsEventListener(this));$('loadingLink').observe('click',(function(event){event.stop();this.end();}).bind(this));$('bottomNavClose').observe('click',(function(event){event.stop();this.end();}).bind(this));var th=this;(function(){var ids='overlay lightbox outerImageContainer imageContainer lightboxImage hoverNav prevLink nextLink loading loadingLink '+'imageDataContainer imageData imageDetails caption numberDisplay bottomNav bottomNavClose';$w(ids).each(function(id){th[id]=$(id);});}).defer();},updateImageList:function(){this.updateImageList=Prototype.emptyFunction;document.observe('click',(function(event){var target=event.findElement('a[rel^=lightbox]')||event.findElement('area[rel^=lightbox]');if(target){event.stop();this.start(target);}}).bind(this));},start:function(imageLink){$$('select','object','embed').each(function(node){node.style.visibility='hidden'});var arrayPageSize=this.getPageSize();$('overlay').setStyle({width:arrayPageSize[0]+'px',height:arrayPageSize[1]+'px'});new Effect.Appear(this.overlay,{duration:this.overlayDuration,from:0.0,to:LightboxOptions.overlayOpacity});this.imageArray=[];var imageNum=0;if((imageLink.rel=='lightbox')){this.imageArray.push([imageLink.href,imageLink.title]);}else{this.imageArray=$$(imageLink.tagName+'[href][rel="'+imageLink.rel+'"]').collect(function(anchor){return[anchor.href,anchor.title];}).uniq();while(this.imageArray[imageNum][0]!=imageLink.href){imageNum++;}}
|
||||
var arrayPageScroll=document.viewport.getScrollOffsets();var lightboxTop=arrayPageScroll[1]+(document.viewport.getHeight()/10);var lightboxLeft=arrayPageScroll[0];this.lightbox.setStyle({top:lightboxTop+'px',left:lightboxLeft+'px'}).show();this.changeImage(imageNum);},changeImage:function(imageNum){this.activeImage=imageNum;if(LightboxOptions.animate)this.loading.show();this.lightboxImage.hide();this.hoverNav.hide();this.prevLink.hide();this.nextLink.hide();this.imageDataContainer.setStyle({opacity:.0001});this.numberDisplay.hide();var imgPreloader=new Image();imgPreloader.onload=(function(){this.lightboxImage.src=this.imageArray[this.activeImage][0];this.resizeImageContainer(imgPreloader.width,imgPreloader.height);}).bind(this);imgPreloader.src=this.imageArray[this.activeImage][0];},resizeImageContainer:function(imgWidth,imgHeight){var widthCurrent=this.outerImageContainer.getWidth();var heightCurrent=this.outerImageContainer.getHeight();var widthNew=(imgWidth+LightboxOptions.borderSize*2);var heightNew=(imgHeight+LightboxOptions.borderSize*2);var xScale=(widthNew/widthCurrent)*100;var yScale=(heightNew/heightCurrent)*100;var wDiff=widthCurrent-widthNew;var hDiff=heightCurrent-heightNew;if(hDiff!=0)new Effect.Scale(this.outerImageContainer,yScale,{scaleX:false,duration:this.resizeDuration,queue:'front'});if(wDiff!=0)new Effect.Scale(this.outerImageContainer,xScale,{scaleY:false,duration:this.resizeDuration,delay:this.resizeDuration});var timeout=0;if((hDiff==0)&&(wDiff==0)){timeout=100;if(Prototype.Browser.IE)timeout=250;}
|
||||
(function(){this.prevLink.setStyle({height:imgHeight+'px'});this.nextLink.setStyle({height:imgHeight+'px'});this.imageDataContainer.setStyle({width:widthNew+'px'});this.showImage();}).bind(this).delay(timeout/1000);},showImage:function(){this.loading.hide();new Effect.Appear(this.lightboxImage,{duration:this.resizeDuration,queue:'end',afterFinish:(function(){this.updateDetails();}).bind(this)});this.preloadNeighborImages();},updateDetails:function(){if(this.imageArray[this.activeImage][1]!=""){this.caption.update(this.imageArray[this.activeImage][1]).show();}
|
||||
if(this.imageArray.length>1){this.numberDisplay.update(LightboxOptions.labelImage+' '+(this.activeImage+1)+' '+LightboxOptions.labelOf+' '+this.imageArray.length).show();}
|
||||
new Effect.Parallel([new Effect.SlideDown(this.imageDataContainer,{sync:true,duration:this.resizeDuration,from:0.0,to:1.0}),new Effect.Appear(this.imageDataContainer,{sync:true,duration:this.resizeDuration})],{duration:this.resizeDuration,afterFinish:(function(){var arrayPageSize=this.getPageSize();this.overlay.setStyle({height:arrayPageSize[1]+'px'});this.updateNav();}).bind(this)});},updateNav:function(){this.hoverNav.show();if(this.activeImage>0)this.prevLink.show();if(this.activeImage<(this.imageArray.length-1))this.nextLink.show();this.enableKeyboardNav();},enableKeyboardNav:function(){document.observe('keydown',this.keyboardAction);},disableKeyboardNav:function(){document.stopObserving('keydown',this.keyboardAction);},keyboardAction:function(event){var keycode=event.keyCode;var escapeKey;if(event.DOM_VK_ESCAPE){escapeKey=event.DOM_VK_ESCAPE;}else{escapeKey=27;}
|
||||
var key=String.fromCharCode(keycode).toLowerCase();if(key.match(/x|o|c/)||(keycode==escapeKey)){this.end();}else if((key=='p')||(keycode==37)){if(this.activeImage!=0){this.disableKeyboardNav();this.changeImage(this.activeImage-1);}}else if((key=='n')||(keycode==39)){if(this.activeImage!=(this.imageArray.length-1)){this.disableKeyboardNav();this.changeImage(this.activeImage+1);}}},preloadNeighborImages:function(){var preloadNextImage,preloadPrevImage;if(this.imageArray.length>this.activeImage+1){preloadNextImage=new Image();preloadNextImage.src=this.imageArray[this.activeImage+1][0];}
|
||||
if(this.activeImage>0){preloadPrevImage=new Image();preloadPrevImage.src=this.imageArray[this.activeImage-1][0];}},end:function(){this.disableKeyboardNav();this.lightbox.hide();new Effect.Fade(this.overlay,{duration:this.overlayDuration});$$('select','object','embed').each(function(node){node.style.visibility='visible'});},getPageSize:function(){var xScroll,yScroll;if(window.innerHeight&&window.scrollMaxY){xScroll=window.innerWidth+window.scrollMaxX;yScroll=window.innerHeight+window.scrollMaxY;}else if(document.body.scrollHeight>document.body.offsetHeight){xScroll=document.body.scrollWidth;yScroll=document.body.scrollHeight;}else{xScroll=document.body.offsetWidth;yScroll=document.body.offsetHeight;}
|
||||
var windowWidth,windowHeight;if(self.innerHeight){if(document.documentElement.clientWidth){windowWidth=document.documentElement.clientWidth;}else{windowWidth=self.innerWidth;}
|
||||
windowHeight=self.innerHeight;}else if(document.documentElement&&document.documentElement.clientHeight){windowWidth=document.documentElement.clientWidth;windowHeight=document.documentElement.clientHeight;}else if(document.body){windowWidth=document.body.clientWidth;windowHeight=document.body.clientHeight;}
|
||||
if(yScroll<windowHeight){pageHeight=windowHeight;}else{pageHeight=yScroll;}
|
||||
if(xScroll<windowWidth){pageWidth=xScroll;}else{pageWidth=windowWidth;}
|
||||
return[pageWidth,pageHeight];}}
|
||||
document.observe('dom:loaded',function(){window.ipsLightbox=new Lightbox();});
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2008 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
* Registers a language handler for SQL.
|
||||
*
|
||||
*
|
||||
* To use, include prettify.js and this file in your HTML page.
|
||||
* Then put your code in an HTML tag like
|
||||
* <pre class="prettyprint lang-sql">(my SQL code)</pre>
|
||||
*
|
||||
*
|
||||
* http://savage.net.au/SQL/sql-99.bnf.html is the basis for the grammar, and
|
||||
* http://msdn.microsoft.com/en-us/library/aa238507(SQL.80).aspx as the basis
|
||||
* for the keyword list.
|
||||
*
|
||||
* @author mikesamuel@gmail.com
|
||||
*/
|
||||
|
||||
PR.registerLangHandler(
|
||||
PR.createSimpleLexer(
|
||||
[
|
||||
// Whitespace
|
||||
[PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'],
|
||||
// A double or single quoted, possibly multi-line, string.
|
||||
[PR.PR_STRING, /^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/, null,
|
||||
'"\'']
|
||||
],
|
||||
[
|
||||
// A comment is either a line comment that starts with two dashes, or
|
||||
// two dashes preceding a long bracketed block.
|
||||
[PR.PR_COMMENT, /^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],
|
||||
[PR.PR_KEYWORD, /^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i, null],
|
||||
// A number is a hex integer literal, a decimal real literal, or in
|
||||
// scientific notation.
|
||||
[PR.PR_LITERAL,
|
||||
/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],
|
||||
// An identifier
|
||||
[PR.PR_PLAIN, /^[a-z_][\w-]*/i],
|
||||
// A run of punctuation
|
||||
[PR.PR_PUNCTUATION, /^[^\w\t\n\r \xA0]+/]
|
||||
]),
|
||||
['sql']);
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2006 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
(function(){
|
||||
var o=true,r=null,z=false;window.PR_SHOULD_USE_CONTINUATION=o;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var N=navigator&&navigator.userAgent&&/\bMSIE 6\./.test(navigator.userAgent);window._pr_isIE6=function(){return N};return N};
|
||||
var aa="!",ba="!=",ca="!==",F="#",da="%",ea="%=",G="&",fa="&&",ja="&&=",ka="&=",H="(",la="*",ma="*=",na="+=",oa=",",pa="-=",qa="->",ra="/",sa="/=",ta=":",ua="::",va=";",I="<",wa="<<",xa="<<=",ya="<=",za="=",Aa="==",Ba="===",J=">",Ca=">=",Da=">>",Ea=">>=",Fa=">>>",Ga=">>>=",Ha="?",Ia="@",L="[",M="^",Ta="^=",Ua="^^",Va="^^=",Wa="{",O="|",Xa="|=",Ya="||",Za="||=",$a="~",ab="break",bb="case",cb="continue",db="delete",eb="do",fb="else",gb="finally",hb="instanceof",ib="return",jb="throw",kb="try",lb="typeof",
|
||||
mb="(?:^^|[+-]",nb="\\$1",ob=")\\s*",pb="&",qb="<",rb=">",sb=""",tb="&#",ub="x",vb="'",wb='"',xb=" ",yb="XMP",zb="</",Ab='="',P="",Q="\\",Bb="b",Cb="t",Db="n",Eb="v",Fb="f",Gb="r",Hb="u",Ib="0",Jb="1",Kb="2",Lb="3",Mb="4",Nb="5",Ob="6",Pb="7",Qb="\\x0",Rb="\\x",Sb="-",Tb="]",Ub="\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]",R="g",Vb="\\B",Wb="\\b",Xb="\\D",Yb="\\d",Zb="\\S",$b="\\s",ac="\\W",bc="\\w",cc="(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)",
|
||||
dc="(?:",ec=")",fc="gi",gc="PRE",hc='<!DOCTYPE foo PUBLIC "foo bar">\n<foo />',ic="\t",jc="\n",kc="[^<]+|<!--[\\s\\S]*?--\>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z][^>]*>|<",lc="nocode",mc=' $1="$2$3$4"',S="pln",nc="string",T="lang-",oc="src",U="str",pc="'\"",qc="'\"`",rc="\"'",V="com",sc="lang-regex",tc="(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)",uc="kwd",vc="^(?:",wc=")\\b",xc=" \r\n\t\u00a0",yc="lit",zc="typ",Ac="0123456789",Y="pun",Bc="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try debugger eval export function get null set undefined var with Infinity NaN caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END break continue do else for if return while case done elif esac eval fi function in local set then until ",
|
||||
Cc="</span>",Dc='<span class="',Ec='">',Fc="$1 ",Gc=" <br />",Hc="<br />",Ic="console",Jc="cannot override language handler %s",Kc="default-markup",Lc="default-code",Mc="dec",Z="lang-js",$="lang-css",Nc="lang-in.tag",Oc="htm",Pc="html",Qc="mxml",Rc="xhtml",Sc="xml",Tc="xsl",Uc=" \t\r\n",Vc="atv",Wc="tag",Xc="atn",Yc="lang-uq.val",Zc="in.tag",$c="uq.val",ad="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where ",
|
||||
bd="c",cd="cc",dd="cpp",ed="cxx",fd="cyc",gd="m",hd="null true false",id="json",jd="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ",
|
||||
kd="cs",ld="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",md="java",nd="break continue do else for if return while case done elif esac eval fi function in local set then until ",
|
||||
od="bsh",pd="csh",qd="sh",rd="break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",sd="cv",td="py",ud="caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",vd="perl",wd="pl",xd="pm",yd="break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",
|
||||
zd="rb",Ad="break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try debugger eval export function get null set undefined var with Infinity NaN ",Bd="js",Cd="regex",Dd="pre",Ed="code",Fd="xmp",Gd="prettyprint",Hd="class",Id="br",Jd="\r";
|
||||
(function(){var N=function(){for(var a=[aa,ba,ca,F,da,ea,G,fa,ja,ka,H,la,ma,na,oa,pa,qa,ra,sa,ta,ua,va,I,wa,xa,ya,za,Aa,Ba,J,Ca,Da,Ea,Fa,Ga,Ha,Ia,L,M,Ta,Ua,Va,Wa,O,Xa,Ya,Za,$a,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb],b=mb,c=0;c<a.length;++c)b+=O+a[c].replace(/([^=<>:&a-z])/g,nb);b+=ob;return b}(),Ja=/&/g,Ka=/</g,La=/>/g,Kd=/\"/g;function Ld(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb).replace(Kd,sb)}function ga(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb)}var Md=/</g,Nd=/>/g,
|
||||
Od=/'/g,Pd=/"/g,Qd=/&/g,Rd=/ /g;function Sd(a){var b=a.indexOf(G);if(b<0)return a;for(--b;(b=a.indexOf(tb,b+1))>=0;){var c=a.indexOf(va,b);if(c>=0){var d=a.substring(b+3,c),g=10;if(d&&d.charAt(0)===ub){d=d.substring(1);g=16}var i=parseInt(d,g);isNaN(i)||(a=a.substring(0,b)+String.fromCharCode(i)+a.substring(c+1))}}return a.replace(Md,I).replace(Nd,J).replace(Od,vb).replace(Pd,wb).replace(Qd,G).replace(Rd,xb)}function Ma(a){return yb===a.tagName}function W(a,b){switch(a.nodeType){case 1:var c=
|
||||
a.tagName.toLowerCase();b.push(I,c);for(var d=0;d<a.attributes.length;++d){var g=a.attributes[d];if(g.specified){b.push(xb);W(g,b)}}b.push(J);for(var i=a.firstChild;i;i=i.nextSibling)W(i,b);if(a.firstChild||!/^(?:br|link|img)$/.test(c))b.push(zb,c,J);break;case 2:b.push(a.name.toLowerCase(),Ab,Ld(a.value),wb);break;case 3:case 4:b.push(ga(a.nodeValue));break}}function Na(a){for(var b=0,c=z,d=z,g=0,i=a.length;g<i;++g){var m=a[g];if(m.ignoreCase)d=o;else if(/[a-z]/i.test(m.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,
|
||||
P))){c=o;d=z;break}}function l(j){if(j.charAt(0)!==Q)return j.charCodeAt(0);switch(j.charAt(1)){case Bb:return 8;case Cb:return 9;case Db:return 10;case Eb:return 11;case Fb:return 12;case Gb:return 13;case Hb:case ub:return parseInt(j.substring(2),16)||j.charCodeAt(1);case Ib:case Jb:case Kb:case Lb:case Mb:case Nb:case Ob:case Pb:return parseInt(j.substring(1),8);default:return j.charCodeAt(1)}}function n(j){if(j<32)return(j<16?Qb:Rb)+j.toString(16);var f=String.fromCharCode(j);if(f===Q||f===Sb||
|
||||
f===L||f===Tb)f=Q+f;return f}function q(j){for(var f=j.substring(1,j.length-1).match(new RegExp(Ub,R)),s=[],k=[],h=f[0]===M,e=h?1:0,p=f.length;e<p;++e){var t=f[e];switch(t){case Vb:case Wb:case Xb:case Yb:case Zb:case $b:case ac:case bc:s.push(t);continue}var u=l(t),x;if(e+2<p&&Sb===f[e+1]){x=l(f[e+2]);e+=2}else x=u;k.push([u,x]);if(!(x<65||u>122)){x<65||u>90||k.push([Math.max(65,u)|32,Math.min(x,90)|32]);x<97||u>122||k.push([Math.max(97,u)&-33,Math.min(x,122)&-33])}}k.sort(function(Oa,Pa){return Oa[0]-
|
||||
Pa[0]||Pa[1]-Oa[1]});var B=[],E=[NaN,NaN];for(e=0;e<k.length;++e){var A=k[e];if(A[0]<=E[1]+1)E[1]=Math.max(E[1],A[1]);else B.push(E=A)}var D=[L];h&&D.push(M);D.push.apply(D,s);for(e=0;e<B.length;++e){A=B[e];D.push(n(A[0]));if(A[1]>A[0]){A[1]+1>A[0]&&D.push(Sb);D.push(n(A[1]))}}D.push(Tb);return D.join(P)}function v(j){var f=j.source.match(new RegExp(cc,R)),s=f.length,k=[],h,e=0;for(h=0;e<s;++e){var p=f[e];if(p===H)++h;else if(Q===p.charAt(0)){var t=+p.substring(1);if(t&&t<=h)k[t]=-1}}for(e=1;e<k.length;++e)if(-1===
|
||||
k[e])k[e]=++b;for(h=e=0;e<s;++e){p=f[e];if(p===H){++h;if(k[h]===undefined)f[e]=dc}else if(Q===p.charAt(0))if((t=+p.substring(1))&&t<=h)f[e]=Q+k[h]}for(h=e=0;e<s;++e)if(M===f[e]&&M!==f[e+1])f[e]=P;if(j.ignoreCase&&c)for(e=0;e<s;++e){p=f[e];var u=p.charAt(0);if(p.length>=2&&u===L)f[e]=q(p);else if(u!==Q)f[e]=p.replace(/[a-zA-Z]/g,function(x){var B=x.charCodeAt(0);return L+String.fromCharCode(B&-33,B|32)+Tb})}return f.join(P)}var w=[];g=0;for(i=a.length;g<i;++g){m=a[g];if(m.global||m.multiline)throw new Error(P+
|
||||
m);w.push(dc+v(m)+ec)}return new RegExp(w.join(O),d?fc:R)}var ha=r;function Td(a){if(r===ha){var b=document.createElement(gc);b.appendChild(document.createTextNode(hc));ha=!/</.test(b.innerHTML)}if(ha){var c=a.innerHTML;if(Ma(a))c=ga(c);return c}for(var d=[],g=a.firstChild;g;g=g.nextSibling)W(g,d);return d.join(P)}function Ud(a){var b=0;return function(c){for(var d=r,g=0,i=0,m=c.length;i<m;++i){var l=c.charAt(i);switch(l){case ic:d||(d=[]);d.push(c.substring(g,i));var n=a-b%a;for(b+=n;n>=0;n-=" ".length)d.push(" ".substring(0,
|
||||
n));g=i+1;break;case jc:b=0;break;default:++b}}if(!d)return c;d.push(c.substring(g));return d.join(P)}}var Vd=new RegExp(kc,R),Wd=/^<\!--/,Xd=/^<\[CDATA\[/,Yd=/^<br\b/i,Qa=/^<(\/?)([a-zA-Z]+)/;function Zd(a){var b=a.match(Vd),c=[],d=0,g=[];if(b)for(var i=0,m=b.length;i<m;++i){var l=b[i];if(l.length>1&&l.charAt(0)===I){if(!Wd.test(l))if(Xd.test(l)){c.push(l.substring(9,l.length-3));d+=l.length-12}else if(Yd.test(l)){c.push(jc);++d}else if(l.indexOf(lc)>=0&&$d(l)){var n=l.match(Qa)[2],q=1,v;v=i+1;a:for(;v<
|
||||
m;++v){var w=b[v].match(Qa);if(w&&w[2]===n)if(w[1]===ra){if(--q===0)break a}else++q}if(v<m){g.push(d,b.slice(i,v+1).join(P));i=v}else g.push(d,l)}else g.push(d,l)}else{var j=Sd(l);c.push(j);d+=j.length}}return{source:c.join(P),tags:g}}function $d(a){return!!a.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,mc).match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)}function ia(a,b,c,d){if(b){var g={source:b,b:a};c(g);d.push.apply(d,g.c)}}function K(a,b){var c={},d;(function(){for(var m=a.concat(b),
|
||||
l=[],n={},q=0,v=m.length;q<v;++q){var w=m[q],j=w[3];if(j)for(var f=j.length;--f>=0;)c[j.charAt(f)]=w;var s=w[1],k=P+s;if(!n.hasOwnProperty(k)){l.push(s);n[k]=r}}l.push(/[\0-\uffff]/);d=Na(l)})();var g=b.length,i=function(m){for(var l=m.source,n=m.b,q=[n,S],v=0,w=l.match(d)||[],j={},f=0,s=w.length;f<s;++f){var k=w[f],h=j[k],e,p;if(typeof h===nc)p=z;else{var t=c[k.charAt(0)];if(t){e=k.match(t[1]);h=t[0]}else{for(var u=0;u<g;++u){t=b[u];if(e=k.match(t[1])){h=t[0];break}}e||(h=S)}if((p=h.length>=5&&T===
|
||||
h.substring(0,5))&&!(e&&e[1])){p=z;h=oc}p||(j[k]=h)}var x=v;v+=k.length;if(p){var B=e[1],E=k.indexOf(B),A=E+B.length,D=h.substring(5);ia(n+x,k.substring(0,E),i,q);ia(n+x+E,B,Ra(D,B),q);ia(n+x+A,k.substring(A),i,q)}else q.push(n+x,h)}m.c=q};return i}function C(a){var b=[],c=[];if(a.tripleQuotedStrings)b.push([U,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,r,pc]);
|
||||
else a.multiLineStrings?b.push([U,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,r,qc]):b.push([U,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,r,rc]);if(a.hashComments)a.cStyleComments?b.push([V,/^#(?:[^\r\n\/]|\/(?!\*)|\/\*[^\r\n]*?\*\/)*/,r,F]):b.push([V,/^#[^\r\n]*/,r,F]);if(a.cStyleComments){c.push([V,/^\/\/[^\r\n]*/,r]);c.push([V,/^\/\*[\s\S]*?(?:\*\/|$)/,r])}a.regexLiterals&&c.push([sc,new RegExp(M+N+tc)]);var d=
|
||||
a.keywords.replace(/^\s+|\s+$/g,P);d.length&&c.push([uc,new RegExp(vc+d.replace(/\s+/g,O)+wc),r]);b.push([S,/^\s+/,r,xc]);c.push([yc,/^@[a-z_$][a-z_$@0-9]*/i,r,Ia],[zc,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/,r],[S,/^[a-z_$][a-z_$@0-9]*/i,r],[yc,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,r,Ac],[Y,/^.[^\s\w\.$@\'\"\`\/\#]*/,r]);return K(b,c)}var ae=C({keywords:Bc,hashComments:o,cStyleComments:o,multiLineStrings:o,regexLiterals:o});function be(a){var b=a.source,c=a.f,d=a.c,
|
||||
g=[],i=0,m=r,l=r,n=0,q=0,v=Ud(window.PR_TAB_WIDTH),w=/([\r\n ]) /g,j=/(^| ) /gm,f=/\r\n?|\n/g,s=/[ \r\n]$/,k=o;function h(p){if(p>i){if(m&&m!==l){g.push(Cc);m=r}if(!m&&l){m=l;g.push(Dc,m,Ec)}var t=ga(v(b.substring(i,p))).replace(k?j:w,Fc);k=s.test(t);var u=window._pr_isIE6()?Gc:Hc;g.push(t.replace(f,u));i=p}}for(;1;){var e;if(e=n<c.length?q<d.length?c[n]<=d[q]:o:z){h(c[n]);if(m){g.push(Cc);m=r}g.push(c[n+1]);n+=2}else if(q<d.length){h(d[q]);l=d[q+1];q+=2}else break}h(b.length);m&&g.push(Cc);a.a=g.join(P)}
|
||||
var X={};function y(a,b){for(var c=b.length;--c>=0;){var d=b[c];if(X.hasOwnProperty(d))Ic in window&&console.i(Jc,d);else X[d]=a}}function Ra(a,b){a&&X.hasOwnProperty(a)||(a=/^\s*</.test(b)?Kc:Lc);return X[a]}y(ae,[Lc]);y(K([],[[S,/^[^<?]+/],[Mc,/^<!\w[^>]*(?:>|$)/],[V,/^<\!--[\s\S]*?(?:-\->|$)/],[T,/^<\?([\s\S]+?)(?:\?>|$)/],[T,/^<%([\s\S]+?)(?:%>|$)/],[Y,/^(?:<[%?]|[%?]>)/],[T,/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],[Z,/^<script\b[^>]*>([\s\S]+?)<\/script\b[^>]*>/i],[$,/^<style\b[^>]*>([\s\S]+?)<\/style\b[^>]*>/i],
|
||||
[Nc,/^(<\/?[a-z][^<>]*>)/i]]),[Kc,Oc,Pc,Qc,Rc,Sc,Tc]);y(K([[S,/^[\s]+/,r,Uc],[Vc,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,r,rc]],[[Wc,/^^<\/?[a-z](?:[\w:-]*\w)?|\/?>$/],[Xc,/^(?!style\b|on)[a-z](?:[\w:-]*\w)?/],[Yc,/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[Y,/^[=<>\/]+/],[Z,/^on\w+\s*=\s*\"([^\"]+)\"/i],[Z,/^on\w+\s*=\s*\'([^\']+)\'/i],[Z,/^on\w+\s*=\s*([^\"\'>\s]+)/i],[$,/^sty\w+\s*=\s*\"([^\"]+)\"/i],[$,/^sty\w+\s*=\s*\'([^\']+)\'/i],[$,/^sty\w+\s*=\s*([^\"\'>\s]+)/i]]),[Zc]);y(K([],[[Vc,/^[\s\S]+/]]),
|
||||
[$c]);y(C({keywords:ad,hashComments:o,cStyleComments:o}),[bd,cd,dd,ed,fd,gd]);y(C({keywords:hd}),[id]);y(C({keywords:jd,hashComments:o,cStyleComments:o}),[kd]);y(C({keywords:ld,cStyleComments:o}),[md]);y(C({keywords:nd,hashComments:o,multiLineStrings:o}),[od,pd,qd]);y(C({keywords:rd,hashComments:o,multiLineStrings:o,tripleQuotedStrings:o}),[sd,td]);y(C({keywords:ud,hashComments:o,multiLineStrings:o,regexLiterals:o}),[vd,wd,xd]);y(C({keywords:yd,hashComments:o,multiLineStrings:o,regexLiterals:o}),
|
||||
[zd]);y(C({keywords:Ad,cStyleComments:o,regexLiterals:o}),[Bd]);y(K([],[[U,/^[\s\S]+/]]),[Cd]);function Sa(a){var b=a.e,c=a.d;a.a=b;try{var d=Zd(b),g=d.source;a.source=g;a.b=0;a.f=d.tags;Ra(c,g)(a);be(a)}catch(i){if(Ic in window){console.log(i);console.h()}}}function ce(a,b){var c={e:a,d:b};Sa(c);return c.a}function de(a){for(var b=window._pr_isIE6(),c=[document.getElementsByTagName(Dd),document.getElementsByTagName(Ed),document.getElementsByTagName(Fd)],d=[],g=0;g<c.length;++g)for(var i=0,m=c[g].length;i<
|
||||
m;++i)d.push(c[g][i]);c=r;var l=Date;l.now||(l={now:function(){return(new Date).getTime()}});var n=0,q;function v(){for(var j=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;n<d.length&&l.now()<j;n++){var f=d[n];if(f.className&&f.className.indexOf(Gd)>=0){var s=f.className.match(/\blang-(\w+)\b/);if(s)s=s[1];for(var k=z,h=f.parentNode;h;h=h.parentNode)if((h.tagName===Dd||h.tagName===Ed||h.tagName===Fd)&&h.className&&h.className.indexOf(Gd)>=0){k=o;break}if(!k){var e=Td(f);e=e.replace(/(?:\r\n?|\n)$/,
|
||||
P);q={e:e,d:s,g:f};Sa(q);w()}}}if(n<d.length)setTimeout(v,250);else a&&a()}function w(){var j=q.a;if(j){var f=q.g;if(Ma(f)){for(var s=document.createElement(gc),k=0;k<f.attributes.length;++k){var h=f.attributes[k];if(h.specified){var e=h.name.toLowerCase();if(e===Hd)s.className=h.value;else s.setAttribute(h.name,h.value)}}s.innerHTML=j;f.parentNode.replaceChild(s,f);f=s}else f.innerHTML=j;if(b&&f.tagName===gc)for(var p=f.getElementsByTagName(Id),t=p.length;--t>=0;){var u=p[t];u.parentNode.replaceChild(document.createTextNode(Jd),
|
||||
u)}}}v()}window.PR_normalizedHtml=W;window.prettyPrintOne=ce;window.prettyPrint=de;window.PR={combinePrefixPatterns:Na,createSimpleLexer:K,registerLangHandler:y,sourceDecorator:C,PR_ATTRIB_NAME:Xc,PR_ATTRIB_VALUE:Vc,PR_COMMENT:V,PR_DECLARATION:Mc,PR_KEYWORD:uc,PR_LITERAL:yc,PR_NOCODE:lc,PR_PLAIN:S,PR_PUNCTUATION:Y,PR_SOURCE:oc,PR_STRING:U,PR_TAG:Wc,PR_TYPE:zc}})();
|
||||
})()
|
||||
+4874
File diff suppressed because it is too large.
Load diff
+136
@@ -0,0 +1,136 @@
|
||||
// script.aculo.us builder.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
|
||||
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
var Builder = {
|
||||
NODEMAP: {
|
||||
AREA: 'map',
|
||||
CAPTION: 'table',
|
||||
COL: 'table',
|
||||
COLGROUP: 'table',
|
||||
LEGEND: 'fieldset',
|
||||
OPTGROUP: 'select',
|
||||
OPTION: 'select',
|
||||
PARAM: 'object',
|
||||
TBODY: 'table',
|
||||
TD: 'table',
|
||||
TFOOT: 'table',
|
||||
TH: 'table',
|
||||
THEAD: 'table',
|
||||
TR: 'table'
|
||||
},
|
||||
// note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
|
||||
// due to a Firefox bug
|
||||
node: function(elementName) {
|
||||
elementName = elementName.toUpperCase();
|
||||
|
||||
// try innerHTML approach
|
||||
var parentTag = this.NODEMAP[elementName] || 'div';
|
||||
var parentElement = document.createElement(parentTag);
|
||||
try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
|
||||
parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
|
||||
} catch(e) {}
|
||||
var element = parentElement.firstChild || null;
|
||||
|
||||
// see if browser added wrapping tags
|
||||
if(element && (element.tagName.toUpperCase() != elementName))
|
||||
element = element.getElementsByTagName(elementName)[0];
|
||||
|
||||
// fallback to createElement approach
|
||||
if(!element) element = document.createElement(elementName);
|
||||
|
||||
// abort if nothing could be created
|
||||
if(!element) return;
|
||||
|
||||
// attributes (or text)
|
||||
if(arguments[1])
|
||||
if(this._isStringOrNumber(arguments[1]) ||
|
||||
(arguments[1] instanceof Array) ||
|
||||
arguments[1].tagName) {
|
||||
this._children(element, arguments[1]);
|
||||
} else {
|
||||
var attrs = this._attributes(arguments[1]);
|
||||
if(attrs.length) {
|
||||
try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
|
||||
parentElement.innerHTML = "<" +elementName + " " +
|
||||
attrs + "></" + elementName + ">";
|
||||
} catch(e) {}
|
||||
element = parentElement.firstChild || null;
|
||||
// workaround firefox 1.0.X bug
|
||||
if(!element) {
|
||||
element = document.createElement(elementName);
|
||||
for(attr in arguments[1])
|
||||
element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
|
||||
}
|
||||
if(element.tagName.toUpperCase() != elementName)
|
||||
element = parentElement.getElementsByTagName(elementName)[0];
|
||||
}
|
||||
}
|
||||
|
||||
// text, or array of children
|
||||
if(arguments[2])
|
||||
this._children(element, arguments[2]);
|
||||
|
||||
return $(element);
|
||||
},
|
||||
_text: function(text) {
|
||||
return document.createTextNode(text);
|
||||
},
|
||||
|
||||
ATTR_MAP: {
|
||||
'className': 'class',
|
||||
'htmlFor': 'for'
|
||||
},
|
||||
|
||||
_attributes: function(attributes) {
|
||||
var attrs = [];
|
||||
for(attribute in attributes)
|
||||
attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
|
||||
'="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'"') + '"');
|
||||
return attrs.join(" ");
|
||||
},
|
||||
_children: function(element, children) {
|
||||
if(children.tagName) {
|
||||
element.appendChild(children);
|
||||
return;
|
||||
}
|
||||
if(typeof children=='object') { // array can hold nodes and text
|
||||
children.flatten().each( function(e) {
|
||||
if(typeof e=='object')
|
||||
element.appendChild(e);
|
||||
else
|
||||
if(Builder._isStringOrNumber(e))
|
||||
element.appendChild(Builder._text(e));
|
||||
});
|
||||
} else
|
||||
if(Builder._isStringOrNumber(children))
|
||||
element.appendChild(Builder._text(children));
|
||||
},
|
||||
_isStringOrNumber: function(param) {
|
||||
return(typeof param=='string' || typeof param=='number');
|
||||
},
|
||||
build: function(html) {
|
||||
var element = this.node('div');
|
||||
$(element).update(html.strip());
|
||||
return element.down();
|
||||
},
|
||||
dump: function(scope) {
|
||||
if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
|
||||
|
||||
var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
|
||||
"BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
|
||||
"FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
|
||||
"KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
|
||||
"PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
|
||||
"TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
|
||||
|
||||
tags.each( function(tag){
|
||||
scope[tag] = function() {
|
||||
return Builder.node.apply(Builder, [tag].concat($A(arguments)));
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,965 @@
|
||||
// script.aculo.us controls.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
|
||||
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
||||
// (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
|
||||
// Contributors:
|
||||
// Richard Livsey
|
||||
// Rahul Bhargava
|
||||
// Rob Wills
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
// Autocompleter.Base handles all the autocompletion functionality
|
||||
// that's independent of the data source for autocompletion. This
|
||||
// includes drawing the autocompletion menu, observing keyboard
|
||||
// and mouse events, and similar.
|
||||
//
|
||||
// Specific autocompleters need to provide, at the very least,
|
||||
// a getUpdatedChoices function that will be invoked every time
|
||||
// the text inside the monitored textbox changes. This method
|
||||
// should get the text for which to provide autocompletion by
|
||||
// invoking this.getToken(), NOT by directly accessing
|
||||
// this.element.value. This is to allow incremental tokenized
|
||||
// autocompletion. Specific auto-completion logic (AJAX, etc)
|
||||
// belongs in getUpdatedChoices.
|
||||
//
|
||||
// Tokenized incremental autocompletion is enabled automatically
|
||||
// when an autocompleter is instantiated with the 'tokens' option
|
||||
// in the options parameter, e.g.:
|
||||
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
|
||||
// will incrementally autocomplete with a comma as the token.
|
||||
// Additionally, ',' in the above example can be replaced with
|
||||
// a token array, e.g. { tokens: [',', '\n'] } which
|
||||
// enables autocompletion on multiple tokens. This is most
|
||||
// useful when one of the tokens is \n (a newline), as it
|
||||
// allows smart autocompletion after linebreaks.
|
||||
|
||||
if(typeof Effect == 'undefined')
|
||||
throw("controls.js requires including script.aculo.us' effects.js library");
|
||||
|
||||
var Autocompleter = { };
|
||||
Autocompleter.Base = Class.create({
|
||||
baseInitialize: function(element, update, options) {
|
||||
element = $(element);
|
||||
this.element = element;
|
||||
this.update = $(update);
|
||||
this.hasFocus = false;
|
||||
this.changed = false;
|
||||
this.active = false;
|
||||
this.index = 0;
|
||||
this.entryCount = 0;
|
||||
this.oldElementValue = this.element.value;
|
||||
|
||||
if(this.setOptions)
|
||||
this.setOptions(options);
|
||||
else
|
||||
this.options = options || { };
|
||||
|
||||
this.options.paramName = this.options.paramName || this.element.name;
|
||||
this.options.tokens = this.options.tokens || [];
|
||||
this.options.frequency = this.options.frequency || 0.4;
|
||||
this.options.minChars = this.options.minChars || 1;
|
||||
this.options.onShow = this.options.onShow ||
|
||||
function(element, update){
|
||||
if(!update.style.position || update.style.position=='absolute') {
|
||||
update.style.position = 'absolute';
|
||||
Position.clone(element, update, {
|
||||
setHeight: false,
|
||||
offsetTop: element.offsetHeight
|
||||
});
|
||||
}
|
||||
Effect.Appear(update,{duration:0.15});
|
||||
};
|
||||
this.options.onHide = this.options.onHide ||
|
||||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
|
||||
|
||||
if(typeof(this.options.tokens) == 'string')
|
||||
this.options.tokens = new Array(this.options.tokens);
|
||||
// Force carriage returns as token delimiters anyway
|
||||
if (!this.options.tokens.include('\n'))
|
||||
this.options.tokens.push('\n');
|
||||
|
||||
this.observer = null;
|
||||
|
||||
this.element.setAttribute('autocomplete','off');
|
||||
|
||||
Element.hide(this.update);
|
||||
|
||||
Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
|
||||
Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
|
||||
if(!this.iefix &&
|
||||
(Prototype.Browser.IE) &&
|
||||
(Element.getStyle(this.update, 'position')=='absolute')) {
|
||||
new Insertion.After(this.update,
|
||||
'<iframe id="' + this.update.id + '_iefix" '+
|
||||
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
|
||||
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
|
||||
this.iefix = $(this.update.id+'_iefix');
|
||||
}
|
||||
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
|
||||
},
|
||||
|
||||
fixIEOverlapping: function() {
|
||||
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
|
||||
this.iefix.style.zIndex = 1;
|
||||
this.update.style.zIndex = 2;
|
||||
Element.show(this.iefix);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.stopIndicator();
|
||||
if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
|
||||
if(this.iefix) Element.hide(this.iefix);
|
||||
},
|
||||
|
||||
startIndicator: function() {
|
||||
if(this.options.indicator) Element.show(this.options.indicator);
|
||||
},
|
||||
|
||||
stopIndicator: function() {
|
||||
if(this.options.indicator) Element.hide(this.options.indicator);
|
||||
},
|
||||
|
||||
onKeyPress: function(event) {
|
||||
if(this.active)
|
||||
switch(event.keyCode) {
|
||||
case Event.KEY_TAB:
|
||||
case Event.KEY_RETURN:
|
||||
this.selectEntry();
|
||||
Event.stop(event);
|
||||
case Event.KEY_ESC:
|
||||
this.hide();
|
||||
this.active = false;
|
||||
Event.stop(event);
|
||||
return;
|
||||
case Event.KEY_LEFT:
|
||||
case Event.KEY_RIGHT:
|
||||
return;
|
||||
case Event.KEY_UP:
|
||||
this.markPrevious();
|
||||
this.render();
|
||||
Event.stop(event);
|
||||
return;
|
||||
case Event.KEY_DOWN:
|
||||
this.markNext();
|
||||
this.render();
|
||||
Event.stop(event);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
|
||||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
|
||||
|
||||
this.changed = true;
|
||||
this.hasFocus = true;
|
||||
|
||||
if(this.observer) clearTimeout(this.observer);
|
||||
this.observer =
|
||||
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this.changed = false;
|
||||
this.hasFocus = true;
|
||||
this.getUpdatedChoices();
|
||||
},
|
||||
|
||||
onHover: function(event) {
|
||||
var element = Event.findElement(event, 'LI');
|
||||
if(this.index != element.autocompleteIndex)
|
||||
{
|
||||
this.index = element.autocompleteIndex;
|
||||
this.render();
|
||||
}
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
onClick: function(event) {
|
||||
var element = Event.findElement(event, 'LI');
|
||||
this.index = element.autocompleteIndex;
|
||||
this.selectEntry();
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onBlur: function(event) {
|
||||
// needed to make click events working
|
||||
setTimeout(this.hide.bind(this), 250);
|
||||
this.hasFocus = false;
|
||||
this.active = false;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if(this.entryCount > 0) {
|
||||
for (var i = 0; i < this.entryCount; i++)
|
||||
this.index==i ?
|
||||
Element.addClassName(this.getEntry(i),"selected") :
|
||||
Element.removeClassName(this.getEntry(i),"selected");
|
||||
if(this.hasFocus) {
|
||||
this.show();
|
||||
this.active = true;
|
||||
}
|
||||
} else {
|
||||
this.active = false;
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
markPrevious: function() {
|
||||
if(this.index > 0) this.index--;
|
||||
else this.index = this.entryCount-1;
|
||||
this.getEntry(this.index).scrollIntoView(true);
|
||||
},
|
||||
|
||||
markNext: function() {
|
||||
if(this.index < this.entryCount-1) this.index++;
|
||||
else this.index = 0;
|
||||
this.getEntry(this.index).scrollIntoView(false);
|
||||
},
|
||||
|
||||
getEntry: function(index) {
|
||||
return this.update.firstChild.childNodes[index];
|
||||
},
|
||||
|
||||
getCurrentEntry: function() {
|
||||
return this.getEntry(this.index);
|
||||
},
|
||||
|
||||
selectEntry: function() {
|
||||
this.active = false;
|
||||
this.updateElement(this.getCurrentEntry());
|
||||
},
|
||||
|
||||
updateElement: function(selectedElement) {
|
||||
if (this.options.updateElement) {
|
||||
this.options.updateElement(selectedElement);
|
||||
return;
|
||||
}
|
||||
var value = '';
|
||||
if (this.options.select) {
|
||||
var nodes = $(selectedElement).select('.' + this.options.select) || [];
|
||||
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
|
||||
} else
|
||||
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
|
||||
|
||||
var bounds = this.getTokenBounds();
|
||||
if (bounds[0] != -1) {
|
||||
var newValue = this.element.value.substr(0, bounds[0]);
|
||||
var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
|
||||
if (whitespace)
|
||||
newValue += whitespace[0];
|
||||
this.element.value = newValue + value + this.element.value.substr(bounds[1]);
|
||||
} else {
|
||||
this.element.value = value;
|
||||
}
|
||||
this.oldElementValue = this.element.value;
|
||||
this.element.focus();
|
||||
|
||||
if (this.options.afterUpdateElement)
|
||||
this.options.afterUpdateElement(this.element, selectedElement);
|
||||
},
|
||||
|
||||
updateChoices: function(choices) {
|
||||
if(!this.changed && this.hasFocus) {
|
||||
this.update.innerHTML = choices;
|
||||
Element.cleanWhitespace(this.update);
|
||||
Element.cleanWhitespace(this.update.down());
|
||||
|
||||
if(this.update.firstChild && this.update.down().childNodes) {
|
||||
this.entryCount =
|
||||
this.update.down().childNodes.length;
|
||||
for (var i = 0; i < this.entryCount; i++) {
|
||||
var entry = this.getEntry(i);
|
||||
entry.autocompleteIndex = i;
|
||||
this.addObservers(entry);
|
||||
}
|
||||
} else {
|
||||
this.entryCount = 0;
|
||||
}
|
||||
|
||||
this.stopIndicator();
|
||||
this.index = 0;
|
||||
|
||||
if(this.entryCount==1 && this.options.autoSelect) {
|
||||
this.selectEntry();
|
||||
this.hide();
|
||||
} else {
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addObservers: function(element) {
|
||||
Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
|
||||
Event.observe(element, "click", this.onClick.bindAsEventListener(this));
|
||||
},
|
||||
|
||||
onObserverEvent: function() {
|
||||
this.changed = false;
|
||||
this.tokenBounds = null;
|
||||
if(this.getToken().length>=this.options.minChars) {
|
||||
this.getUpdatedChoices();
|
||||
} else {
|
||||
this.active = false;
|
||||
this.hide();
|
||||
}
|
||||
this.oldElementValue = this.element.value;
|
||||
},
|
||||
|
||||
getToken: function() {
|
||||
var bounds = this.getTokenBounds();
|
||||
return this.element.value.substring(bounds[0], bounds[1]).strip();
|
||||
},
|
||||
|
||||
getTokenBounds: function() {
|
||||
if (null != this.tokenBounds) return this.tokenBounds;
|
||||
var value = this.element.value;
|
||||
if (value.strip().empty()) return [-1, 0];
|
||||
var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
|
||||
var offset = (diff == this.oldElementValue.length ? 1 : 0);
|
||||
var prevTokenPos = -1, nextTokenPos = value.length;
|
||||
var tp;
|
||||
for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
|
||||
tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
|
||||
if (tp > prevTokenPos) prevTokenPos = tp;
|
||||
tp = value.indexOf(this.options.tokens[index], diff + offset);
|
||||
if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
|
||||
}
|
||||
return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
|
||||
}
|
||||
});
|
||||
|
||||
Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
|
||||
var boundary = Math.min(newS.length, oldS.length);
|
||||
for (var index = 0; index < boundary; ++index)
|
||||
if (newS[index] != oldS[index])
|
||||
return index;
|
||||
return boundary;
|
||||
};
|
||||
|
||||
Ajax.Autocompleter = Class.create(Autocompleter.Base, {
|
||||
initialize: function(element, update, url, options) {
|
||||
this.baseInitialize(element, update, options);
|
||||
this.options.asynchronous = true;
|
||||
this.options.onComplete = this.onComplete.bind(this);
|
||||
this.options.defaultParams = this.options.parameters || null;
|
||||
this.url = url;
|
||||
},
|
||||
|
||||
getUpdatedChoices: function() {
|
||||
this.startIndicator();
|
||||
|
||||
var entry = encodeURIComponent(this.options.paramName) + '=' +
|
||||
encodeURIComponent(this.getToken());
|
||||
|
||||
this.options.parameters = this.options.callback ?
|
||||
this.options.callback(this.element, entry) : entry;
|
||||
|
||||
if(this.options.defaultParams)
|
||||
this.options.parameters += '&' + this.options.defaultParams;
|
||||
|
||||
new Ajax.Request(this.url, this.options);
|
||||
},
|
||||
|
||||
onComplete: function(request) {
|
||||
this.updateChoices(request.responseText);
|
||||
}
|
||||
});
|
||||
|
||||
// The local array autocompleter. Used when you'd prefer to
|
||||
// inject an array of autocompletion options into the page, rather
|
||||
// than sending out Ajax queries, which can be quite slow sometimes.
|
||||
//
|
||||
// The constructor takes four parameters. The first two are, as usual,
|
||||
// the id of the monitored textbox, and id of the autocompletion menu.
|
||||
// The third is the array you want to autocomplete from, and the fourth
|
||||
// is the options block.
|
||||
//
|
||||
// Extra local autocompletion options:
|
||||
// - choices - How many autocompletion choices to offer
|
||||
//
|
||||
// - partialSearch - If false, the autocompleter will match entered
|
||||
// text only at the beginning of strings in the
|
||||
// autocomplete array. Defaults to true, which will
|
||||
// match text at the beginning of any *word* in the
|
||||
// strings in the autocomplete array. If you want to
|
||||
// search anywhere in the string, additionally set
|
||||
// the option fullSearch to true (default: off).
|
||||
//
|
||||
// - fullSsearch - Search anywhere in autocomplete array strings.
|
||||
//
|
||||
// - partialChars - How many characters to enter before triggering
|
||||
// a partial match (unlike minChars, which defines
|
||||
// how many characters are required to do any match
|
||||
// at all). Defaults to 2.
|
||||
//
|
||||
// - ignoreCase - Whether to ignore case when autocompleting.
|
||||
// Defaults to true.
|
||||
//
|
||||
// It's possible to pass in a custom function as the 'selector'
|
||||
// option, if you prefer to write your own autocompletion logic.
|
||||
// In that case, the other options above will not apply unless
|
||||
// you support them.
|
||||
|
||||
Autocompleter.Local = Class.create(Autocompleter.Base, {
|
||||
initialize: function(element, update, array, options) {
|
||||
this.baseInitialize(element, update, options);
|
||||
this.options.array = array;
|
||||
},
|
||||
|
||||
getUpdatedChoices: function() {
|
||||
this.updateChoices(this.options.selector(this));
|
||||
},
|
||||
|
||||
setOptions: function(options) {
|
||||
this.options = Object.extend({
|
||||
choices: 10,
|
||||
partialSearch: true,
|
||||
partialChars: 2,
|
||||
ignoreCase: true,
|
||||
fullSearch: false,
|
||||
selector: function(instance) {
|
||||
var ret = []; // Beginning matches
|
||||
var partial = []; // Inside matches
|
||||
var entry = instance.getToken();
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < instance.options.array.length &&
|
||||
ret.length < instance.options.choices ; i++) {
|
||||
|
||||
var elem = instance.options.array[i];
|
||||
var foundPos = instance.options.ignoreCase ?
|
||||
elem.toLowerCase().indexOf(entry.toLowerCase()) :
|
||||
elem.indexOf(entry);
|
||||
|
||||
while (foundPos != -1) {
|
||||
if (foundPos == 0 && elem.length != entry.length) {
|
||||
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
|
||||
elem.substr(entry.length) + "</li>");
|
||||
break;
|
||||
} else if (entry.length >= instance.options.partialChars &&
|
||||
instance.options.partialSearch && foundPos != -1) {
|
||||
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
|
||||
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
|
||||
elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
|
||||
foundPos + entry.length) + "</li>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foundPos = instance.options.ignoreCase ?
|
||||
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
|
||||
elem.indexOf(entry, foundPos + 1);
|
||||
|
||||
}
|
||||
}
|
||||
if (partial.length)
|
||||
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
|
||||
return "<ul>" + ret.join('') + "</ul>";
|
||||
}
|
||||
}, options || { });
|
||||
}
|
||||
});
|
||||
|
||||
// AJAX in-place editor and collection editor
|
||||
// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
|
||||
|
||||
// Use this if you notice weird scrolling problems on some browsers,
|
||||
// the DOM might be a bit confused when this gets called so do this
|
||||
// waits 1 ms (with setTimeout) until it does the activation
|
||||
Field.scrollFreeActivate = function(field) {
|
||||
setTimeout(function() {
|
||||
Field.activate(field);
|
||||
}, 1);
|
||||
};
|
||||
|
||||
Ajax.InPlaceEditor = Class.create({
|
||||
initialize: function(element, url, options) {
|
||||
this.url = url;
|
||||
this.element = element = $(element);
|
||||
this.prepareOptions();
|
||||
this._controls = { };
|
||||
arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
|
||||
Object.extend(this.options, options || { });
|
||||
if (!this.options.formId && this.element.id) {
|
||||
this.options.formId = this.element.id + '-inplaceeditor';
|
||||
if ($(this.options.formId))
|
||||
this.options.formId = '';
|
||||
}
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl = $(this.options.externalControl);
|
||||
if (!this.options.externalControl)
|
||||
this.options.externalControlOnly = false;
|
||||
this._originalBackground = this.element.getStyle('background-color') || 'transparent';
|
||||
this.element.title = this.options.clickToEditText;
|
||||
this._boundCancelHandler = this.handleFormCancellation.bind(this);
|
||||
this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
|
||||
this._boundFailureHandler = this.handleAJAXFailure.bind(this);
|
||||
this._boundSubmitHandler = this.handleFormSubmission.bind(this);
|
||||
this._boundWrapperHandler = this.wrapUp.bind(this);
|
||||
this.registerListeners();
|
||||
},
|
||||
checkForEscapeOrReturn: function(e) {
|
||||
if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
|
||||
if (Event.KEY_ESC == e.keyCode)
|
||||
this.handleFormCancellation(e);
|
||||
else if (Event.KEY_RETURN == e.keyCode)
|
||||
this.handleFormSubmission(e);
|
||||
},
|
||||
createControl: function(mode, handler, extraClasses) {
|
||||
var control = this.options[mode + 'Control'];
|
||||
var text = this.options[mode + 'Text'];
|
||||
if ('button' == control) {
|
||||
var btn = document.createElement('input');
|
||||
btn.type = 'submit';
|
||||
btn.value = text;
|
||||
btn.className = 'editor_' + mode + '_button';
|
||||
if ('cancel' == mode)
|
||||
btn.onclick = this._boundCancelHandler;
|
||||
this._form.appendChild(btn);
|
||||
this._controls[mode] = btn;
|
||||
} else if ('link' == control) {
|
||||
var link = document.createElement('a');
|
||||
link.href = '#';
|
||||
link.appendChild(document.createTextNode(text));
|
||||
link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
|
||||
link.className = 'editor_' + mode + '_link';
|
||||
if (extraClasses)
|
||||
link.className += ' ' + extraClasses;
|
||||
this._form.appendChild(link);
|
||||
this._controls[mode] = link;
|
||||
}
|
||||
},
|
||||
createEditField: function() {
|
||||
var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
|
||||
var fld;
|
||||
if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
|
||||
fld = document.createElement('input');
|
||||
fld.type = 'text';
|
||||
var size = this.options.size || this.options.cols || 0;
|
||||
if (0 < size) fld.size = size;
|
||||
} else {
|
||||
fld = document.createElement('textarea');
|
||||
fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
|
||||
fld.cols = this.options.cols || 40;
|
||||
}
|
||||
fld.name = this.options.paramName;
|
||||
fld.value = text; // No HTML breaks conversion anymore
|
||||
fld.className = 'editor_field';
|
||||
if (this.options.submitOnBlur)
|
||||
fld.onblur = this._boundSubmitHandler;
|
||||
this._controls.editor = fld;
|
||||
if (this.options.loadTextURL)
|
||||
this.loadExternalText();
|
||||
this._form.appendChild(this._controls.editor);
|
||||
},
|
||||
createForm: function() {
|
||||
var ipe = this;
|
||||
function addText(mode, condition) {
|
||||
var text = ipe.options['text' + mode + 'Controls'];
|
||||
if (!text || condition === false) return;
|
||||
ipe._form.appendChild(document.createTextNode(text));
|
||||
};
|
||||
this._form = $(document.createElement('form'));
|
||||
this._form.id = this.options.formId;
|
||||
this._form.addClassName(this.options.formClassName);
|
||||
this._form.onsubmit = this._boundSubmitHandler;
|
||||
this.createEditField();
|
||||
if ('textarea' == this._controls.editor.tagName.toLowerCase())
|
||||
this._form.appendChild(document.createElement('br'));
|
||||
if (this.options.onFormCustomization)
|
||||
this.options.onFormCustomization(this, this._form);
|
||||
addText('Before', this.options.okControl || this.options.cancelControl);
|
||||
this.createControl('ok', this._boundSubmitHandler);
|
||||
addText('Between', this.options.okControl && this.options.cancelControl);
|
||||
this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
|
||||
addText('After', this.options.okControl || this.options.cancelControl);
|
||||
},
|
||||
destroy: function() {
|
||||
if (this._oldInnerHTML)
|
||||
this.element.innerHTML = this._oldInnerHTML;
|
||||
this.leaveEditMode();
|
||||
this.unregisterListeners();
|
||||
},
|
||||
enterEditMode: function(e) {
|
||||
if (this._saving || this._editing) return;
|
||||
this._editing = true;
|
||||
this.triggerCallback('onEnterEditMode');
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.hide();
|
||||
this.element.hide();
|
||||
this.createForm();
|
||||
this.element.parentNode.insertBefore(this._form, this.element);
|
||||
if (!this.options.loadTextURL)
|
||||
this.postProcessEditField();
|
||||
if (e) Event.stop(e);
|
||||
},
|
||||
enterHover: function(e) {
|
||||
if (this.options.hoverClassName)
|
||||
this.element.addClassName(this.options.hoverClassName);
|
||||
if (this._saving) return;
|
||||
this.triggerCallback('onEnterHover');
|
||||
},
|
||||
getText: function() {
|
||||
return this.element.innerHTML.unescapeHTML();
|
||||
},
|
||||
handleAJAXFailure: function(transport) {
|
||||
this.triggerCallback('onFailure', transport);
|
||||
if (this._oldInnerHTML) {
|
||||
this.element.innerHTML = this._oldInnerHTML;
|
||||
this._oldInnerHTML = null;
|
||||
}
|
||||
},
|
||||
handleFormCancellation: function(e) {
|
||||
this.wrapUp();
|
||||
if (e) Event.stop(e);
|
||||
},
|
||||
handleFormSubmission: function(e) {
|
||||
var form = this._form;
|
||||
var value = $F(this._controls.editor);
|
||||
this.prepareSubmission();
|
||||
var params = this.options.callback(form, value) || '';
|
||||
if (Object.isString(params))
|
||||
params = params.toQueryParams();
|
||||
params.editorId = this.element.id;
|
||||
if (this.options.htmlResponse) {
|
||||
var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: params,
|
||||
onComplete: this._boundWrapperHandler,
|
||||
onFailure: this._boundFailureHandler
|
||||
});
|
||||
new Ajax.Updater({ success: this.element }, this.url, options);
|
||||
} else {
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: params,
|
||||
onComplete: this._boundWrapperHandler,
|
||||
onFailure: this._boundFailureHandler
|
||||
});
|
||||
new Ajax.Request(this.url, options);
|
||||
}
|
||||
if (e) Event.stop(e);
|
||||
},
|
||||
leaveEditMode: function() {
|
||||
this.element.removeClassName(this.options.savingClassName);
|
||||
this.removeForm();
|
||||
this.leaveHover();
|
||||
this.element.style.backgroundColor = this._originalBackground;
|
||||
this.element.show();
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.show();
|
||||
this._saving = false;
|
||||
this._editing = false;
|
||||
this._oldInnerHTML = null;
|
||||
this.triggerCallback('onLeaveEditMode');
|
||||
},
|
||||
leaveHover: function(e) {
|
||||
if (this.options.hoverClassName)
|
||||
this.element.removeClassName(this.options.hoverClassName);
|
||||
if (this._saving) return;
|
||||
this.triggerCallback('onLeaveHover');
|
||||
},
|
||||
loadExternalText: function() {
|
||||
this._form.addClassName(this.options.loadingClassName);
|
||||
this._controls.editor.disabled = true;
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
||||
onComplete: Prototype.emptyFunction,
|
||||
onSuccess: function(transport) {
|
||||
this._form.removeClassName(this.options.loadingClassName);
|
||||
var text = transport.responseText;
|
||||
if (this.options.stripLoadedTextTags)
|
||||
text = text.stripTags();
|
||||
this._controls.editor.value = text;
|
||||
this._controls.editor.disabled = false;
|
||||
this.postProcessEditField();
|
||||
}.bind(this),
|
||||
onFailure: this._boundFailureHandler
|
||||
});
|
||||
new Ajax.Request(this.options.loadTextURL, options);
|
||||
},
|
||||
postProcessEditField: function() {
|
||||
var fpc = this.options.fieldPostCreation;
|
||||
if (fpc)
|
||||
$(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
|
||||
},
|
||||
prepareOptions: function() {
|
||||
this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
|
||||
Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
|
||||
[this._extraDefaultOptions].flatten().compact().each(function(defs) {
|
||||
Object.extend(this.options, defs);
|
||||
}.bind(this));
|
||||
},
|
||||
prepareSubmission: function() {
|
||||
this._saving = true;
|
||||
this.removeForm();
|
||||
this.leaveHover();
|
||||
this.showSaving();
|
||||
},
|
||||
registerListeners: function() {
|
||||
this._listeners = { };
|
||||
var listener;
|
||||
$H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
|
||||
listener = this[pair.value].bind(this);
|
||||
this._listeners[pair.key] = listener;
|
||||
if (!this.options.externalControlOnly)
|
||||
this.element.observe(pair.key, listener);
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.observe(pair.key, listener);
|
||||
}.bind(this));
|
||||
},
|
||||
removeForm: function() {
|
||||
if (!this._form) return;
|
||||
this._form.remove();
|
||||
this._form = null;
|
||||
this._controls = { };
|
||||
},
|
||||
showSaving: function() {
|
||||
this._oldInnerHTML = this.element.innerHTML;
|
||||
this.element.innerHTML = this.options.savingText;
|
||||
this.element.addClassName(this.options.savingClassName);
|
||||
this.element.style.backgroundColor = this._originalBackground;
|
||||
this.element.show();
|
||||
},
|
||||
triggerCallback: function(cbName, arg) {
|
||||
if ('function' == typeof this.options[cbName]) {
|
||||
this.options[cbName](this, arg);
|
||||
}
|
||||
},
|
||||
unregisterListeners: function() {
|
||||
$H(this._listeners).each(function(pair) {
|
||||
if (!this.options.externalControlOnly)
|
||||
this.element.stopObserving(pair.key, pair.value);
|
||||
if (this.options.externalControl)
|
||||
this.options.externalControl.stopObserving(pair.key, pair.value);
|
||||
}.bind(this));
|
||||
},
|
||||
wrapUp: function(transport) {
|
||||
this.leaveEditMode();
|
||||
// Can't use triggerCallback due to backward compatibility: requires
|
||||
// binding + direct element
|
||||
this._boundComplete(transport, this.element);
|
||||
}
|
||||
});
|
||||
|
||||
Object.extend(Ajax.InPlaceEditor.prototype, {
|
||||
dispose: Ajax.InPlaceEditor.prototype.destroy
|
||||
});
|
||||
|
||||
Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
|
||||
initialize: function($super, element, url, options) {
|
||||
this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
|
||||
$super(element, url, options);
|
||||
},
|
||||
|
||||
createEditField: function() {
|
||||
var list = document.createElement('select');
|
||||
list.name = this.options.paramName;
|
||||
list.size = 1;
|
||||
this._controls.editor = list;
|
||||
this._collection = this.options.collection || [];
|
||||
if (this.options.loadCollectionURL)
|
||||
this.loadCollection();
|
||||
else
|
||||
this.checkForExternalText();
|
||||
this._form.appendChild(this._controls.editor);
|
||||
},
|
||||
|
||||
loadCollection: function() {
|
||||
this._form.addClassName(this.options.loadingClassName);
|
||||
this.showLoadingText(this.options.loadingCollectionText);
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
||||
onComplete: Prototype.emptyFunction,
|
||||
onSuccess: function(transport) {
|
||||
var js = transport.responseText.strip();
|
||||
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
|
||||
throw('Server returned an invalid collection representation.');
|
||||
this._collection = eval(js);
|
||||
this.checkForExternalText();
|
||||
}.bind(this),
|
||||
onFailure: this.onFailure
|
||||
});
|
||||
new Ajax.Request(this.options.loadCollectionURL, options);
|
||||
},
|
||||
|
||||
showLoadingText: function(text) {
|
||||
this._controls.editor.disabled = true;
|
||||
var tempOption = this._controls.editor.firstChild;
|
||||
if (!tempOption) {
|
||||
tempOption = document.createElement('option');
|
||||
tempOption.value = '';
|
||||
this._controls.editor.appendChild(tempOption);
|
||||
tempOption.selected = true;
|
||||
}
|
||||
tempOption.update((text || '').stripScripts().stripTags());
|
||||
},
|
||||
|
||||
checkForExternalText: function() {
|
||||
this._text = this.getText();
|
||||
if (this.options.loadTextURL)
|
||||
this.loadExternalText();
|
||||
else
|
||||
this.buildOptionList();
|
||||
},
|
||||
|
||||
loadExternalText: function() {
|
||||
this.showLoadingText(this.options.loadingText);
|
||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
||||
Object.extend(options, {
|
||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
||||
onComplete: Prototype.emptyFunction,
|
||||
onSuccess: function(transport) {
|
||||
this._text = transport.responseText.strip();
|
||||
this.buildOptionList();
|
||||
}.bind(this),
|
||||
onFailure: this.onFailure
|
||||
});
|
||||
new Ajax.Request(this.options.loadTextURL, options);
|
||||
},
|
||||
|
||||
buildOptionList: function() {
|
||||
this._form.removeClassName(this.options.loadingClassName);
|
||||
this._collection = this._collection.map(function(entry) {
|
||||
return 2 === entry.length ? entry : [entry, entry].flatten();
|
||||
});
|
||||
var marker = ('value' in this.options) ? this.options.value : this._text;
|
||||
var textFound = this._collection.any(function(entry) {
|
||||
return entry[0] == marker;
|
||||
}.bind(this));
|
||||
this._controls.editor.update('');
|
||||
var option;
|
||||
this._collection.each(function(entry, index) {
|
||||
option = document.createElement('option');
|
||||
option.value = entry[0];
|
||||
option.selected = textFound ? entry[0] == marker : 0 == index;
|
||||
option.appendChild(document.createTextNode(entry[1]));
|
||||
this._controls.editor.appendChild(option);
|
||||
}.bind(this));
|
||||
this._controls.editor.disabled = false;
|
||||
Field.scrollFreeActivate(this._controls.editor);
|
||||
}
|
||||
});
|
||||
|
||||
//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
|
||||
//**** This only exists for a while, in order to let ****
|
||||
//**** users adapt to the new API. Read up on the new ****
|
||||
//**** API and convert your code to it ASAP! ****
|
||||
|
||||
Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
|
||||
if (!options) return;
|
||||
function fallback(name, expr) {
|
||||
if (name in options || expr === undefined) return;
|
||||
options[name] = expr;
|
||||
};
|
||||
fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
|
||||
options.cancelLink == options.cancelButton == false ? false : undefined)));
|
||||
fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
|
||||
options.okLink == options.okButton == false ? false : undefined)));
|
||||
fallback('highlightColor', options.highlightcolor);
|
||||
fallback('highlightEndColor', options.highlightendcolor);
|
||||
};
|
||||
|
||||
Object.extend(Ajax.InPlaceEditor, {
|
||||
DefaultOptions: {
|
||||
ajaxOptions: { },
|
||||
autoRows: 3, // Use when multi-line w/ rows == 1
|
||||
cancelControl: 'link', // 'link'|'button'|false
|
||||
cancelText: 'cancel',
|
||||
clickToEditText: 'Изменить',
|
||||
externalControl: null, // id|elt
|
||||
externalControlOnly: false,
|
||||
fieldPostCreation: 'activate', // 'activate'|'focus'|false
|
||||
formClassName: 'inplaceeditor-form',
|
||||
formId: null, // id|elt
|
||||
highlightColor: '#ffff99',
|
||||
highlightEndColor: '#ffffff',
|
||||
hoverClassName: '',
|
||||
htmlResponse: true,
|
||||
loadingClassName: 'inplaceeditor-loading',
|
||||
loadingText: 'Загрузка...',
|
||||
okControl: 'button', // 'link'|'button'|false
|
||||
okText: 'ok',
|
||||
paramName: 'value',
|
||||
rows: 1, // If 1 and multi-line, uses autoRows
|
||||
savingClassName: 'inplaceeditor-saving',
|
||||
savingText: 'Сохранение...',
|
||||
size: 0,
|
||||
stripLoadedTextTags: false,
|
||||
submitOnBlur: false,
|
||||
textAfterControls: '',
|
||||
textBeforeControls: '',
|
||||
textBetweenControls: ''
|
||||
},
|
||||
DefaultCallbacks: {
|
||||
callback: function(form) {
|
||||
return Form.serialize(form);
|
||||
},
|
||||
onComplete: function(transport, element) {
|
||||
// For backward compatibility, this one is bound to the IPE, and passes
|
||||
// the element directly. It was too often customized, so we don't break it.
|
||||
new Effect.Highlight(element, {
|
||||
startcolor: this.options.highlightColor, keepBackgroundImage: true });
|
||||
},
|
||||
onEnterEditMode: null,
|
||||
onEnterHover: function(ipe) {
|
||||
ipe.element.style.backgroundColor = ipe.options.highlightColor;
|
||||
if (ipe._effect)
|
||||
ipe._effect.cancel();
|
||||
},
|
||||
onFailure: function(transport, ipe) {
|
||||
alert('Error communication with the server: ' + transport.responseText.stripTags());
|
||||
},
|
||||
onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
|
||||
onLeaveEditMode: null,
|
||||
onLeaveHover: function(ipe) {
|
||||
ipe._effect = new Effect.Highlight(ipe.element, {
|
||||
startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
|
||||
restorecolor: ipe._originalBackground, keepBackgroundImage: true
|
||||
});
|
||||
}
|
||||
},
|
||||
Listeners: {
|
||||
click: 'enterEditMode',
|
||||
keydown: 'checkForEscapeOrReturn',
|
||||
mouseover: 'enterHover',
|
||||
mouseout: 'leaveHover'
|
||||
}
|
||||
});
|
||||
|
||||
Ajax.InPlaceCollectionEditor.DefaultOptions = {
|
||||
loadingCollectionText: 'Загрузка настроек...'
|
||||
};
|
||||
|
||||
// Delayed observer, like Form.Element.Observer,
|
||||
// but waits for delay after last key input
|
||||
// Ideal for live-search fields
|
||||
|
||||
Form.Element.DelayedObserver = Class.create({
|
||||
initialize: function(element, delay, callback) {
|
||||
this.delay = delay || 0.5;
|
||||
this.element = $(element);
|
||||
this.callback = callback;
|
||||
this.timer = null;
|
||||
this.lastValue = $F(this.element);
|
||||
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
|
||||
},
|
||||
delayedListener: function(event) {
|
||||
if(this.lastValue == $F(this.element)) return;
|
||||
if(this.timer) clearTimeout(this.timer);
|
||||
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
|
||||
this.lastValue = $F(this.element);
|
||||
},
|
||||
onTimerEvent: function() {
|
||||
this.timer = null;
|
||||
this.callback(this.element, $F(this.element));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,975 @@
|
||||
// script.aculo.us dragdrop.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
|
||||
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
if(Object.isUndefined(Effect))
|
||||
throw("dragdrop.js requires including script.aculo.us' effects.js library");
|
||||
|
||||
var Droppables = {
|
||||
drops: [],
|
||||
|
||||
remove: function(element) {
|
||||
this.drops = this.drops.reject(function(d) { return d.element==$(element) });
|
||||
},
|
||||
|
||||
add: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
greedy: true,
|
||||
hoverclass: null,
|
||||
tree: false
|
||||
}, arguments[1] || { });
|
||||
|
||||
// cache containers
|
||||
if(options.containment) {
|
||||
options._containers = [];
|
||||
var containment = options.containment;
|
||||
if(Object.isArray(containment)) {
|
||||
containment.each( function(c) { options._containers.push($(c)) });
|
||||
} else {
|
||||
options._containers.push($(containment));
|
||||
}
|
||||
}
|
||||
|
||||
if(options.accept) options.accept = [options.accept].flatten();
|
||||
|
||||
Element.makePositioned(element); // fix IE
|
||||
options.element = element;
|
||||
|
||||
this.drops.push(options);
|
||||
},
|
||||
|
||||
findDeepestChild: function(drops) {
|
||||
deepest = drops[0];
|
||||
|
||||
for (i = 1; i < drops.length; ++i)
|
||||
if (Element.isParent(drops[i].element, deepest.element))
|
||||
deepest = drops[i];
|
||||
|
||||
return deepest;
|
||||
},
|
||||
|
||||
isContained: function(element, drop) {
|
||||
var containmentNode;
|
||||
if(drop.tree) {
|
||||
containmentNode = element.treeNode;
|
||||
} else {
|
||||
containmentNode = element.parentNode;
|
||||
}
|
||||
return drop._containers.detect(function(c) { return containmentNode == c });
|
||||
},
|
||||
|
||||
isAffected: function(point, element, drop) {
|
||||
return (
|
||||
(drop.element!=element) &&
|
||||
((!drop._containers) ||
|
||||
this.isContained(element, drop)) &&
|
||||
((!drop.accept) ||
|
||||
(Element.classNames(element).detect(
|
||||
function(v) { return drop.accept.include(v) } ) )) &&
|
||||
Position.within(drop.element, point[0], point[1]) );
|
||||
},
|
||||
|
||||
deactivate: function(drop) {
|
||||
if(drop.hoverclass)
|
||||
Element.removeClassName(drop.element, drop.hoverclass);
|
||||
this.last_active = null;
|
||||
},
|
||||
|
||||
activate: function(drop) {
|
||||
if(drop.hoverclass)
|
||||
Element.addClassName(drop.element, drop.hoverclass);
|
||||
this.last_active = drop;
|
||||
},
|
||||
|
||||
show: function(point, element) {
|
||||
if(!this.drops.length) return;
|
||||
var drop, affected = [];
|
||||
|
||||
this.drops.each( function(drop) {
|
||||
if(Droppables.isAffected(point, element, drop))
|
||||
affected.push(drop);
|
||||
});
|
||||
|
||||
if(affected.length>0)
|
||||
drop = Droppables.findDeepestChild(affected);
|
||||
|
||||
if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
|
||||
if (drop) {
|
||||
Position.within(drop.element, point[0], point[1]);
|
||||
if(drop.onHover)
|
||||
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
|
||||
|
||||
if (drop != this.last_active) Droppables.activate(drop);
|
||||
}
|
||||
},
|
||||
|
||||
fire: function(event, element) {
|
||||
if(!this.last_active) return;
|
||||
Position.prepare();
|
||||
|
||||
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
|
||||
if (this.last_active.onDrop) {
|
||||
this.last_active.onDrop(element, this.last_active.element, event);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if(this.last_active)
|
||||
this.deactivate(this.last_active);
|
||||
}
|
||||
};
|
||||
|
||||
var Draggables = {
|
||||
drags: [],
|
||||
observers: [],
|
||||
|
||||
register: function(draggable) {
|
||||
if(this.drags.length == 0) {
|
||||
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
|
||||
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
|
||||
this.eventKeypress = this.keyPress.bindAsEventListener(this);
|
||||
|
||||
Event.observe(document, "mouseup", this.eventMouseUp);
|
||||
Event.observe(document, "mousemove", this.eventMouseMove);
|
||||
Event.observe(document, "keypress", this.eventKeypress);
|
||||
}
|
||||
this.drags.push(draggable);
|
||||
},
|
||||
|
||||
unregister: function(draggable) {
|
||||
this.drags = this.drags.reject(function(d) { return d==draggable });
|
||||
if(this.drags.length == 0) {
|
||||
Event.stopObserving(document, "mouseup", this.eventMouseUp);
|
||||
Event.stopObserving(document, "mousemove", this.eventMouseMove);
|
||||
Event.stopObserving(document, "keypress", this.eventKeypress);
|
||||
}
|
||||
},
|
||||
|
||||
activate: function(draggable) {
|
||||
if(draggable.options.delay) {
|
||||
this._timeout = setTimeout(function() {
|
||||
Draggables._timeout = null;
|
||||
window.focus();
|
||||
Draggables.activeDraggable = draggable;
|
||||
}.bind(this), draggable.options.delay);
|
||||
} else {
|
||||
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
|
||||
this.activeDraggable = draggable;
|
||||
}
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
this.activeDraggable = null;
|
||||
},
|
||||
|
||||
updateDrag: function(event) {
|
||||
if(!this.activeDraggable) return;
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
// Mozilla-based browsers fire successive mousemove events with
|
||||
// the same coordinates, prevent needless redrawing (moz bug?)
|
||||
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
|
||||
this._lastPointer = pointer;
|
||||
|
||||
this.activeDraggable.updateDrag(event, pointer);
|
||||
},
|
||||
|
||||
endDrag: function(event) {
|
||||
if(this._timeout) {
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
}
|
||||
if(!this.activeDraggable) return;
|
||||
this._lastPointer = null;
|
||||
this.activeDraggable.endDrag(event);
|
||||
this.activeDraggable = null;
|
||||
},
|
||||
|
||||
keyPress: function(event) {
|
||||
if(this.activeDraggable)
|
||||
this.activeDraggable.keyPress(event);
|
||||
},
|
||||
|
||||
addObserver: function(observer) {
|
||||
this.observers.push(observer);
|
||||
this._cacheObserverCallbacks();
|
||||
},
|
||||
|
||||
removeObserver: function(element) { // element instead of observer fixes mem leaks
|
||||
this.observers = this.observers.reject( function(o) { return o.element==element });
|
||||
this._cacheObserverCallbacks();
|
||||
},
|
||||
|
||||
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
|
||||
if(this[eventName+'Count'] > 0)
|
||||
this.observers.each( function(o) {
|
||||
if(o[eventName]) o[eventName](eventName, draggable, event);
|
||||
});
|
||||
if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
|
||||
},
|
||||
|
||||
_cacheObserverCallbacks: function() {
|
||||
['onStart','onEnd','onDrag'].each( function(eventName) {
|
||||
Draggables[eventName+'Count'] = Draggables.observers.select(
|
||||
function(o) { return o[eventName]; }
|
||||
).length;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var Draggable = Class.create({
|
||||
initialize: function(element) {
|
||||
var defaults = {
|
||||
handle: false,
|
||||
reverteffect: function(element, top_offset, left_offset) {
|
||||
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
|
||||
new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
|
||||
queue: {scope:'_draggable', position:'end'}
|
||||
});
|
||||
},
|
||||
endeffect: function(element) {
|
||||
var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
|
||||
new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
|
||||
queue: {scope:'_draggable', position:'end'},
|
||||
afterFinish: function(){
|
||||
Draggable._dragging[element] = false
|
||||
}
|
||||
});
|
||||
},
|
||||
zindex: 1000,
|
||||
revert: false,
|
||||
quiet: false,
|
||||
scroll: false,
|
||||
scrollSensitivity: 20,
|
||||
scrollSpeed: 15,
|
||||
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
|
||||
delay: 0
|
||||
};
|
||||
|
||||
if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
|
||||
Object.extend(defaults, {
|
||||
starteffect: function(element) {
|
||||
element._opacity = Element.getOpacity(element);
|
||||
Draggable._dragging[element] = true;
|
||||
new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
|
||||
}
|
||||
});
|
||||
|
||||
var options = Object.extend(defaults, arguments[1] || { });
|
||||
|
||||
this.element = $(element);
|
||||
|
||||
if(options.handle && Object.isString(options.handle))
|
||||
this.handle = this.element.down('.'+options.handle, 0);
|
||||
|
||||
if(!this.handle) this.handle = $(options.handle);
|
||||
if(!this.handle) this.handle = this.element;
|
||||
|
||||
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
|
||||
options.scroll = $(options.scroll);
|
||||
this._isScrollChild = Element.childOf(this.element, options.scroll);
|
||||
}
|
||||
|
||||
Element.makePositioned(this.element); // fix IE
|
||||
|
||||
this.options = options;
|
||||
this.dragging = false;
|
||||
|
||||
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
|
||||
Event.observe(this.handle, "mousedown", this.eventMouseDown);
|
||||
|
||||
Draggables.register(this);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
|
||||
Draggables.unregister(this);
|
||||
},
|
||||
|
||||
currentDelta: function() {
|
||||
return([
|
||||
parseInt(Element.getStyle(this.element,'left') || '0'),
|
||||
parseInt(Element.getStyle(this.element,'top') || '0')]);
|
||||
},
|
||||
|
||||
initDrag: function(event) {
|
||||
if(!Object.isUndefined(Draggable._dragging[this.element]) &&
|
||||
Draggable._dragging[this.element]) return;
|
||||
if(Event.isLeftClick(event)) {
|
||||
// abort on form elements, fixes a Firefox issue
|
||||
var src = Event.element(event);
|
||||
if((tag_name = src.tagName.toUpperCase()) && (
|
||||
tag_name=='INPUT' ||
|
||||
tag_name=='SELECT' ||
|
||||
tag_name=='OPTION' ||
|
||||
tag_name=='BUTTON' ||
|
||||
tag_name=='TEXTAREA')) return;
|
||||
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
var pos = Position.cumulativeOffset(this.element);
|
||||
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
|
||||
|
||||
Draggables.activate(this);
|
||||
Event.stop(event);
|
||||
}
|
||||
},
|
||||
|
||||
startDrag: function(event) {
|
||||
this.dragging = true;
|
||||
if(!this.delta)
|
||||
this.delta = this.currentDelta();
|
||||
|
||||
if(this.options.zindex) {
|
||||
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
|
||||
this.element.style.zIndex = this.options.zindex;
|
||||
}
|
||||
|
||||
if(this.options.ghosting) {
|
||||
this._clone = this.element.cloneNode(true);
|
||||
this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
|
||||
if (!this._originallyAbsolute)
|
||||
Position.absolutize(this.element);
|
||||
this.element.parentNode.insertBefore(this._clone, this.element);
|
||||
}
|
||||
|
||||
if(this.options.scroll) {
|
||||
if (this.options.scroll == window) {
|
||||
var where = this._getWindowScroll(this.options.scroll);
|
||||
this.originalScrollLeft = where.left;
|
||||
this.originalScrollTop = where.top;
|
||||
} else {
|
||||
this.originalScrollLeft = this.options.scroll.scrollLeft;
|
||||
this.originalScrollTop = this.options.scroll.scrollTop;
|
||||
}
|
||||
}
|
||||
|
||||
Draggables.notify('onStart', this, event);
|
||||
|
||||
if(this.options.starteffect) this.options.starteffect(this.element);
|
||||
},
|
||||
|
||||
updateDrag: function(event, pointer) {
|
||||
if(!this.dragging) this.startDrag(event);
|
||||
|
||||
if(!this.options.quiet){
|
||||
Position.prepare();
|
||||
Droppables.show(pointer, this.element);
|
||||
}
|
||||
|
||||
Draggables.notify('onDrag', this, event);
|
||||
|
||||
this.draw(pointer);
|
||||
if(this.options.change) this.options.change(this);
|
||||
|
||||
if(this.options.scroll) {
|
||||
this.stopScrolling();
|
||||
|
||||
var p;
|
||||
if (this.options.scroll == window) {
|
||||
with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
|
||||
} else {
|
||||
p = Position.page(this.options.scroll);
|
||||
p[0] += this.options.scroll.scrollLeft + Position.deltaX;
|
||||
p[1] += this.options.scroll.scrollTop + Position.deltaY;
|
||||
p.push(p[0]+this.options.scroll.offsetWidth);
|
||||
p.push(p[1]+this.options.scroll.offsetHeight);
|
||||
}
|
||||
var speed = [0,0];
|
||||
if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
|
||||
if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
|
||||
if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
|
||||
if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
|
||||
this.startScrolling(speed);
|
||||
}
|
||||
|
||||
// fix AppleWebKit rendering
|
||||
if(Prototype.Browser.WebKit) window.scrollBy(0,0);
|
||||
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
finishDrag: function(event, success) {
|
||||
this.dragging = false;
|
||||
|
||||
if(this.options.quiet){
|
||||
Position.prepare();
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
Droppables.show(pointer, this.element);
|
||||
}
|
||||
|
||||
if(this.options.ghosting) {
|
||||
if (!this._originallyAbsolute)
|
||||
Position.relativize(this.element);
|
||||
delete this._originallyAbsolute;
|
||||
Element.remove(this._clone);
|
||||
this._clone = null;
|
||||
}
|
||||
|
||||
var dropped = false;
|
||||
if(success) {
|
||||
dropped = Droppables.fire(event, this.element);
|
||||
if (!dropped) dropped = false;
|
||||
}
|
||||
if(dropped && this.options.onDropped) this.options.onDropped(this.element);
|
||||
Draggables.notify('onEnd', this, event);
|
||||
|
||||
var revert = this.options.revert;
|
||||
if(revert && Object.isFunction(revert)) revert = revert(this.element);
|
||||
|
||||
var d = this.currentDelta();
|
||||
if(revert && this.options.reverteffect) {
|
||||
if (dropped == 0 || revert != 'failure')
|
||||
this.options.reverteffect(this.element,
|
||||
d[1]-this.delta[1], d[0]-this.delta[0]);
|
||||
} else {
|
||||
this.delta = d;
|
||||
}
|
||||
|
||||
if(this.options.zindex)
|
||||
this.element.style.zIndex = this.originalZ;
|
||||
|
||||
if(this.options.endeffect)
|
||||
this.options.endeffect(this.element);
|
||||
|
||||
Draggables.deactivate(this);
|
||||
Droppables.reset();
|
||||
},
|
||||
|
||||
keyPress: function(event) {
|
||||
if(event.keyCode!=Event.KEY_ESC) return;
|
||||
this.finishDrag(event, false);
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
endDrag: function(event) {
|
||||
if(!this.dragging) return;
|
||||
this.stopScrolling();
|
||||
this.finishDrag(event, true);
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
draw: function(point) {
|
||||
var pos = Position.cumulativeOffset(this.element);
|
||||
if(this.options.ghosting) {
|
||||
var r = Position.realOffset(this.element);
|
||||
pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
|
||||
}
|
||||
|
||||
var d = this.currentDelta();
|
||||
pos[0] -= d[0]; pos[1] -= d[1];
|
||||
|
||||
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
|
||||
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
|
||||
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
|
||||
}
|
||||
|
||||
var p = [0,1].map(function(i){
|
||||
return (point[i]-pos[i]-this.offset[i])
|
||||
}.bind(this));
|
||||
|
||||
if(this.options.snap) {
|
||||
if(Object.isFunction(this.options.snap)) {
|
||||
p = this.options.snap(p[0],p[1],this);
|
||||
} else {
|
||||
if(Object.isArray(this.options.snap)) {
|
||||
p = p.map( function(v, i) {
|
||||
return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
|
||||
} else {
|
||||
p = p.map( function(v) {
|
||||
return (v/this.options.snap).round()*this.options.snap }.bind(this));
|
||||
}
|
||||
}}
|
||||
|
||||
var style = this.element.style;
|
||||
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
|
||||
style.left = p[0] + "px";
|
||||
if((!this.options.constraint) || (this.options.constraint=='vertical'))
|
||||
style.top = p[1] + "px";
|
||||
|
||||
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
|
||||
},
|
||||
|
||||
stopScrolling: function() {
|
||||
if(this.scrollInterval) {
|
||||
clearInterval(this.scrollInterval);
|
||||
this.scrollInterval = null;
|
||||
Draggables._lastScrollPointer = null;
|
||||
}
|
||||
},
|
||||
|
||||
startScrolling: function(speed) {
|
||||
if(!(speed[0] || speed[1])) return;
|
||||
this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
|
||||
this.lastScrolled = new Date();
|
||||
this.scrollInterval = setInterval(this.scroll.bind(this), 10);
|
||||
},
|
||||
|
||||
scroll: function() {
|
||||
var current = new Date();
|
||||
var delta = current - this.lastScrolled;
|
||||
this.lastScrolled = current;
|
||||
if(this.options.scroll == window) {
|
||||
with (this._getWindowScroll(this.options.scroll)) {
|
||||
if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
|
||||
var d = delta / 1000;
|
||||
this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
|
||||
this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
|
||||
}
|
||||
|
||||
Position.prepare();
|
||||
Droppables.show(Draggables._lastPointer, this.element);
|
||||
Draggables.notify('onDrag', this);
|
||||
if (this._isScrollChild) {
|
||||
Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
|
||||
Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
|
||||
Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
|
||||
if (Draggables._lastScrollPointer[0] < 0)
|
||||
Draggables._lastScrollPointer[0] = 0;
|
||||
if (Draggables._lastScrollPointer[1] < 0)
|
||||
Draggables._lastScrollPointer[1] = 0;
|
||||
this.draw(Draggables._lastScrollPointer);
|
||||
}
|
||||
|
||||
if(this.options.change) this.options.change(this);
|
||||
},
|
||||
|
||||
_getWindowScroll: function(w) {
|
||||
var T, L, W, H;
|
||||
with (w.document) {
|
||||
if (w.document.documentElement && documentElement.scrollTop) {
|
||||
T = documentElement.scrollTop;
|
||||
L = documentElement.scrollLeft;
|
||||
} else if (w.document.body) {
|
||||
T = body.scrollTop;
|
||||
L = body.scrollLeft;
|
||||
}
|
||||
if (w.innerWidth) {
|
||||
W = w.innerWidth;
|
||||
H = w.innerHeight;
|
||||
} else if (w.document.documentElement && documentElement.clientWidth) {
|
||||
W = documentElement.clientWidth;
|
||||
H = documentElement.clientHeight;
|
||||
} else {
|
||||
W = body.offsetWidth;
|
||||
H = body.offsetHeight;
|
||||
}
|
||||
}
|
||||
return { top: T, left: L, width: W, height: H };
|
||||
}
|
||||
});
|
||||
|
||||
Draggable._dragging = { };
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var SortableObserver = Class.create({
|
||||
initialize: function(element, observer) {
|
||||
this.element = $(element);
|
||||
this.observer = observer;
|
||||
this.lastValue = Sortable.serialize(this.element);
|
||||
},
|
||||
|
||||
onStart: function() {
|
||||
this.lastValue = Sortable.serialize(this.element);
|
||||
},
|
||||
|
||||
onEnd: function() {
|
||||
Sortable.unmark();
|
||||
if(this.lastValue != Sortable.serialize(this.element))
|
||||
this.observer(this.element)
|
||||
}
|
||||
});
|
||||
|
||||
var Sortable = {
|
||||
SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
|
||||
|
||||
sortables: { },
|
||||
|
||||
_findRootElement: function(element) {
|
||||
while (element.tagName.toUpperCase() != "BODY") {
|
||||
if(element.id && Sortable.sortables[element.id]) return element;
|
||||
element = element.parentNode;
|
||||
}
|
||||
},
|
||||
|
||||
options: function(element) {
|
||||
element = Sortable._findRootElement($(element));
|
||||
if(!element) return;
|
||||
return Sortable.sortables[element.id];
|
||||
},
|
||||
|
||||
destroy: function(element){
|
||||
element = $(element);
|
||||
var s = Sortable.sortables[element.id];
|
||||
|
||||
if(s) {
|
||||
Draggables.removeObserver(s.element);
|
||||
s.droppables.each(function(d){ Droppables.remove(d) });
|
||||
s.draggables.invoke('destroy');
|
||||
|
||||
delete Sortable.sortables[s.element.id];
|
||||
}
|
||||
},
|
||||
|
||||
create: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
element: element,
|
||||
tag: 'li', // assumes li children, override with tag: 'tagname'
|
||||
dropOnEmpty: false,
|
||||
tree: false,
|
||||
treeTag: 'ul',
|
||||
overlap: 'vertical', // one of 'vertical', 'horizontal'
|
||||
constraint: 'vertical', // one of 'vertical', 'horizontal', false
|
||||
containment: element, // also takes array of elements (or id's); or false
|
||||
handle: false, // or a CSS class
|
||||
only: false,
|
||||
delay: 0,
|
||||
hoverclass: null,
|
||||
ghosting: false,
|
||||
quiet: false,
|
||||
scroll: false,
|
||||
scrollSensitivity: 20,
|
||||
scrollSpeed: 15,
|
||||
format: this.SERIALIZE_RULE,
|
||||
|
||||
// these take arrays of elements or ids and can be
|
||||
// used for better initialization performance
|
||||
elements: false,
|
||||
handles: false,
|
||||
|
||||
onChange: Prototype.emptyFunction,
|
||||
onUpdate: Prototype.emptyFunction
|
||||
}, arguments[1] || { });
|
||||
|
||||
// clear any old sortable with same element
|
||||
this.destroy(element);
|
||||
|
||||
// build options for the draggables
|
||||
var options_for_draggable = {
|
||||
revert: true,
|
||||
quiet: options.quiet,
|
||||
scroll: options.scroll,
|
||||
scrollSpeed: options.scrollSpeed,
|
||||
scrollSensitivity: options.scrollSensitivity,
|
||||
delay: options.delay,
|
||||
ghosting: options.ghosting,
|
||||
constraint: options.constraint,
|
||||
handle: options.handle };
|
||||
|
||||
if(options.starteffect)
|
||||
options_for_draggable.starteffect = options.starteffect;
|
||||
|
||||
if(options.reverteffect)
|
||||
options_for_draggable.reverteffect = options.reverteffect;
|
||||
else
|
||||
if(options.ghosting) options_for_draggable.reverteffect = function(element) {
|
||||
element.style.top = 0;
|
||||
element.style.left = 0;
|
||||
};
|
||||
|
||||
if(options.endeffect)
|
||||
options_for_draggable.endeffect = options.endeffect;
|
||||
|
||||
if(options.zindex)
|
||||
options_for_draggable.zindex = options.zindex;
|
||||
|
||||
// build options for the droppables
|
||||
var options_for_droppable = {
|
||||
overlap: options.overlap,
|
||||
containment: options.containment,
|
||||
tree: options.tree,
|
||||
hoverclass: options.hoverclass,
|
||||
onHover: Sortable.onHover
|
||||
};
|
||||
|
||||
var options_for_tree = {
|
||||
onHover: Sortable.onEmptyHover,
|
||||
overlap: options.overlap,
|
||||
containment: options.containment,
|
||||
hoverclass: options.hoverclass
|
||||
};
|
||||
|
||||
// fix for gecko engine
|
||||
Element.cleanWhitespace(element);
|
||||
|
||||
options.draggables = [];
|
||||
options.droppables = [];
|
||||
|
||||
// drop on empty handling
|
||||
if(options.dropOnEmpty || options.tree) {
|
||||
Droppables.add(element, options_for_tree);
|
||||
options.droppables.push(element);
|
||||
}
|
||||
|
||||
(options.elements || this.findElements(element, options) || []).each( function(e,i) {
|
||||
var handle = options.handles ? $(options.handles[i]) :
|
||||
(options.handle ? $(e).select('.' + options.handle)[0] : e);
|
||||
options.draggables.push(
|
||||
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
|
||||
Droppables.add(e, options_for_droppable);
|
||||
if(options.tree) e.treeNode = element;
|
||||
options.droppables.push(e);
|
||||
});
|
||||
|
||||
if(options.tree) {
|
||||
(Sortable.findTreeElements(element, options) || []).each( function(e) {
|
||||
Droppables.add(e, options_for_tree);
|
||||
e.treeNode = element;
|
||||
options.droppables.push(e);
|
||||
});
|
||||
}
|
||||
|
||||
// keep reference
|
||||
this.sortables[element.id] = options;
|
||||
|
||||
// for onupdate
|
||||
Draggables.addObserver(new SortableObserver(element, options.onUpdate));
|
||||
|
||||
},
|
||||
|
||||
// return all suitable-for-sortable elements in a guaranteed order
|
||||
findElements: function(element, options) {
|
||||
return Element.findChildren(
|
||||
element, options.only, options.tree ? true : false, options.tag);
|
||||
},
|
||||
|
||||
findTreeElements: function(element, options) {
|
||||
return Element.findChildren(
|
||||
element, options.only, options.tree ? true : false, options.treeTag);
|
||||
},
|
||||
|
||||
onHover: function(element, dropon, overlap) {
|
||||
if(Element.isParent(dropon, element)) return;
|
||||
|
||||
if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
|
||||
return;
|
||||
} else if(overlap>0.5) {
|
||||
Sortable.mark(dropon, 'before');
|
||||
if(dropon.previousSibling != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = "hidden"; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, dropon);
|
||||
if(dropon.parentNode!=oldParentNode)
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
Sortable.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
} else {
|
||||
Sortable.mark(dropon, 'after');
|
||||
var nextElement = dropon.nextSibling || null;
|
||||
if(nextElement != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = "hidden"; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, nextElement);
|
||||
if(dropon.parentNode!=oldParentNode)
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
Sortable.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onEmptyHover: function(element, dropon, overlap) {
|
||||
var oldParentNode = element.parentNode;
|
||||
var droponOptions = Sortable.options(dropon);
|
||||
|
||||
if(!Element.isParent(dropon, element)) {
|
||||
var index;
|
||||
|
||||
var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
|
||||
var child = null;
|
||||
|
||||
if(children) {
|
||||
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
|
||||
|
||||
for (index = 0; index < children.length; index += 1) {
|
||||
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
|
||||
offset -= Element.offsetSize (children[index], droponOptions.overlap);
|
||||
} else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
|
||||
child = index + 1 < children.length ? children[index + 1] : null;
|
||||
break;
|
||||
} else {
|
||||
child = children[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dropon.insertBefore(element, child);
|
||||
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
droponOptions.onChange(element);
|
||||
}
|
||||
},
|
||||
|
||||
unmark: function() {
|
||||
if(Sortable._marker) Sortable._marker.hide();
|
||||
},
|
||||
|
||||
mark: function(dropon, position) {
|
||||
// mark on ghosting only
|
||||
var sortable = Sortable.options(dropon.parentNode);
|
||||
if(sortable && !sortable.ghosting) return;
|
||||
|
||||
if(!Sortable._marker) {
|
||||
Sortable._marker =
|
||||
($('dropmarker') || Element.extend(document.createElement('DIV'))).
|
||||
hide().addClassName('dropmarker').setStyle({position:'absolute'});
|
||||
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
|
||||
}
|
||||
var offsets = Position.cumulativeOffset(dropon);
|
||||
Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
|
||||
|
||||
if(position=='after')
|
||||
if(sortable.overlap == 'horizontal')
|
||||
Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
|
||||
else
|
||||
Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
|
||||
|
||||
Sortable._marker.show();
|
||||
},
|
||||
|
||||
_tree: function(element, options, parent) {
|
||||
var children = Sortable.findElements(element, options) || [];
|
||||
|
||||
for (var i = 0; i < children.length; ++i) {
|
||||
var match = children[i].id.match(options.format);
|
||||
|
||||
if (!match) continue;
|
||||
|
||||
var child = {
|
||||
id: encodeURIComponent(match ? match[1] : null),
|
||||
element: element,
|
||||
parent: parent,
|
||||
children: [],
|
||||
position: parent.children.length,
|
||||
container: $(children[i]).down(options.treeTag)
|
||||
};
|
||||
|
||||
/* Get the element containing the children and recurse over it */
|
||||
if (child.container)
|
||||
this._tree(child.container, options, child);
|
||||
|
||||
parent.children.push (child);
|
||||
}
|
||||
|
||||
return parent;
|
||||
},
|
||||
|
||||
tree: function(element) {
|
||||
element = $(element);
|
||||
var sortableOptions = this.options(element);
|
||||
var options = Object.extend({
|
||||
tag: sortableOptions.tag,
|
||||
treeTag: sortableOptions.treeTag,
|
||||
only: sortableOptions.only,
|
||||
name: element.id,
|
||||
format: sortableOptions.format
|
||||
}, arguments[1] || { });
|
||||
|
||||
var root = {
|
||||
id: null,
|
||||
parent: null,
|
||||
children: [],
|
||||
container: element,
|
||||
position: 0
|
||||
};
|
||||
|
||||
return Sortable._tree(element, options, root);
|
||||
},
|
||||
|
||||
/* Construct a [i] index for a particular node */
|
||||
_constructIndex: function(node) {
|
||||
var index = '';
|
||||
do {
|
||||
if (node.id) index = '[' + node.position + ']' + index;
|
||||
} while ((node = node.parent) != null);
|
||||
return index;
|
||||
},
|
||||
|
||||
sequence: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend(this.options(element), arguments[1] || { });
|
||||
|
||||
return $(this.findElements(element, options) || []).map( function(item) {
|
||||
return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
|
||||
});
|
||||
},
|
||||
|
||||
setSequence: function(element, new_sequence) {
|
||||
element = $(element);
|
||||
var options = Object.extend(this.options(element), arguments[2] || { });
|
||||
|
||||
var nodeMap = { };
|
||||
this.findElements(element, options).each( function(n) {
|
||||
if (n.id.match(options.format))
|
||||
nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
|
||||
n.parentNode.removeChild(n);
|
||||
});
|
||||
|
||||
new_sequence.each(function(ident) {
|
||||
var n = nodeMap[ident];
|
||||
if (n) {
|
||||
n[1].appendChild(n[0]);
|
||||
delete nodeMap[ident];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
serialize: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend(Sortable.options(element), arguments[1] || { });
|
||||
var name = encodeURIComponent(
|
||||
(arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
|
||||
|
||||
if (options.tree) {
|
||||
return Sortable.tree(element, arguments[1]).children.map( function (item) {
|
||||
return [name + Sortable._constructIndex(item) + "[id]=" +
|
||||
encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
|
||||
}).flatten().join('&');
|
||||
} else {
|
||||
return Sortable.sequence(element, arguments[1]).map( function(item) {
|
||||
return name + "[]=" + encodeURIComponent(item);
|
||||
}).join('&');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns true if child is contained within element
|
||||
Element.isParent = function(child, element) {
|
||||
if (!child.parentNode || child == element) return false;
|
||||
if (child.parentNode == element) return true;
|
||||
return Element.isParent(child.parentNode, element);
|
||||
};
|
||||
|
||||
Element.findChildren = function(element, only, recursive, tagName) {
|
||||
if(!element.hasChildNodes()) return null;
|
||||
tagName = tagName.toUpperCase();
|
||||
if(only) only = [only].flatten();
|
||||
var elements = [];
|
||||
$A(element.childNodes).each( function(e) {
|
||||
if(e.tagName && e.tagName.toUpperCase()==tagName &&
|
||||
(!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
|
||||
elements.push(e);
|
||||
if(recursive) {
|
||||
var grandchildren = Element.findChildren(e, only, recursive, tagName);
|
||||
if(grandchildren) elements.push(grandchildren);
|
||||
}
|
||||
});
|
||||
|
||||
return (elements.length>0 ? elements.flatten() : []);
|
||||
};
|
||||
|
||||
Element.offsetSize = function (element, type) {
|
||||
return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
|
||||
};
|
||||
+1130
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1 @@
|
||||
<html>␍<head><title>IP.Board - Bulletin Board System</title></head>␍<body>␍<h1>403: IP.Board -> Forbidden</h1>␍<hr>␍You have reached this page in error, please use your back button to return to the forum.␍<hr>␍<a href="http://www.invisionboard.com/">IP.Board</a>␍</body>␍</html>␍
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,60 @@
|
||||
// script.aculo.us scriptaculous.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
|
||||
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
var Scriptaculous = {
|
||||
Version: '1.8.2',
|
||||
require: function(libraryName) {
|
||||
// inserting via DOM fails in Safari 2.0, so brute force approach
|
||||
document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
|
||||
},
|
||||
REQUIRED_PROTOTYPE: '1.6.0.3',
|
||||
load: function() {
|
||||
function convertVersionString(versionString) {
|
||||
var v = versionString.replace(/_.*|\./g, '');
|
||||
v = parseInt(v + '0'.times(4-v.length));
|
||||
return versionString.indexOf('_') > -1 ? v-1 : v;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
var js = /scriptaculous\.js(\?.*)?$/;
|
||||
$$('head script[src]').findAll(function(s) {
|
||||
return s.src.match(js);
|
||||
}).each(function(s) {
|
||||
var path = s.src.replace(js, ''),
|
||||
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();
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
// script.aculo.us slider.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
|
||||
|
||||
// Copyright (c) 2005-2008 Marty Haught, Thomas Fuchs
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
if (!Control) var Control = { };
|
||||
|
||||
// options:
|
||||
// axis: 'vertical', or 'horizontal' (default)
|
||||
//
|
||||
// callbacks:
|
||||
// onChange(value)
|
||||
// onSlide(value)
|
||||
Control.Slider = Class.create({
|
||||
initialize: function(handle, track, options) {
|
||||
var slider = this;
|
||||
|
||||
if (Object.isArray(handle)) {
|
||||
this.handles = handle.collect( function(e) { return $(e) });
|
||||
} else {
|
||||
this.handles = [$(handle)];
|
||||
}
|
||||
|
||||
this.track = $(track);
|
||||
this.options = options || { };
|
||||
|
||||
this.axis = this.options.axis || 'horizontal';
|
||||
this.increment = this.options.increment || 1;
|
||||
this.step = parseInt(this.options.step || '1');
|
||||
this.range = this.options.range || $R(0,1);
|
||||
|
||||
this.value = 0; // assure backwards compat
|
||||
this.values = this.handles.map( function() { return 0 });
|
||||
this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
|
||||
this.options.startSpan = $(this.options.startSpan || null);
|
||||
this.options.endSpan = $(this.options.endSpan || null);
|
||||
|
||||
this.restricted = this.options.restricted || false;
|
||||
|
||||
this.maximum = this.options.maximum || this.range.end;
|
||||
this.minimum = this.options.minimum || this.range.start;
|
||||
|
||||
// Will be used to align the handle onto the track, if necessary
|
||||
this.alignX = parseInt(this.options.alignX || '0');
|
||||
this.alignY = parseInt(this.options.alignY || '0');
|
||||
|
||||
this.trackLength = this.maximumOffset() - this.minimumOffset();
|
||||
|
||||
this.handleLength = this.isVertical() ?
|
||||
(this.handles[0].offsetHeight != 0 ?
|
||||
this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
|
||||
(this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
|
||||
this.handles[0].style.width.replace(/px$/,""));
|
||||
|
||||
this.active = false;
|
||||
this.dragging = false;
|
||||
this.disabled = false;
|
||||
|
||||
if (this.options.disabled) this.setDisabled();
|
||||
|
||||
// Allowed values array
|
||||
this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
|
||||
if (this.allowedValues) {
|
||||
this.minimum = this.allowedValues.min();
|
||||
this.maximum = this.allowedValues.max();
|
||||
}
|
||||
|
||||
this.eventMouseDown = this.startDrag.bindAsEventListener(this);
|
||||
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
|
||||
this.eventMouseMove = this.update.bindAsEventListener(this);
|
||||
|
||||
// Initialize handles in reverse (make sure first handle is active)
|
||||
this.handles.each( function(h,i) {
|
||||
i = slider.handles.length-1-i;
|
||||
slider.setValue(parseFloat(
|
||||
(Object.isArray(slider.options.sliderValue) ?
|
||||
slider.options.sliderValue[i] : slider.options.sliderValue) ||
|
||||
slider.range.start), i);
|
||||
h.makePositioned().observe("mousedown", slider.eventMouseDown);
|
||||
});
|
||||
|
||||
this.track.observe("mousedown", this.eventMouseDown);
|
||||
document.observe("mouseup", this.eventMouseUp);
|
||||
document.observe("mousemove", this.eventMouseMove);
|
||||
|
||||
this.initialized = true;
|
||||
},
|
||||
dispose: function() {
|
||||
var slider = this;
|
||||
Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
|
||||
Event.stopObserving(document, "mouseup", this.eventMouseUp);
|
||||
Event.stopObserving(document, "mousemove", this.eventMouseMove);
|
||||
this.handles.each( function(h) {
|
||||
Event.stopObserving(h, "mousedown", slider.eventMouseDown);
|
||||
});
|
||||
},
|
||||
setDisabled: function(){
|
||||
this.disabled = true;
|
||||
},
|
||||
setEnabled: function(){
|
||||
this.disabled = false;
|
||||
},
|
||||
getNearestValue: function(value){
|
||||
if (this.allowedValues){
|
||||
if (value >= this.allowedValues.max()) return(this.allowedValues.max());
|
||||
if (value <= this.allowedValues.min()) return(this.allowedValues.min());
|
||||
|
||||
var offset = Math.abs(this.allowedValues[0] - value);
|
||||
var newValue = this.allowedValues[0];
|
||||
this.allowedValues.each( function(v) {
|
||||
var currentOffset = Math.abs(v - value);
|
||||
if (currentOffset <= offset){
|
||||
newValue = v;
|
||||
offset = currentOffset;
|
||||
}
|
||||
});
|
||||
return newValue;
|
||||
}
|
||||
if (value > this.range.end) return this.range.end;
|
||||
if (value < this.range.start) return this.range.start;
|
||||
return value;
|
||||
},
|
||||
setValue: function(sliderValue, handleIdx){
|
||||
if (!this.active) {
|
||||
this.activeHandleIdx = handleIdx || 0;
|
||||
this.activeHandle = this.handles[this.activeHandleIdx];
|
||||
this.updateStyles();
|
||||
}
|
||||
handleIdx = handleIdx || this.activeHandleIdx || 0;
|
||||
if (this.initialized && this.restricted) {
|
||||
if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
|
||||
sliderValue = this.values[handleIdx-1];
|
||||
if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
|
||||
sliderValue = this.values[handleIdx+1];
|
||||
}
|
||||
sliderValue = this.getNearestValue(sliderValue);
|
||||
this.values[handleIdx] = sliderValue;
|
||||
this.value = this.values[0]; // assure backwards compat
|
||||
|
||||
this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
|
||||
this.translateToPx(sliderValue);
|
||||
|
||||
this.drawSpans();
|
||||
if (!this.dragging || !this.event) this.updateFinished();
|
||||
},
|
||||
setValueBy: function(delta, handleIdx) {
|
||||
this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
|
||||
handleIdx || this.activeHandleIdx || 0);
|
||||
},
|
||||
translateToPx: function(value) {
|
||||
return Math.round(
|
||||
((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
|
||||
(value - this.range.start)) + "px";
|
||||
},
|
||||
translateToValue: function(offset) {
|
||||
return ((offset/(this.trackLength-this.handleLength) *
|
||||
(this.range.end-this.range.start)) + this.range.start);
|
||||
},
|
||||
getRange: function(range) {
|
||||
var v = this.values.sortBy(Prototype.K);
|
||||
range = range || 0;
|
||||
return $R(v[range],v[range+1]);
|
||||
},
|
||||
minimumOffset: function(){
|
||||
return(this.isVertical() ? this.alignY : this.alignX);
|
||||
},
|
||||
maximumOffset: function(){
|
||||
return(this.isVertical() ?
|
||||
(this.track.offsetHeight != 0 ? this.track.offsetHeight :
|
||||
this.track.style.height.replace(/px$/,"")) - this.alignY :
|
||||
(this.track.offsetWidth != 0 ? this.track.offsetWidth :
|
||||
this.track.style.width.replace(/px$/,"")) - this.alignX);
|
||||
},
|
||||
isVertical: function(){
|
||||
return (this.axis == 'vertical');
|
||||
},
|
||||
drawSpans: function() {
|
||||
var slider = this;
|
||||
if (this.spans)
|
||||
$R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
|
||||
if (this.options.startSpan)
|
||||
this.setSpan(this.options.startSpan,
|
||||
$R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
|
||||
if (this.options.endSpan)
|
||||
this.setSpan(this.options.endSpan,
|
||||
$R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
|
||||
},
|
||||
setSpan: function(span, range) {
|
||||
if (this.isVertical()) {
|
||||
span.style.top = this.translateToPx(range.start);
|
||||
span.style.height = this.translateToPx(range.end - range.start + this.range.start);
|
||||
} else {
|
||||
span.style.left = this.translateToPx(range.start);
|
||||
span.style.width = this.translateToPx(range.end - range.start + this.range.start);
|
||||
}
|
||||
},
|
||||
updateStyles: function() {
|
||||
this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
|
||||
Element.addClassName(this.activeHandle, 'selected');
|
||||
},
|
||||
startDrag: function(event) {
|
||||
if (Event.isLeftClick(event)) {
|
||||
if (!this.disabled){
|
||||
this.active = true;
|
||||
|
||||
var handle = Event.element(event);
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
var track = handle;
|
||||
if (track==this.track) {
|
||||
var offsets = Position.cumulativeOffset(this.track);
|
||||
this.event = event;
|
||||
this.setValue(this.translateToValue(
|
||||
(this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
|
||||
));
|
||||
var offsets = Position.cumulativeOffset(this.activeHandle);
|
||||
this.offsetX = (pointer[0] - offsets[0]);
|
||||
this.offsetY = (pointer[1] - offsets[1]);
|
||||
} else {
|
||||
// find the handle (prevents issues with Safari)
|
||||
while((this.handles.indexOf(handle) == -1) && handle.parentNode)
|
||||
handle = handle.parentNode;
|
||||
|
||||
if (this.handles.indexOf(handle)!=-1) {
|
||||
this.activeHandle = handle;
|
||||
this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
|
||||
this.updateStyles();
|
||||
|
||||
var offsets = Position.cumulativeOffset(this.activeHandle);
|
||||
this.offsetX = (pointer[0] - offsets[0]);
|
||||
this.offsetY = (pointer[1] - offsets[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Event.stop(event);
|
||||
}
|
||||
},
|
||||
update: function(event) {
|
||||
if (this.active) {
|
||||
if (!this.dragging) this.dragging = true;
|
||||
this.draw(event);
|
||||
if (Prototype.Browser.WebKit) window.scrollBy(0,0);
|
||||
Event.stop(event);
|
||||
}
|
||||
},
|
||||
draw: function(event) {
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
var offsets = Position.cumulativeOffset(this.track);
|
||||
pointer[0] -= this.offsetX + offsets[0];
|
||||
pointer[1] -= this.offsetY + offsets[1];
|
||||
this.event = event;
|
||||
this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
|
||||
if (this.initialized && this.options.onSlide)
|
||||
this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
|
||||
},
|
||||
endDrag: function(event) {
|
||||
if (this.active && this.dragging) {
|
||||
this.finishDrag(event, true);
|
||||
Event.stop(event);
|
||||
}
|
||||
this.active = false;
|
||||
this.dragging = false;
|
||||
},
|
||||
finishDrag: function(event, success) {
|
||||
this.active = false;
|
||||
this.dragging = false;
|
||||
this.updateFinished();
|
||||
},
|
||||
updateFinished: function() {
|
||||
if (this.initialized && this.options.onChange)
|
||||
this.options.onChange(this.values.length>1 ? this.values : this.value, this);
|
||||
this.event = null;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
// script.aculo.us sound.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
|
||||
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
//
|
||||
// Based on code created by Jules Gravinese (http://www.webveteran.com/)
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
Sound = {
|
||||
tracks: {},
|
||||
_enabled: true,
|
||||
template:
|
||||
new Template('<embed style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>'),
|
||||
enable: function(){
|
||||
Sound._enabled = true;
|
||||
},
|
||||
disable: function(){
|
||||
Sound._enabled = false;
|
||||
},
|
||||
play: function(url){
|
||||
if(!Sound._enabled) return;
|
||||
var options = Object.extend({
|
||||
track: 'global', url: url, replace: false
|
||||
}, arguments[1] || {});
|
||||
|
||||
if(options.replace && this.tracks[options.track]) {
|
||||
$R(0, this.tracks[options.track].id).each(function(id){
|
||||
var sound = $('sound_'+options.track+'_'+id);
|
||||
sound.Stop && sound.Stop();
|
||||
sound.remove();
|
||||
});
|
||||
this.tracks[options.track] = null;
|
||||
}
|
||||
|
||||
if(!this.tracks[options.track])
|
||||
this.tracks[options.track] = { id: 0 };
|
||||
else
|
||||
this.tracks[options.track].id++;
|
||||
|
||||
options.id = this.tracks[options.track].id;
|
||||
$$('body')[0].insert(
|
||||
Prototype.Browser.IE ? new Element('bgsound',{
|
||||
id: 'sound_'+options.track+'_'+options.id,
|
||||
src: options.url, loop: 1, autostart: true
|
||||
}) : Sound.template.evaluate(options));
|
||||
}
|
||||
};
|
||||
|
||||
if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
|
||||
if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
|
||||
Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>');
|
||||
else
|
||||
Sound.play = function(){};
|
||||
}
|
||||
@@ -0,0 +1,568 @@
|
||||
// script.aculo.us unittest.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008
|
||||
|
||||
// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
|
||||
// (c) 2005-2008 Michael Schuerig (http://www.schuerig.de/michael/)
|
||||
//
|
||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
||||
|
||||
// experimental, Firefox-only
|
||||
Event.simulateMouse = function(element, eventName) {
|
||||
var options = Object.extend({
|
||||
pointerX: 0,
|
||||
pointerY: 0,
|
||||
buttons: 0,
|
||||
ctrlKey: false,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false
|
||||
}, arguments[2] || {});
|
||||
var oEvent = document.createEvent("MouseEvents");
|
||||
oEvent.initMouseEvent(eventName, true, true, document.defaultView,
|
||||
options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
|
||||
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
|
||||
|
||||
if(this.mark) Element.remove(this.mark);
|
||||
this.mark = document.createElement('div');
|
||||
this.mark.appendChild(document.createTextNode(" "));
|
||||
document.body.appendChild(this.mark);
|
||||
this.mark.style.position = 'absolute';
|
||||
this.mark.style.top = options.pointerY + "px";
|
||||
this.mark.style.left = options.pointerX + "px";
|
||||
this.mark.style.width = "5px";
|
||||
this.mark.style.height = "5px;";
|
||||
this.mark.style.borderTop = "1px solid red;";
|
||||
this.mark.style.borderLeft = "1px solid red;";
|
||||
|
||||
if(this.step)
|
||||
alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
|
||||
|
||||
$(element).dispatchEvent(oEvent);
|
||||
};
|
||||
|
||||
// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
|
||||
// You need to downgrade to 1.0.4 for now to get this working
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
|
||||
Event.simulateKey = function(element, eventName) {
|
||||
var options = Object.extend({
|
||||
ctrlKey: false,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
keyCode: 0,
|
||||
charCode: 0
|
||||
}, arguments[2] || {});
|
||||
|
||||
var oEvent = document.createEvent("KeyEvents");
|
||||
oEvent.initKeyEvent(eventName, true, true, window,
|
||||
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
|
||||
options.keyCode, options.charCode );
|
||||
$(element).dispatchEvent(oEvent);
|
||||
};
|
||||
|
||||
Event.simulateKeys = function(element, command) {
|
||||
for(var i=0; i<command.length; i++) {
|
||||
Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
|
||||
}
|
||||
};
|
||||
|
||||
var Test = {};
|
||||
Test.Unit = {};
|
||||
|
||||
// security exception workaround
|
||||
Test.Unit.inspect = Object.inspect;
|
||||
|
||||
Test.Unit.Logger = Class.create();
|
||||
Test.Unit.Logger.prototype = {
|
||||
initialize: function(log) {
|
||||
this.log = $(log);
|
||||
if (this.log) {
|
||||
this._createLogTable();
|
||||
}
|
||||
},
|
||||
start: function(testName) {
|
||||
if (!this.log) return;
|
||||
this.testName = testName;
|
||||
this.lastLogLine = document.createElement('tr');
|
||||
this.statusCell = document.createElement('td');
|
||||
this.nameCell = document.createElement('td');
|
||||
this.nameCell.className = "nameCell";
|
||||
this.nameCell.appendChild(document.createTextNode(testName));
|
||||
this.messageCell = document.createElement('td');
|
||||
this.lastLogLine.appendChild(this.statusCell);
|
||||
this.lastLogLine.appendChild(this.nameCell);
|
||||
this.lastLogLine.appendChild(this.messageCell);
|
||||
this.loglines.appendChild(this.lastLogLine);
|
||||
},
|
||||
finish: function(status, summary) {
|
||||
if (!this.log) return;
|
||||
this.lastLogLine.className = status;
|
||||
this.statusCell.innerHTML = status;
|
||||
this.messageCell.innerHTML = this._toHTML(summary);
|
||||
this.addLinksToResults();
|
||||
},
|
||||
message: function(message) {
|
||||
if (!this.log) return;
|
||||
this.messageCell.innerHTML = this._toHTML(message);
|
||||
},
|
||||
summary: function(summary) {
|
||||
if (!this.log) return;
|
||||
this.logsummary.innerHTML = this._toHTML(summary);
|
||||
},
|
||||
_createLogTable: function() {
|
||||
this.log.innerHTML =
|
||||
'<div id="logsummary"></div>' +
|
||||
'<table id="logtable">' +
|
||||
'<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
|
||||
'<tbody id="loglines"></tbody>' +
|
||||
'</table>';
|
||||
this.logsummary = $('logsummary');
|
||||
this.loglines = $('loglines');
|
||||
},
|
||||
_toHTML: function(txt) {
|
||||
return txt.escapeHTML().replace(/\n/g,"<br/>");
|
||||
},
|
||||
addLinksToResults: function(){
|
||||
$$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
|
||||
td.title = "Run only this test";
|
||||
Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
|
||||
});
|
||||
$$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
|
||||
td.title = "Run all tests";
|
||||
Event.observe(td, 'click', function(){ window.location.search = "";});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Test.Unit.Runner = Class.create();
|
||||
Test.Unit.Runner.prototype = {
|
||||
initialize: function(testcases) {
|
||||
this.options = Object.extend({
|
||||
testLog: 'testlog'
|
||||
}, arguments[1] || {});
|
||||
this.options.resultsURL = this.parseResultsURLQueryParameter();
|
||||
this.options.tests = this.parseTestsQueryParameter();
|
||||
if (this.options.testLog) {
|
||||
this.options.testLog = $(this.options.testLog) || null;
|
||||
}
|
||||
if(this.options.tests) {
|
||||
this.tests = [];
|
||||
for(var i = 0; i < this.options.tests.length; i++) {
|
||||
if(/^test/.test(this.options.tests[i])) {
|
||||
this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.options.test) {
|
||||
this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
|
||||
} else {
|
||||
this.tests = [];
|
||||
for(var testcase in testcases) {
|
||||
if(/^test/.test(testcase)) {
|
||||
this.tests.push(
|
||||
new Test.Unit.Testcase(
|
||||
this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,
|
||||
testcases[testcase], testcases["setup"], testcases["teardown"]
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.currentTest = 0;
|
||||
this.logger = new Test.Unit.Logger(this.options.testLog);
|
||||
setTimeout(this.runTests.bind(this), 1000);
|
||||
},
|
||||
parseResultsURLQueryParameter: function() {
|
||||
return window.location.search.parseQuery()["resultsURL"];
|
||||
},
|
||||
parseTestsQueryParameter: function(){
|
||||
if (window.location.search.parseQuery()["tests"]){
|
||||
return window.location.search.parseQuery()["tests"].split(',');
|
||||
};
|
||||
},
|
||||
// Returns:
|
||||
// "ERROR" if there was an error,
|
||||
// "FAILURE" if there was a failure, or
|
||||
// "SUCCESS" if there was neither
|
||||
getResult: function() {
|
||||
var hasFailure = false;
|
||||
for(var i=0;i<this.tests.length;i++) {
|
||||
if (this.tests[i].errors > 0) {
|
||||
return "ERROR";
|
||||
}
|
||||
if (this.tests[i].failures > 0) {
|
||||
hasFailure = true;
|
||||
}
|
||||
}
|
||||
if (hasFailure) {
|
||||
return "FAILURE";
|
||||
} else {
|
||||
return "SUCCESS";
|
||||
}
|
||||
},
|
||||
postResults: function() {
|
||||
if (this.options.resultsURL) {
|
||||
new Ajax.Request(this.options.resultsURL,
|
||||
{ method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
|
||||
}
|
||||
},
|
||||
runTests: function() {
|
||||
var test = this.tests[this.currentTest];
|
||||
if (!test) {
|
||||
// finished!
|
||||
this.postResults();
|
||||
this.logger.summary(this.summary());
|
||||
return;
|
||||
}
|
||||
if(!test.isWaiting) {
|
||||
this.logger.start(test.name);
|
||||
}
|
||||
test.run();
|
||||
if(test.isWaiting) {
|
||||
this.logger.message("Waiting for " + test.timeToWait + "ms");
|
||||
setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
|
||||
} else {
|
||||
this.logger.finish(test.status(), test.summary());
|
||||
this.currentTest++;
|
||||
// tail recursive, hopefully the browser will skip the stackframe
|
||||
this.runTests();
|
||||
}
|
||||
},
|
||||
summary: function() {
|
||||
var assertions = 0;
|
||||
var failures = 0;
|
||||
var errors = 0;
|
||||
var messages = [];
|
||||
for(var i=0;i<this.tests.length;i++) {
|
||||
assertions += this.tests[i].assertions;
|
||||
failures += this.tests[i].failures;
|
||||
errors += this.tests[i].errors;
|
||||
}
|
||||
return (
|
||||
(this.options.context ? this.options.context + ': ': '') +
|
||||
this.tests.length + " tests, " +
|
||||
assertions + " assertions, " +
|
||||
failures + " failures, " +
|
||||
errors + " errors");
|
||||
}
|
||||
};
|
||||
|
||||
Test.Unit.Assertions = Class.create();
|
||||
Test.Unit.Assertions.prototype = {
|
||||
initialize: function() {
|
||||
this.assertions = 0;
|
||||
this.failures = 0;
|
||||
this.errors = 0;
|
||||
this.messages = [];
|
||||
},
|
||||
summary: function() {
|
||||
return (
|
||||
this.assertions + " assertions, " +
|
||||
this.failures + " failures, " +
|
||||
this.errors + " errors" + "\n" +
|
||||
this.messages.join("\n"));
|
||||
},
|
||||
pass: function() {
|
||||
this.assertions++;
|
||||
},
|
||||
fail: function(message) {
|
||||
this.failures++;
|
||||
this.messages.push("Failure: " + message);
|
||||
},
|
||||
info: function(message) {
|
||||
this.messages.push("Info: " + message);
|
||||
},
|
||||
error: function(error) {
|
||||
this.errors++;
|
||||
this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
|
||||
},
|
||||
status: function() {
|
||||
if (this.failures > 0) return 'failed';
|
||||
if (this.errors > 0) return 'error';
|
||||
return 'passed';
|
||||
},
|
||||
assert: function(expression) {
|
||||
var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
|
||||
try { expression ? this.pass() :
|
||||
this.fail(message); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertEqual: function(expected, actual) {
|
||||
var message = arguments[2] || "assertEqual";
|
||||
try { (expected == actual) ? this.pass() :
|
||||
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
||||
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertInspect: function(expected, actual) {
|
||||
var message = arguments[2] || "assertInspect";
|
||||
try { (expected == actual.inspect()) ? this.pass() :
|
||||
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
||||
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertEnumEqual: function(expected, actual) {
|
||||
var message = arguments[2] || "assertEnumEqual";
|
||||
try { $A(expected).length == $A(actual).length &&
|
||||
expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
|
||||
this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
|
||||
', actual ' + Test.Unit.inspect(actual)); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertNotEqual: function(expected, actual) {
|
||||
var message = arguments[2] || "assertNotEqual";
|
||||
try { (expected != actual) ? this.pass() :
|
||||
this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertIdentical: function(expected, actual) {
|
||||
var message = arguments[2] || "assertIdentical";
|
||||
try { (expected === actual) ? this.pass() :
|
||||
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
||||
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertNotIdentical: function(expected, actual) {
|
||||
var message = arguments[2] || "assertNotIdentical";
|
||||
try { !(expected === actual) ? this.pass() :
|
||||
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
||||
'", actual "' + Test.Unit.inspect(actual) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertNull: function(obj) {
|
||||
var message = arguments[1] || 'assertNull';
|
||||
try { (obj==null) ? this.pass() :
|
||||
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertMatch: function(expected, actual) {
|
||||
var message = arguments[2] || 'assertMatch';
|
||||
var regex = new RegExp(expected);
|
||||
try { (regex.exec(actual)) ? this.pass() :
|
||||
this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertHidden: function(element) {
|
||||
var message = arguments[1] || 'assertHidden';
|
||||
this.assertEqual("none", element.style.display, message);
|
||||
},
|
||||
assertNotNull: function(object) {
|
||||
var message = arguments[1] || 'assertNotNull';
|
||||
this.assert(object != null, message);
|
||||
},
|
||||
assertType: function(expected, actual) {
|
||||
var message = arguments[2] || 'assertType';
|
||||
try {
|
||||
(actual.constructor == expected) ? this.pass() :
|
||||
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
||||
'", actual "' + (actual.constructor) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertNotOfType: function(expected, actual) {
|
||||
var message = arguments[2] || 'assertNotOfType';
|
||||
try {
|
||||
(actual.constructor != expected) ? this.pass() :
|
||||
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
|
||||
'", actual "' + (actual.constructor) + '"'); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertInstanceOf: function(expected, actual) {
|
||||
var message = arguments[2] || 'assertInstanceOf';
|
||||
try {
|
||||
(actual instanceof expected) ? this.pass() :
|
||||
this.fail(message + ": object was not an instance of the expected type"); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertNotInstanceOf: function(expected, actual) {
|
||||
var message = arguments[2] || 'assertNotInstanceOf';
|
||||
try {
|
||||
!(actual instanceof expected) ? this.pass() :
|
||||
this.fail(message + ": object was an instance of the not expected type"); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertRespondsTo: function(method, obj) {
|
||||
var message = arguments[2] || 'assertRespondsTo';
|
||||
try {
|
||||
(obj[method] && typeof obj[method] == 'function') ? this.pass() :
|
||||
this.fail(message + ": object doesn't respond to [" + method + "]"); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertReturnsTrue: function(method, obj) {
|
||||
var message = arguments[2] || 'assertReturnsTrue';
|
||||
try {
|
||||
var m = obj[method];
|
||||
if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
|
||||
m() ? this.pass() :
|
||||
this.fail(message + ": method returned false"); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertReturnsFalse: function(method, obj) {
|
||||
var message = arguments[2] || 'assertReturnsFalse';
|
||||
try {
|
||||
var m = obj[method];
|
||||
if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
|
||||
!m() ? this.pass() :
|
||||
this.fail(message + ": method returned true"); }
|
||||
catch(e) { this.error(e); }
|
||||
},
|
||||
assertRaise: function(exceptionName, method) {
|
||||
var message = arguments[2] || 'assertRaise';
|
||||
try {
|
||||
method();
|
||||
this.fail(message + ": exception expected but none was raised"); }
|
||||
catch(e) {
|
||||
((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e);
|
||||
}
|
||||
},
|
||||
assertElementsMatch: function() {
|
||||
var expressions = $A(arguments), elements = $A(expressions.shift());
|
||||
if (elements.length != expressions.length) {
|
||||
this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
|
||||
return false;
|
||||
}
|
||||
elements.zip(expressions).all(function(pair, index) {
|
||||
var element = $(pair.first()), expression = pair.last();
|
||||
if (element.match(expression)) return true;
|
||||
this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
|
||||
}.bind(this)) && this.pass();
|
||||
},
|
||||
assertElementMatches: function(element, expression) {
|
||||
this.assertElementsMatch([element], expression);
|
||||
},
|
||||
benchmark: function(operation, iterations) {
|
||||
var startAt = new Date();
|
||||
(iterations || 1).times(operation);
|
||||
var timeTaken = ((new Date())-startAt);
|
||||
this.info((arguments[2] || 'Operation') + ' finished ' +
|
||||
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
|
||||
return timeTaken;
|
||||
},
|
||||
_isVisible: function(element) {
|
||||
element = $(element);
|
||||
if(!element.parentNode) return true;
|
||||
this.assertNotNull(element);
|
||||
if(element.style && Element.getStyle(element, 'display') == 'none')
|
||||
return false;
|
||||
|
||||
return this._isVisible(element.parentNode);
|
||||
},
|
||||
assertNotVisible: function(element) {
|
||||
this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
|
||||
},
|
||||
assertVisible: function(element) {
|
||||
this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
|
||||
},
|
||||
benchmark: function(operation, iterations) {
|
||||
var startAt = new Date();
|
||||
(iterations || 1).times(operation);
|
||||
var timeTaken = ((new Date())-startAt);
|
||||
this.info((arguments[2] || 'Operation') + ' finished ' +
|
||||
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
|
||||
return timeTaken;
|
||||
}
|
||||
};
|
||||
|
||||
Test.Unit.Testcase = Class.create();
|
||||
Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
|
||||
initialize: function(name, test, setup, teardown) {
|
||||
Test.Unit.Assertions.prototype.initialize.bind(this)();
|
||||
this.name = name;
|
||||
|
||||
if(typeof test == 'string') {
|
||||
test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
|
||||
test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
|
||||
this.test = function() {
|
||||
eval('with(this){'+test+'}');
|
||||
}
|
||||
} else {
|
||||
this.test = test || function() {};
|
||||
}
|
||||
|
||||
this.setup = setup || function() {};
|
||||
this.teardown = teardown || function() {};
|
||||
this.isWaiting = false;
|
||||
this.timeToWait = 1000;
|
||||
},
|
||||
wait: function(time, nextPart) {
|
||||
this.isWaiting = true;
|
||||
this.test = nextPart;
|
||||
this.timeToWait = time;
|
||||
},
|
||||
run: function() {
|
||||
try {
|
||||
try {
|
||||
if (!this.isWaiting) this.setup.bind(this)();
|
||||
this.isWaiting = false;
|
||||
this.test.bind(this)();
|
||||
} finally {
|
||||
if(!this.isWaiting) {
|
||||
this.teardown.bind(this)();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(e) { this.error(e); }
|
||||
}
|
||||
});
|
||||
|
||||
// *EXPERIMENTAL* BDD-style testing to please non-technical folk
|
||||
// This draws many ideas from RSpec http://rspec.rubyforge.org/
|
||||
|
||||
Test.setupBDDExtensionMethods = function(){
|
||||
var METHODMAP = {
|
||||
shouldEqual: 'assertEqual',
|
||||
shouldNotEqual: 'assertNotEqual',
|
||||
shouldEqualEnum: 'assertEnumEqual',
|
||||
shouldBeA: 'assertType',
|
||||
shouldNotBeA: 'assertNotOfType',
|
||||
shouldBeAn: 'assertType',
|
||||
shouldNotBeAn: 'assertNotOfType',
|
||||
shouldBeNull: 'assertNull',
|
||||
shouldNotBeNull: 'assertNotNull',
|
||||
|
||||
shouldBe: 'assertReturnsTrue',
|
||||
shouldNotBe: 'assertReturnsFalse',
|
||||
shouldRespondTo: 'assertRespondsTo'
|
||||
};
|
||||
var makeAssertion = function(assertion, args, object) {
|
||||
this[assertion].apply(this,(args || []).concat([object]));
|
||||
};
|
||||
|
||||
Test.BDDMethods = {};
|
||||
$H(METHODMAP).each(function(pair) {
|
||||
Test.BDDMethods[pair.key] = function() {
|
||||
var args = $A(arguments);
|
||||
var scope = args.shift();
|
||||
makeAssertion.apply(scope, [pair.value, args, this]); };
|
||||
});
|
||||
|
||||
[Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each(
|
||||
function(p){ Object.extend(p, Test.BDDMethods) }
|
||||
);
|
||||
};
|
||||
|
||||
Test.context = function(name, spec, log){
|
||||
Test.setupBDDExtensionMethods();
|
||||
|
||||
var compiledSpec = {};
|
||||
var titles = {};
|
||||
for(specName in spec) {
|
||||
switch(specName){
|
||||
case "setup":
|
||||
case "teardown":
|
||||
compiledSpec[specName] = spec[specName];
|
||||
break;
|
||||
default:
|
||||
var testName = 'test'+specName.gsub(/\s+/,'-').camelize();
|
||||
var body = spec[specName].toString().split('\n').slice(1);
|
||||
if(/^\{/.test(body[0])) body = body.slice(1);
|
||||
body.pop();
|
||||
body = body.map(function(statement){
|
||||
return statement.strip()
|
||||
});
|
||||
compiledSpec[testName] = body.join('\n');
|
||||
titles[testName] = specName;
|
||||
}
|
||||
}
|
||||
new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
/* SWFObject v2.0 rc4 <http://code.google.com/p/swfobject/>
|
||||
Copyright (c) 2007 Geoff Stearns, Michael Williams, and Bobby van der Sluis
|
||||
This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
|
||||
*/
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Cookie Plug-in
|
||||
|
||||
This plug in automatically gets all the cookies for this site and adds them to the post_params.
|
||||
Cookies are loaded only on initialization. The refreshCookies function can be called to update the post_params.
|
||||
The cookies will override any other post params with the same name.
|
||||
*/
|
||||
|
||||
var SWFUpload;
|
||||
if (typeof(SWFUpload) === "function") {
|
||||
SWFUpload.prototype.initSettings = function (oldInitSettings) {
|
||||
return function () {
|
||||
if (typeof(oldInitSettings) === "function") {
|
||||
oldInitSettings.call(this);
|
||||
}
|
||||
|
||||
this.refreshCookies(false); // The false parameter must be sent since SWFUpload has not initialzed at this point
|
||||
};
|
||||
}(SWFUpload.prototype.initSettings);
|
||||
|
||||
// refreshes the post_params and updates SWFUpload. The sendToFlash parameters is optional and defaults to True
|
||||
SWFUpload.prototype.refreshCookies = function (sendToFlash) {
|
||||
if (sendToFlash === undefined) {
|
||||
sendToFlash = true;
|
||||
}
|
||||
sendToFlash = !!sendToFlash;
|
||||
|
||||
// Get the post_params object
|
||||
var postParams = this.settings.post_params;
|
||||
|
||||
// Get the cookies
|
||||
var i, cookieArray = document.cookie.split(';'), caLength = cookieArray.length, c, eqIndex, name, value;
|
||||
for (i = 0; i < caLength; i++) {
|
||||
c = cookieArray[i];
|
||||
|
||||
// Left Trim spaces
|
||||
while (c.charAt(0) === " ") {
|
||||
c = c.substring(1, c.length);
|
||||
}
|
||||
eqIndex = c.indexOf("=");
|
||||
if (eqIndex > 0) {
|
||||
name = c.substring(0, eqIndex);
|
||||
value = c.substring(eqIndex + 1);
|
||||
postParams[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (sendToFlash) {
|
||||
this.setPostParams(postParams);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Queue Plug-in
|
||||
|
||||
Features:
|
||||
*Adds a cancelQueue() method for cancelling the entire queue.
|
||||
*All queued files are uploaded when startUpload() is called.
|
||||
*If false is returned from uploadComplete then the queue upload is stopped.
|
||||
If false is not returned (strict comparison) then the queue upload is continued.
|
||||
*Adds a QueueComplete event that is fired when all the queued files have finished uploading.
|
||||
Set the event handler with the queue_complete_handler setting.
|
||||
|
||||
*/
|
||||
|
||||
var SWFUpload;
|
||||
if (typeof(SWFUpload) === "function") {
|
||||
SWFUpload.queue = {};
|
||||
|
||||
SWFUpload.prototype.initSettings = (function (oldInitSettings) {
|
||||
return function () {
|
||||
if (typeof(oldInitSettings) === "function") {
|
||||
oldInitSettings.call(this);
|
||||
}
|
||||
|
||||
this.queueSettings = {};
|
||||
|
||||
this.queueSettings.queue_cancelled_flag = false;
|
||||
this.queueSettings.queue_upload_count = 0;
|
||||
|
||||
this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
|
||||
this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler;
|
||||
this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
|
||||
this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler;
|
||||
|
||||
this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
|
||||
};
|
||||
})(SWFUpload.prototype.initSettings);
|
||||
|
||||
SWFUpload.prototype.startUpload = function (fileID) {
|
||||
this.queueSettings.queue_cancelled_flag = false;
|
||||
this.callFlash("StartUpload", [fileID]);
|
||||
};
|
||||
|
||||
SWFUpload.prototype.cancelQueue = function () {
|
||||
this.queueSettings.queue_cancelled_flag = true;
|
||||
this.stopUpload();
|
||||
|
||||
var stats = this.getStats();
|
||||
while (stats.files_queued > 0) {
|
||||
this.cancelUpload();
|
||||
stats = this.getStats();
|
||||
}
|
||||
};
|
||||
|
||||
SWFUpload.queue.uploadStartHandler = function (file) {
|
||||
var returnValue;
|
||||
if (typeof(this.queueSettings.user_upload_start_handler) === "function") {
|
||||
returnValue = this.queueSettings.user_upload_start_handler.call(this, file);
|
||||
}
|
||||
|
||||
// To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value.
|
||||
returnValue = (returnValue === false) ? false : true;
|
||||
|
||||
this.queueSettings.queue_cancelled_flag = !returnValue;
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
SWFUpload.queue.uploadCompleteHandler = function (file) {
|
||||
var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler;
|
||||
var continueUpload;
|
||||
|
||||
if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
|
||||
this.queueSettings.queue_upload_count++;
|
||||
}
|
||||
|
||||
if (typeof(user_upload_complete_handler) === "function") {
|
||||
continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
|
||||
} else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
|
||||
// If the file was stopped and re-queued don't restart the upload
|
||||
continueUpload = false;
|
||||
} else {
|
||||
continueUpload = true;
|
||||
}
|
||||
|
||||
if (continueUpload) {
|
||||
var stats = this.getStats();
|
||||
if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) {
|
||||
this.startUpload();
|
||||
} else if (this.queueSettings.queue_cancelled_flag === false) {
|
||||
this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]);
|
||||
this.queueSettings.queue_upload_count = 0;
|
||||
} else {
|
||||
this.queueSettings.queue_cancelled_flag = false;
|
||||
this.queueSettings.queue_upload_count = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
SWFUpload.SWFObject Plugin
|
||||
|
||||
Summary:
|
||||
This plugin uses SWFObject to embed SWFUpload dynamically in the page. SWFObject provides accurate Flash Player detection and DOM Ready loading.
|
||||
This plugin replaces the Graceful Degradation plugin.
|
||||
|
||||
Features:
|
||||
* swfupload_load_failed_hander event
|
||||
* swfupload_pre_load_handler event
|
||||
* minimum_flash_version setting (default: "9.0.28")
|
||||
* SWFUpload.onload event for early loading
|
||||
|
||||
Usage:
|
||||
Provide handlers and settings as needed. When using the SWFUpload.SWFObject plugin you should initialize SWFUploading
|
||||
in SWFUpload.onload rather than in window.onload. When initialized this way SWFUpload can load earlier preventing the UI flicker
|
||||
that was seen using the Graceful Degradation plugin.
|
||||
|
||||
<script type="text/javascript">
|
||||
var swfu;
|
||||
SWFUpload.onload = function () {
|
||||
swfu = new SWFUpload({
|
||||
minimum_flash_version: "9.0.28",
|
||||
swfupload_pre_load_handler: swfuploadPreLoad,
|
||||
swfupload_load_failed_handler: swfuploadLoadFailed
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
Notes:
|
||||
You must provide set minimum_flash_version setting to "8" if you are using SWFUpload for Flash Player 8.
|
||||
The swfuploadLoadFailed event is only fired if the minimum version of Flash Player is not met. Other issues such as missing SWF files, browser bugs
|
||||
or corrupt Flash Player installations will not trigger this event.
|
||||
The swfuploadPreLoad event is fired as soon as the minimum version of Flash Player is found. It does not wait for SWFUpload to load and can
|
||||
be used to prepare the SWFUploadUI and hide alternate content.
|
||||
swfobject's onDomReady event is cross-browser safe but will default to the window.onload event when DOMReady is not supported by the browser.
|
||||
Early DOM Loading is supported in major modern browsers but cannot be guaranteed for every browser ever made.
|
||||
*/
|
||||
|
||||
|
||||
/* SWFObject v2.1 <http://code.google.com/p/swfobject/>
|
||||
Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
|
||||
This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
|
||||
*/
|
||||
var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("<script id=__ie_ondomload defer=true src=//:><\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r<q;r++){o[r]()}}function f(q){if(e){q()}else{o[o.length]=q}}function R(r){if(typeof j.addEventListener!=b){j.addEventListener("load",r,false)}else{if(typeof K.addEventListener!=b){K.addEventListener("load",r,false)}else{if(typeof j.attachEvent!=b){I(j,"onload",r)}else{if(typeof j.onload=="function"){var q=j.onload;j.onload=function(){q();r()}}else{j.onload=r}}}}}function H(){var t=N.length;for(var q=0;q<t;q++){var u=N[q].id;if(h.pv[0]>0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u<v;u++){if(y[u].nodeName=="DATA"){w.setAttribute("src",y[u].nodeValue)}else{w.setAttribute(y[u].nodeName,y[u].nodeValue)}}}var x=q.childNodes;if(x){var z=x.length;for(var r=0;r<z;r++){if(x[r].nodeType==1&&x[r].nodeName=="PARAM"){w.setAttribute(x[r].getAttribute("name"),x[r].getAttribute("value"))}}}t.parentNode.replaceChild(w,t)}}function k(w){A=true;var u=C(w.id);if(u){if(w.altContentId){var y=C(w.altContentId);if(y){M=y;l=w.altContentId}}else{M=G(u)}if(!(/%$/.test(w.width))&&parseInt(w.width,10)<310){w.width="310"}if(!(/%$/.test(w.height))&&parseInt(w.height,10)<137){w.height="137"}K.title=K.title.slice(0,47)+" - Flash Player Installation";var z=h.ie&&h.win?"ActiveX":"PlugIn",q=K.title,r="MMredirectURL="+j.location+"&MMplayerType="+z+"&MMdoctitle="+q,x=w.id;if(h.ie&&h.win&&u.readyState!=4){var t=a("div");x+="SWFObjectNew";t.setAttribute("id",x);u.parentNode.insertBefore(t,u);u.style.display="none";var v=function(){u.parentNode.removeChild(u)};I(j,"onload",v)}U({data:w.expressInstall,id:m,width:w.width,height:w.height},{flashvars:r},x)}}function O(t){if(h.ie&&h.win&&t.readyState!=4){var r=a("div");t.parentNode.insertBefore(r,t);r.parentNode.replaceChild(G(t),r);t.style.display="none";var q=function(){t.parentNode.removeChild(t)};I(j,"onload",q)}else{t.parentNode.replaceChild(G(t),t)}}function G(v){var u=a("div");if(h.win&&h.ie){u.innerHTML=v.innerHTML}else{var r=v.getElementsByTagName(Q)[0];if(r){var w=r.childNodes;if(w){var q=w.length;for(var t=0;t<q;t++){if(!(w[t].nodeType==1&&w[t].nodeName=="PARAM")&&!(w[t].nodeType==8)){u.appendChild(w[t].cloneNode(true))}}}}}return u}function U(AG,AE,t){var q,v=C(t);if(v){if(typeof AG.id==b){AG.id=t}if(h.ie&&h.win){var AF="";for(var AB in AG){if(AG[AB]!=Object.prototype[AB]){if(AB.toLowerCase()=="data"){AE.movie=AG[AB]}else{if(AB.toLowerCase()=="styleclass"){AF+=' class="'+AG[AB]+'"'}else{if(AB.toLowerCase()!="classid"){AF+=" "+AB+'="'+AG[AB]+'"'}}}}}var AD="";for(var AA in AE){Line truncated
|
||||
|
||||
|
||||
|
||||
var SWFUpload;
|
||||
if (typeof(SWFUpload) === "function") {
|
||||
SWFUpload.onload = function () {};
|
||||
|
||||
swfobject.addDomLoadEvent(function () {
|
||||
if (typeof(SWFUpload.onload) === "function") {
|
||||
SWFUpload.onload.call(window);
|
||||
}
|
||||
});
|
||||
|
||||
SWFUpload.prototype.initSettings = (function (oldInitSettings) {
|
||||
return function () {
|
||||
if (typeof(oldInitSettings) === "function") {
|
||||
oldInitSettings.call(this);
|
||||
}
|
||||
|
||||
this.ensureDefault = function (settingName, defaultValue) {
|
||||
this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
|
||||
};
|
||||
|
||||
this.ensureDefault("minimum_flash_version", "9.0.28");
|
||||
this.ensureDefault("swfupload_pre_load_handler", null);
|
||||
this.ensureDefault("swfupload_load_failed_handler", null);
|
||||
|
||||
delete this.ensureDefault;
|
||||
|
||||
};
|
||||
})(SWFUpload.prototype.initSettings);
|
||||
|
||||
|
||||
SWFUpload.prototype.loadFlash = function (oldLoadFlash) {
|
||||
return function () {
|
||||
var hasFlash = swfobject.hasFlashPlayerVersion(this.settings.minimum_flash_version);
|
||||
|
||||
if (hasFlash) {
|
||||
this.queueEvent("swfupload_pre_load_handler");
|
||||
if (typeof(oldLoadFlash) === "function") {
|
||||
oldLoadFlash.call(this);
|
||||
}
|
||||
} else {
|
||||
this.queueEvent("swfupload_load_failed_handler");
|
||||
}
|
||||
};
|
||||
|
||||
}(SWFUpload.prototype.loadFlash);
|
||||
|
||||
SWFUpload.prototype.displayDebugInfo = function (oldDisplayDebugInfo) {
|
||||
return function () {
|
||||
if (typeof(oldDisplayDebugInfo) === "function") {
|
||||
oldDisplayDebugInfo.call(this);
|
||||
}
|
||||
|
||||
this.debug(
|
||||
[
|
||||
"SWFUpload.SWFObject Plugin settings:", "\n",
|
||||
"\t", "minimum_flash_version: ", this.settings.minimum_flash_version, "\n",
|
||||
"\t", "swfupload_pre_load_handler assigned: ", (typeof(this.settings.swfupload_pre_load_handler) === "function").toString(), "\n",
|
||||
"\t", "swfupload_load_failed_handler assigned: ", (typeof(this.settings.swfupload_load_failed_handler) === "function").toString(), "\n",
|
||||
].join("")
|
||||
);
|
||||
};
|
||||
}(SWFUpload.prototype.displayDebugInfo);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
|
||||
*
|
||||
* mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/
|
||||
*
|
||||
* SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
*/
|
||||
+980
@@ -0,0 +1,980 @@
|
||||
/**
|
||||
* SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
|
||||
*
|
||||
* mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/
|
||||
*
|
||||
* SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz←n and Mammon Media and is released under the MIT License:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* ******************* */
|
||||
/* Constructor & Init */
|
||||
/* ******************* */
|
||||
var SWFUpload;
|
||||
|
||||
if (SWFUpload == undefined) {
|
||||
SWFUpload = function (settings) {
|
||||
this.initSWFUpload(settings);
|
||||
};
|
||||
}
|
||||
|
||||
SWFUpload.prototype.initSWFUpload = function (settings) {
|
||||
try {
|
||||
this.customSettings = {}; // A container where developers can place their own settings associated with this instance.
|
||||
this.settings = settings;
|
||||
this.eventQueue = [];
|
||||
this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
|
||||
this.movieElement = null;
|
||||
|
||||
|
||||
// Setup global control tracking
|
||||
SWFUpload.instances[this.movieName] = this;
|
||||
|
||||
// Load the settings. Load the Flash movie.
|
||||
this.initSettings();
|
||||
this.loadFlash();
|
||||
this.displayDebugInfo();
|
||||
} catch (ex) {
|
||||
delete SWFUpload.instances[this.movieName];
|
||||
throw ex;
|
||||
}
|
||||
};
|
||||
|
||||
/* *************** */
|
||||
/* Static Members */
|
||||
/* *************** */
|
||||
SWFUpload.instances = {};
|
||||
SWFUpload.movieCount = 0;
|
||||
SWFUpload.version = "2.2.0 2009-03-25";
|
||||
SWFUpload.QUEUE_ERROR = {
|
||||
QUEUE_LIMIT_EXCEEDED : -100,
|
||||
FILE_EXCEEDS_SIZE_LIMIT : -110,
|
||||
ZERO_BYTE_FILE : -120,
|
||||
INVALID_FILETYPE : -130
|
||||
};
|
||||
SWFUpload.UPLOAD_ERROR = {
|
||||
HTTP_ERROR : -200,
|
||||
MISSING_UPLOAD_URL : -210,
|
||||
IO_ERROR : -220,
|
||||
SECURITY_ERROR : -230,
|
||||
UPLOAD_LIMIT_EXCEEDED : -240,
|
||||
UPLOAD_FAILED : -250,
|
||||
SPECIFIED_FILE_ID_NOT_FOUND : -260,
|
||||
FILE_VALIDATION_FAILED : -270,
|
||||
FILE_CANCELLED : -280,
|
||||
UPLOAD_STOPPED : -290
|
||||
};
|
||||
SWFUpload.FILE_STATUS = {
|
||||
QUEUED : -1,
|
||||
IN_PROGRESS : -2,
|
||||
ERROR : -3,
|
||||
COMPLETE : -4,
|
||||
CANCELLED : -5
|
||||
};
|
||||
SWFUpload.BUTTON_ACTION = {
|
||||
SELECT_FILE : -100,
|
||||
SELECT_FILES : -110,
|
||||
START_UPLOAD : -120
|
||||
};
|
||||
SWFUpload.CURSOR = {
|
||||
ARROW : -1,
|
||||
HAND : -2
|
||||
};
|
||||
SWFUpload.WINDOW_MODE = {
|
||||
WINDOW : "window",
|
||||
TRANSPARENT : "transparent",
|
||||
OPAQUE : "opaque"
|
||||
};
|
||||
|
||||
// Private: takes a URL, determines if it is relative and converts to an absolute URL
|
||||
// using the current site. Only processes the URL if it can, otherwise returns the URL untouched
|
||||
SWFUpload.completeURL = function(url) {
|
||||
if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
|
||||
|
||||
var indexSlash = window.location.pathname.lastIndexOf("/");
|
||||
if (indexSlash <= 0) {
|
||||
path = "/";
|
||||
} else {
|
||||
path = window.location.pathname.substr(0, indexSlash) + "/";
|
||||
}
|
||||
|
||||
return /*currentURL +*/ path + url;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* ******************** */
|
||||
/* Instance Members */
|
||||
/* ******************** */
|
||||
|
||||
// Private: initSettings ensures that all the
|
||||
// settings are set, getting a default value if one was not assigned.
|
||||
SWFUpload.prototype.initSettings = function () {
|
||||
this.ensureDefault = function (settingName, defaultValue) {
|
||||
this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
|
||||
};
|
||||
|
||||
// Upload backend settings
|
||||
this.ensureDefault("upload_url", "");
|
||||
this.ensureDefault("preserve_relative_urls", false);
|
||||
this.ensureDefault("file_post_name", "Filedata");
|
||||
this.ensureDefault("post_params", {});
|
||||
this.ensureDefault("use_query_string", false);
|
||||
this.ensureDefault("requeue_on_error", false);
|
||||
this.ensureDefault("http_success", []);
|
||||
this.ensureDefault("assume_success_timeout", 0);
|
||||
|
||||
// File Settings
|
||||
this.ensureDefault("file_types", "*.*");
|
||||
this.ensureDefault("file_types_description", "All Files");
|
||||
this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited"
|
||||
this.ensureDefault("file_upload_limit", 0);
|
||||
this.ensureDefault("file_queue_limit", 0);
|
||||
|
||||
// Flash Settings
|
||||
this.ensureDefault("flash_url", "swfupload.swf");
|
||||
this.ensureDefault("prevent_swf_caching", true);
|
||||
|
||||
// Button Settings
|
||||
this.ensureDefault("button_image_url", "");
|
||||
this.ensureDefault("button_width", 1);
|
||||
this.ensureDefault("button_height", 1);
|
||||
this.ensureDefault("button_text", "");
|
||||
this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
|
||||
this.ensureDefault("button_text_top_padding", 0);
|
||||
this.ensureDefault("button_text_left_padding", 0);
|
||||
this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
|
||||
this.ensureDefault("button_disabled", false);
|
||||
this.ensureDefault("button_placeholder_id", "");
|
||||
this.ensureDefault("button_placeholder", null);
|
||||
this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
|
||||
this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
|
||||
|
||||
// Debug Settings
|
||||
this.ensureDefault("debug", false);
|
||||
this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API
|
||||
|
||||
// Event Handlers
|
||||
this.settings.return_upload_start_handler = this.returnUploadStart;
|
||||
this.ensureDefault("swfupload_loaded_handler", null);
|
||||
this.ensureDefault("file_dialog_start_handler", null);
|
||||
this.ensureDefault("file_queued_handler", null);
|
||||
this.ensureDefault("file_queue_error_handler", null);
|
||||
this.ensureDefault("file_dialog_complete_handler", null);
|
||||
|
||||
this.ensureDefault("upload_start_handler", null);
|
||||
this.ensureDefault("upload_progress_handler", null);
|
||||
this.ensureDefault("upload_error_handler", null);
|
||||
this.ensureDefault("upload_success_handler", null);
|
||||
this.ensureDefault("upload_complete_handler", null);
|
||||
|
||||
this.ensureDefault("debug_handler", this.debugMessage);
|
||||
|
||||
this.ensureDefault("custom_settings", {});
|
||||
|
||||
// Other settings
|
||||
this.customSettings = this.settings.custom_settings;
|
||||
|
||||
// Update the flash url if needed
|
||||
if (!!this.settings.prevent_swf_caching) {
|
||||
this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime();
|
||||
}
|
||||
|
||||
if (!this.settings.preserve_relative_urls) {
|
||||
//this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it
|
||||
this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
|
||||
this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
|
||||
}
|
||||
|
||||
delete this.ensureDefault;
|
||||
};
|
||||
|
||||
// Private: loadFlash replaces the button_placeholder element with the flash movie.
|
||||
SWFUpload.prototype.loadFlash = function () {
|
||||
var targetElement, tempParent;
|
||||
|
||||
// Make sure an element with the ID we are going to use doesn't already exist
|
||||
if (document.getElementById(this.movieName) !== null) {
|
||||
throw "ID " + this.movieName + " уже используется. Flash-объект не может быть добавлен";
|
||||
}
|
||||
|
||||
// Get the element where we will be placing the flash movie
|
||||
targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
|
||||
|
||||
if (targetElement == undefined) {
|
||||
throw "Невозможно найти метку(placeholder).";
|
||||
}
|
||||
|
||||
// Append the container and load the flash
|
||||
tempParent = document.createElement("div");
|
||||
tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
|
||||
targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
|
||||
|
||||
// Fix IE Flash/Form bug
|
||||
if (window[this.movieName] == undefined) {
|
||||
window[this.movieName] = this.getMovieElement();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
|
||||
SWFUpload.prototype.getFlashHTML = function () {
|
||||
// Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
|
||||
return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
|
||||
'<param name="wmode" value="', this.settings.button_window_mode, '" />',
|
||||
'<param name="movie" value="', this.settings.flash_url, '" />',
|
||||
'<param name="quality" value="high" />',
|
||||
'<param name="menu" value="false" />',
|
||||
'<param name="allowScriptAccess" value="always" />',
|
||||
'<param name="flashvars" value="' + this.getFlashVars() + '" />',
|
||||
'</object>'].join("");
|
||||
};
|
||||
|
||||
// Private: getFlashVars builds the parameter string that will be passed
|
||||
// to flash in the flashvars param.
|
||||
SWFUpload.prototype.getFlashVars = function () {
|
||||
// Build a string from the post param object
|
||||
var paramString = this.buildParamString();
|
||||
var httpSuccessString = this.settings.http_success.join(",");
|
||||
|
||||
// Build the parameter string
|
||||
return ["movieName=", encodeURIComponent(this.movieName),
|
||||
"&uploadURL=", encodeURIComponent(this.settings.upload_url),
|
||||
"&useQueryString=", encodeURIComponent(this.settings.use_query_string),
|
||||
"&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
|
||||
"&httpSuccess=", encodeURIComponent(httpSuccessString),
|
||||
"&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout),
|
||||
"&params=", encodeURIComponent(paramString),
|
||||
"&filePostName=", encodeURIComponent(this.settings.file_post_name),
|
||||
"&fileTypes=", encodeURIComponent(this.settings.file_types),
|
||||
"&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
|
||||
"&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
|
||||
"&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
|
||||
"&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
|
||||
"&debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
|
||||
"&buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
|
||||
"&buttonWidth=", encodeURIComponent(this.settings.button_width),
|
||||
"&buttonHeight=", encodeURIComponent(this.settings.button_height),
|
||||
"&buttonText=", encodeURIComponent(this.settings.button_text),
|
||||
"&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
|
||||
"&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
|
||||
"&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
|
||||
"&buttonAction=", encodeURIComponent(this.settings.button_action),
|
||||
"&buttonDisabled=", encodeURIComponent(this.settings.button_disabled),
|
||||
"&buttonCursor=", encodeURIComponent(this.settings.button_cursor)
|
||||
].join("");
|
||||
};
|
||||
|
||||
// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
|
||||
// The element is cached after the first lookup
|
||||
SWFUpload.prototype.getMovieElement = function () {
|
||||
if (this.movieElement == undefined) {
|
||||
this.movieElement = document.getElementById(this.movieName);
|
||||
}
|
||||
|
||||
if (this.movieElement === null) {
|
||||
throw "Flash элемент не найден";
|
||||
}
|
||||
|
||||
return this.movieElement;
|
||||
};
|
||||
|
||||
// Private: buildParamString takes the name/value pairs in the post_params setting object
|
||||
// and joins them up in to a string formatted "name=value&name=value"
|
||||
SWFUpload.prototype.buildParamString = function () {
|
||||
var postParams = this.settings.post_params;
|
||||
var paramStringPairs = [];
|
||||
|
||||
if (typeof(postParams) === "object") {
|
||||
for (var name in postParams) {
|
||||
if (postParams.hasOwnProperty(name)) {
|
||||
paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paramStringPairs.join("&");
|
||||
};
|
||||
|
||||
// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
|
||||
// all references to the SWF, and other objects so memory is properly freed.
|
||||
// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
|
||||
// Credits: Major improvements provided by steffen
|
||||
SWFUpload.prototype.destroy = function () {
|
||||
try {
|
||||
// Make sure Flash is done before we try to remove it
|
||||
this.cancelUpload(null, false);
|
||||
|
||||
|
||||
// Remove the SWFUpload DOM nodes
|
||||
var movieElement = null;
|
||||
movieElement = this.getMovieElement();
|
||||
|
||||
if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
|
||||
// Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
|
||||
for (var i in movieElement) {
|
||||
try {
|
||||
if (typeof(movieElement[i]) === "function") {
|
||||
movieElement[i] = null;
|
||||
}
|
||||
} catch (ex1) {}
|
||||
}
|
||||
|
||||
// Remove the Movie Element from the page
|
||||
try {
|
||||
movieElement.parentNode.removeChild(movieElement);
|
||||
} catch (ex) {}
|
||||
}
|
||||
|
||||
// Remove IE form fix reference
|
||||
window[this.movieName] = null;
|
||||
|
||||
// Destroy other references
|
||||
SWFUpload.instances[this.movieName] = null;
|
||||
delete SWFUpload.instances[this.movieName];
|
||||
|
||||
this.movieElement = null;
|
||||
this.settings = null;
|
||||
this.customSettings = null;
|
||||
this.eventQueue = null;
|
||||
this.movieName = null;
|
||||
|
||||
|
||||
return true;
|
||||
} catch (ex2) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Public: displayDebugInfo prints out settings and configuration
|
||||
// information about this SWFUpload instance.
|
||||
// This function (and any references to it) can be deleted when placing
|
||||
// SWFUpload in production.
|
||||
SWFUpload.prototype.displayDebugInfo = function () {
|
||||
this.debug(
|
||||
[
|
||||
"---SWFUpload Instance Info---\n",
|
||||
"Version: ", SWFUpload.version, "\n",
|
||||
"Movie Name: ", this.movieName, "\n",
|
||||
"Settings:\n",
|
||||
"\t", "upload_url: ", this.settings.upload_url, "\n",
|
||||
"\t", "flash_url: ", this.settings.flash_url, "\n",
|
||||
"\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n",
|
||||
"\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n",
|
||||
"\t", "http_success: ", this.settings.http_success.join(", "), "\n",
|
||||
"\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n",
|
||||
"\t", "file_post_name: ", this.settings.file_post_name, "\n",
|
||||
"\t", "post_params: ", this.settings.post_params.toString(), "\n",
|
||||
"\t", "file_types: ", this.settings.file_types, "\n",
|
||||
"\t", "file_types_description: ", this.settings.file_types_description, "\n",
|
||||
"\t", "file_size_limit: ", this.settings.file_size_limit, "\n",
|
||||
"\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n",
|
||||
"\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n",
|
||||
"\t", "debug: ", this.settings.debug.toString(), "\n",
|
||||
|
||||
"\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n",
|
||||
|
||||
"\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n",
|
||||
"\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
|
||||
"\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n",
|
||||
"\t", "button_width: ", this.settings.button_width.toString(), "\n",
|
||||
"\t", "button_height: ", this.settings.button_height.toString(), "\n",
|
||||
"\t", "button_text: ", this.settings.button_text.toString(), "\n",
|
||||
"\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n",
|
||||
"\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n",
|
||||
"\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
|
||||
"\t", "button_action: ", this.settings.button_action.toString(), "\n",
|
||||
"\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n",
|
||||
|
||||
"\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n",
|
||||
"Event Handlers:\n",
|
||||
"\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n",
|
||||
"\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n",
|
||||
"\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n",
|
||||
"\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n",
|
||||
"\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n",
|
||||
"\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n",
|
||||
"\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n",
|
||||
"\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n",
|
||||
"\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n",
|
||||
"\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n"
|
||||
].join("")
|
||||
);
|
||||
};
|
||||
|
||||
/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
|
||||
the maintain v2 API compatibility
|
||||
*/
|
||||
// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
|
||||
SWFUpload.prototype.addSetting = function (name, value, default_value) {
|
||||
if (value == undefined) {
|
||||
return (this.settings[name] = default_value);
|
||||
} else {
|
||||
return (this.settings[name] = value);
|
||||
}
|
||||
};
|
||||
|
||||
// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
|
||||
SWFUpload.prototype.getSetting = function (name) {
|
||||
if (this.settings[name] != undefined) {
|
||||
return this.settings[name];
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Private: callFlash handles function calls made to the Flash element.
|
||||
// Calls are made with a setTimeout for some functions to work around
|
||||
// bugs in the ExternalInterface library.
|
||||
SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
|
||||
argumentArray = argumentArray || [];
|
||||
|
||||
var movieElement = this.getMovieElement();
|
||||
var returnValue, returnString;
|
||||
|
||||
// Flash's method if calling ExternalInterface methods (code adapted from MooTools).
|
||||
try {
|
||||
returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
|
||||
returnValue = eval(returnString);
|
||||
} catch (ex) {
|
||||
throw "Вызов " + functionName + " неудачен";
|
||||
}
|
||||
|
||||
// Unescape file post param values
|
||||
if (returnValue != undefined && typeof returnValue.post === "object") {
|
||||
returnValue = this.unescapeFilePostParams(returnValue);
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
/* *****************************
|
||||
-- Flash control methods --
|
||||
Your UI should use these
|
||||
to operate SWFUpload
|
||||
***************************** */
|
||||
|
||||
// WARNING: this function does not work in Flash Player 10
|
||||
// Public: selectFile causes a File Selection Dialog window to appear. This
|
||||
// dialog only allows 1 file to be selected.
|
||||
SWFUpload.prototype.selectFile = function () {
|
||||
this.callFlash("SelectFile");
|
||||
};
|
||||
|
||||
// WARNING: this function does not work in Flash Player 10
|
||||
// Public: selectFiles causes a File Selection Dialog window to appear/ This
|
||||
// dialog allows the user to select any number of files
|
||||
// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
|
||||
// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around
|
||||
// for this bug.
|
||||
SWFUpload.prototype.selectFiles = function () {
|
||||
this.callFlash("SelectFiles");
|
||||
};
|
||||
|
||||
|
||||
// Public: startUpload starts uploading the first file in the queue unless
|
||||
// the optional parameter 'fileID' specifies the ID
|
||||
SWFUpload.prototype.startUpload = function (fileID) {
|
||||
this.callFlash("StartUpload", [fileID]);
|
||||
};
|
||||
|
||||
// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index.
|
||||
// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
|
||||
// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
|
||||
SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
|
||||
if (triggerErrorEvent !== false) {
|
||||
triggerErrorEvent = true;
|
||||
}
|
||||
this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
|
||||
};
|
||||
|
||||
// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
|
||||
// If nothing is currently uploading then nothing happens.
|
||||
SWFUpload.prototype.stopUpload = function () {
|
||||
this.callFlash("StopUpload");
|
||||
};
|
||||
|
||||
/* ************************
|
||||
* Settings methods
|
||||
* These methods change the SWFUpload settings.
|
||||
* SWFUpload settings should not be changed directly on the settings object
|
||||
* since many of the settings need to be passed to Flash in order to take
|
||||
* effect.
|
||||
* *********************** */
|
||||
|
||||
// Public: getStats gets the file statistics object.
|
||||
SWFUpload.prototype.getStats = function () {
|
||||
return this.callFlash("GetStats");
|
||||
};
|
||||
|
||||
// Public: setStats changes the SWFUpload statistics. You shouldn't need to
|
||||
// change the statistics but you can. Changing the statistics does not
|
||||
// affect SWFUpload accept for the successful_uploads count which is used
|
||||
// by the upload_limit setting to determine how many files the user may upload.
|
||||
SWFUpload.prototype.setStats = function (statsObject) {
|
||||
this.callFlash("SetStats", [statsObject]);
|
||||
};
|
||||
|
||||
// Public: getFile retrieves a File object by ID or Index. If the file is
|
||||
// not found then 'null' is returned.
|
||||
SWFUpload.prototype.getFile = function (fileID) {
|
||||
if (typeof(fileID) === "number") {
|
||||
return this.callFlash("GetFileByIndex", [fileID]);
|
||||
} else {
|
||||
return this.callFlash("GetFile", [fileID]);
|
||||
}
|
||||
};
|
||||
|
||||
// Public: addFileParam sets a name/value pair that will be posted with the
|
||||
// file specified by the Files ID. If the name already exists then the
|
||||
// exiting value will be overwritten.
|
||||
SWFUpload.prototype.addFileParam = function (fileID, name, value) {
|
||||
return this.callFlash("AddFileParam", [fileID, name, value]);
|
||||
};
|
||||
|
||||
// Public: removeFileParam removes a previously set (by addFileParam) name/value
|
||||
// pair from the specified file.
|
||||
SWFUpload.prototype.removeFileParam = function (fileID, name) {
|
||||
this.callFlash("RemoveFileParam", [fileID, name]);
|
||||
};
|
||||
|
||||
// Public: setUploadUrl changes the upload_url setting.
|
||||
SWFUpload.prototype.setUploadURL = function (url) {
|
||||
this.settings.upload_url = url.toString();
|
||||
this.callFlash("SetUploadURL", [url]);
|
||||
};
|
||||
|
||||
// Public: setPostParams changes the post_params setting
|
||||
SWFUpload.prototype.setPostParams = function (paramsObject) {
|
||||
this.settings.post_params = paramsObject;
|
||||
this.callFlash("SetPostParams", [paramsObject]);
|
||||
};
|
||||
|
||||
// Public: addPostParam adds post name/value pair. Each name can have only one value.
|
||||
SWFUpload.prototype.addPostParam = function (name, value) {
|
||||
this.settings.post_params[name] = value;
|
||||
this.callFlash("SetPostParams", [this.settings.post_params]);
|
||||
};
|
||||
|
||||
// Public: removePostParam deletes post name/value pair.
|
||||
SWFUpload.prototype.removePostParam = function (name) {
|
||||
delete this.settings.post_params[name];
|
||||
this.callFlash("SetPostParams", [this.settings.post_params]);
|
||||
};
|
||||
|
||||
// Public: setFileTypes changes the file_types setting and the file_types_description setting
|
||||
SWFUpload.prototype.setFileTypes = function (types, description) {
|
||||
this.settings.file_types = types;
|
||||
this.settings.file_types_description = description;
|
||||
this.callFlash("SetFileTypes", [types, description]);
|
||||
};
|
||||
|
||||
// Public: setFileSizeLimit changes the file_size_limit setting
|
||||
SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
|
||||
this.settings.file_size_limit = fileSizeLimit;
|
||||
this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
|
||||
};
|
||||
|
||||
// Public: setFileUploadLimit changes the file_upload_limit setting
|
||||
SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
|
||||
this.settings.file_upload_limit = fileUploadLimit;
|
||||
this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
|
||||
};
|
||||
|
||||
// Public: setFileQueueLimit changes the file_queue_limit setting
|
||||
SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
|
||||
this.settings.file_queue_limit = fileQueueLimit;
|
||||
this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
|
||||
};
|
||||
|
||||
// Public: setFilePostName changes the file_post_name setting
|
||||
SWFUpload.prototype.setFilePostName = function (filePostName) {
|
||||
this.settings.file_post_name = filePostName;
|
||||
this.callFlash("SetFilePostName", [filePostName]);
|
||||
};
|
||||
|
||||
// Public: setUseQueryString changes the use_query_string setting
|
||||
SWFUpload.prototype.setUseQueryString = function (useQueryString) {
|
||||
this.settings.use_query_string = useQueryString;
|
||||
this.callFlash("SetUseQueryString", [useQueryString]);
|
||||
};
|
||||
|
||||
// Public: setRequeueOnError changes the requeue_on_error setting
|
||||
SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
|
||||
this.settings.requeue_on_error = requeueOnError;
|
||||
this.callFlash("SetRequeueOnError", [requeueOnError]);
|
||||
};
|
||||
|
||||
// Public: setHTTPSuccess changes the http_success setting
|
||||
SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
|
||||
if (typeof http_status_codes === "string") {
|
||||
http_status_codes = http_status_codes.replace(" ", "").split(",");
|
||||
}
|
||||
|
||||
this.settings.http_success = http_status_codes;
|
||||
this.callFlash("SetHTTPSuccess", [http_status_codes]);
|
||||
};
|
||||
|
||||
// Public: setHTTPSuccess changes the http_success setting
|
||||
SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
|
||||
this.settings.assume_success_timeout = timeout_seconds;
|
||||
this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
|
||||
};
|
||||
|
||||
// Public: setDebugEnabled changes the debug_enabled setting
|
||||
SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
|
||||
this.settings.debug_enabled = debugEnabled;
|
||||
this.callFlash("SetDebugEnabled", [debugEnabled]);
|
||||
};
|
||||
|
||||
// Public: setButtonImageURL loads a button image sprite
|
||||
SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
|
||||
if (buttonImageURL == undefined) {
|
||||
buttonImageURL = "";
|
||||
}
|
||||
|
||||
this.settings.button_image_url = buttonImageURL;
|
||||
this.callFlash("SetButtonImageURL", [buttonImageURL]);
|
||||
};
|
||||
|
||||
// Public: setButtonDimensions resizes the Flash Movie and button
|
||||
SWFUpload.prototype.setButtonDimensions = function (width, height) {
|
||||
this.settings.button_width = width;
|
||||
this.settings.button_height = height;
|
||||
|
||||
var movie = this.getMovieElement();
|
||||
if (movie != undefined) {
|
||||
movie.style.width = width + "px";
|
||||
movie.style.height = height + "px";
|
||||
}
|
||||
|
||||
this.callFlash("SetButtonDimensions", [width, height]);
|
||||
};
|
||||
// Public: setButtonText Changes the text overlaid on the button
|
||||
SWFUpload.prototype.setButtonText = function (html) {
|
||||
this.settings.button_text = html;
|
||||
this.callFlash("SetButtonText", [html]);
|
||||
};
|
||||
// Public: setButtonTextPadding changes the top and left padding of the text overlay
|
||||
SWFUpload.prototype.setButtonTextPadding = function (left, top) {
|
||||
this.settings.button_text_top_padding = top;
|
||||
this.settings.button_text_left_padding = left;
|
||||
this.callFlash("SetButtonTextPadding", [left, top]);
|
||||
};
|
||||
|
||||
// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
|
||||
SWFUpload.prototype.setButtonTextStyle = function (css) {
|
||||
this.settings.button_text_style = css;
|
||||
this.callFlash("SetButtonTextStyle", [css]);
|
||||
};
|
||||
// Public: setButtonDisabled disables/enables the button
|
||||
SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
|
||||
this.settings.button_disabled = isDisabled;
|
||||
this.callFlash("SetButtonDisabled", [isDisabled]);
|
||||
};
|
||||
// Public: setButtonAction sets the action that occurs when the button is clicked
|
||||
SWFUpload.prototype.setButtonAction = function (buttonAction) {
|
||||
this.settings.button_action = buttonAction;
|
||||
this.callFlash("SetButtonAction", [buttonAction]);
|
||||
};
|
||||
|
||||
// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
|
||||
SWFUpload.prototype.setButtonCursor = function (cursor) {
|
||||
this.settings.button_cursor = cursor;
|
||||
this.callFlash("SetButtonCursor", [cursor]);
|
||||
};
|
||||
|
||||
/* *******************************
|
||||
Flash Event Interfaces
|
||||
These functions are used by Flash to trigger the various
|
||||
events.
|
||||
|
||||
All these functions a Private.
|
||||
|
||||
Because the ExternalInterface library is buggy the event calls
|
||||
are added to a queue and the queue then executed by a setTimeout.
|
||||
This ensures that events are executed in a determinate order and that
|
||||
the ExternalInterface bugs are avoided.
|
||||
******************************* */
|
||||
|
||||
SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
|
||||
// Warning: Don't call this.debug inside here or you'll create an infinite loop
|
||||
|
||||
if (argumentArray == undefined) {
|
||||
argumentArray = [];
|
||||
} else if (!(argumentArray instanceof Array)) {
|
||||
argumentArray = [argumentArray];
|
||||
}
|
||||
|
||||
var self = this;
|
||||
if (typeof this.settings[handlerName] === "function") {
|
||||
// Queue the event
|
||||
this.eventQueue.push(function () {
|
||||
this.settings[handlerName].apply(this, argumentArray);
|
||||
});
|
||||
|
||||
// Execute the next queued event
|
||||
setTimeout(function () {
|
||||
self.executeNextEvent();
|
||||
}, 0);
|
||||
|
||||
} else if (this.settings[handlerName] !== null) {
|
||||
throw "Обработчик " + handlerName + " неизвестен или это не функция";
|
||||
}
|
||||
};
|
||||
|
||||
// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout
|
||||
// we must queue them in order to garentee that they are executed in order.
|
||||
SWFUpload.prototype.executeNextEvent = function () {
|
||||
// Warning: Don't call this.debug inside here or you'll create an infinite loop
|
||||
|
||||
var f = this.eventQueue ? this.eventQueue.shift() : null;
|
||||
if (typeof(f) === "function") {
|
||||
f.apply(this);
|
||||
}
|
||||
};
|
||||
|
||||
// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
|
||||
// properties that contain characters that are not valid for JavaScript identifiers. To work around this
|
||||
// the Flash Component escapes the parameter names and we must unescape again before passing them along.
|
||||
SWFUpload.prototype.unescapeFilePostParams = function (file) {
|
||||
var reg = /[$]([0-9a-f]{4})/i;
|
||||
var unescapedPost = {};
|
||||
var uk;
|
||||
|
||||
if (file != undefined) {
|
||||
for (var k in file.post) {
|
||||
if (file.post.hasOwnProperty(k)) {
|
||||
uk = k;
|
||||
var match;
|
||||
while ((match = reg.exec(uk)) !== null) {
|
||||
uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16)));
|
||||
}
|
||||
unescapedPost[uk] = file.post[k];
|
||||
}
|
||||
}
|
||||
|
||||
file.post = unescapedPost;
|
||||
}
|
||||
|
||||
return file;
|
||||
};
|
||||
|
||||
// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
|
||||
SWFUpload.prototype.testExternalInterface = function () {
|
||||
try {
|
||||
return this.callFlash("TestExternalInterface");
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Private: This event is called by Flash when it has finished loading. Don't modify this.
|
||||
// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
|
||||
SWFUpload.prototype.flashReady = function () {
|
||||
// Check that the movie element is loaded correctly with its ExternalInterface methods defined
|
||||
var movieElement = this.getMovieElement();
|
||||
|
||||
if (!movieElement) {
|
||||
this.debug("Flash called back ready but the flash movie can't be found.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.cleanUp(movieElement);
|
||||
|
||||
this.queueEvent("swfupload_loaded_handler");
|
||||
};
|
||||
|
||||
// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
|
||||
// This function is called by Flash each time the ExternalInterface functions are created.
|
||||
SWFUpload.prototype.cleanUp = function (movieElement) {
|
||||
// Pro-actively unhook all the Flash functions
|
||||
try {
|
||||
if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE
|
||||
this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");
|
||||
for (var key in movieElement) {
|
||||
try {
|
||||
if (typeof(movieElement[key]) === "function") {
|
||||
movieElement[key] = null;
|
||||
}
|
||||
} catch (ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex1) {
|
||||
|
||||
}
|
||||
|
||||
// Fix Flashes own cleanup code so if the SWFMovie was removed from the page
|
||||
// it doesn't display errors.
|
||||
window["__flash__removeCallback"] = function (instance, name) {
|
||||
try {
|
||||
if (instance) {
|
||||
instance[name] = null;
|
||||
}
|
||||
} catch (flashEx) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* This is a chance to do something before the browse window opens */
|
||||
SWFUpload.prototype.fileDialogStart = function () {
|
||||
this.queueEvent("file_dialog_start_handler");
|
||||
};
|
||||
|
||||
|
||||
/* Called when a file is successfully added to the queue. */
|
||||
SWFUpload.prototype.fileQueued = function (file) {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
this.queueEvent("file_queued_handler", file);
|
||||
};
|
||||
|
||||
|
||||
/* Handle errors that occur when an attempt to queue a file fails. */
|
||||
SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
|
||||
};
|
||||
|
||||
/* Called after the file dialog has closed and the selected files have been queued.
|
||||
You could call startUpload here if you want the queued files to begin uploading immediately. */
|
||||
SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) {
|
||||
this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]);
|
||||
};
|
||||
|
||||
SWFUpload.prototype.uploadStart = function (file) {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
this.queueEvent("return_upload_start_handler", file);
|
||||
};
|
||||
|
||||
SWFUpload.prototype.returnUploadStart = function (file) {
|
||||
var returnValue;
|
||||
if (typeof this.settings.upload_start_handler === "function") {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
returnValue = this.settings.upload_start_handler.call(this, file);
|
||||
} else if (this.settings.upload_start_handler != undefined) {
|
||||
throw "upload_start_handler must be a function";
|
||||
}
|
||||
|
||||
// Convert undefined to true so if nothing is returned from the upload_start_handler it is
|
||||
// interpretted as 'true'.
|
||||
if (returnValue === undefined) {
|
||||
returnValue = true;
|
||||
}
|
||||
|
||||
returnValue = !!returnValue;
|
||||
|
||||
this.callFlash("ReturnUploadStart", [returnValue]);
|
||||
};
|
||||
|
||||
|
||||
|
||||
SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
|
||||
};
|
||||
|
||||
SWFUpload.prototype.uploadError = function (file, errorCode, message) {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
this.queueEvent("upload_error_handler", [file, errorCode, message]);
|
||||
};
|
||||
|
||||
SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
this.queueEvent("upload_success_handler", [file, serverData, responseReceived]);
|
||||
};
|
||||
|
||||
SWFUpload.prototype.uploadComplete = function (file) {
|
||||
file = this.unescapeFilePostParams(file);
|
||||
this.queueEvent("upload_complete_handler", file);
|
||||
};
|
||||
|
||||
/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
|
||||
internal debug console. You can override this event and have messages written where you want. */
|
||||
SWFUpload.prototype.debug = function (message) {
|
||||
this.queueEvent("debug_handler", message);
|
||||
};
|
||||
|
||||
|
||||
/* **********************************
|
||||
Debug Console
|
||||
The debug console is a self contained, in page location
|
||||
for debug message to be sent. The Debug Console adds
|
||||
itself to the body if necessary.
|
||||
|
||||
The console is automatically scrolled as messages appear.
|
||||
|
||||
If you are using your own debug handler or when you deploy to production and
|
||||
have debug disabled you can remove these functions to reduce the file size
|
||||
and complexity.
|
||||
********************************** */
|
||||
|
||||
// Private: debugMessage is the default debug_handler. If you want to print debug messages
|
||||
// call the debug() function. When overriding the function your own function should
|
||||
// check to see if the debug setting is true before outputting debug information.
|
||||
SWFUpload.prototype.debugMessage = function (message) {
|
||||
if (this.settings.debug) {
|
||||
var exceptionMessage, exceptionValues = [];
|
||||
|
||||
// Check for an exception object and print it nicely
|
||||
if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") {
|
||||
for (var key in message) {
|
||||
if (message.hasOwnProperty(key)) {
|
||||
exceptionValues.push(key + ": " + message[key]);
|
||||
}
|
||||
}
|
||||
exceptionMessage = exceptionValues.join("\n") || "";
|
||||
exceptionValues = exceptionMessage.split("\n");
|
||||
exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
|
||||
SWFUpload.Console.writeLine(exceptionMessage);
|
||||
} else {
|
||||
SWFUpload.Console.writeLine(message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SWFUpload.Console = {};
|
||||
SWFUpload.Console.writeLine = function (message) {
|
||||
var console, documentForm;
|
||||
|
||||
try {
|
||||
console = document.getElementById("SWFUpload_Console");
|
||||
|
||||
if (!console) {
|
||||
documentForm = document.createElement("form");
|
||||
document.getElementsByTagName("body")[0].appendChild(documentForm);
|
||||
|
||||
console = document.createElement("textarea");
|
||||
console.id = "SWFUpload_Console";
|
||||
console.style.fontFamily = "monospace";
|
||||
console.setAttribute("wrap", "off");
|
||||
console.wrap = "off";
|
||||
console.style.overflow = "auto";
|
||||
console.style.width = "700px";
|
||||
console.style.height = "350px";
|
||||
console.style.margin = "5px";
|
||||
documentForm.appendChild(console);
|
||||
}
|
||||
|
||||
console.value += message + "\n";
|
||||
|
||||
console.scrollTop = console.scrollHeight - console.clientHeight;
|
||||
} catch (ex) {
|
||||
alert("Исключение: " + ex.name + " Сообщение: " + ex.message);
|
||||
}
|
||||
};
|
||||
Binary file not shown.
Reference in new issue
Block a user