Alien-Web-ExtJS-V3
view release on metacpan or search on metacpan
share/ext-all-debug-w-comments.js view on Meta::CPAN
return function() { // return a closure for efficiency
var m = this.getMonth();
return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
};
}(),
/**
* Get the English ordinal suffix of the current day (equivalent to the format specifier 'S').
* @return {String} 'st, 'nd', 'rd' or 'th'.
*/
getSuffix : function() {
switch (this.getDate()) {
case 1:
case 21:
case 31:
return "st";
case 2:
case 22:
return "nd";
case 3:
case 23:
return "rd";
default:
return "th";
}
},
/**
* Creates and returns a new Date instance with the exact same date value as the called instance.
* Dates are copied and passed by reference, so if a copied date variable is modified later, the original
* variable will also be changed. When the intention is to create a new variable that will not
* modify the original instance, you should create a clone.
*
* Example of correctly cloning a date:
* <pre><code>
//wrong way:
var orig = new Date('10/1/2006');
var copy = orig;
copy.setDate(5);
document.write(orig); //returns 'Thu Oct 05 2006'!
//correct way:
var orig = new Date('10/1/2006');
var copy = orig.clone();
copy.setDate(5);
document.write(orig); //returns 'Thu Oct 01 2006'
</code></pre>
* @return {Date} The new Date instance.
*/
clone : function() {
return new Date(this.getTime());
},
/**
* Checks if the current date is affected by Daylight Saving Time (DST).
* @return {Boolean} True if the current date is affected by DST.
*/
isDST : function() {
// adapted from http://extjs.com/forum/showthread.php?p=247172#post247172
// courtesy of @geoffrey.mcgill
return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
},
/**
* Attempts to clear all time information from this Date by setting the time to midnight of the same day,
* automatically adjusting for Daylight Saving Time (DST) where applicable.
* (note: DST timezone information for the browser's host operating system is assumed to be up-to-date)
* @param {Boolean} clone true to create a clone of this date, clear the time and return it (defaults to false).
* @return {Date} this or the clone.
*/
clearTime : function(clone) {
if (clone) {
return this.clone().clearTime();
}
// get current date before clearing time
var d = this.getDate();
// clear time
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
this.setMilliseconds(0);
if (this.getDate() != d) { // account for DST (i.e. day of month changed when setting hour = 0)
// note: DST adjustments are assumed to occur in multiples of 1 hour (this is almost always the case)
// refer to http://www.timeanddate.com/time/aboutdst.html for the (rare) exceptions to this rule
// increment hour until cloned date == current date
for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
this.setDate(d);
this.setHours(c.getHours());
}
return this;
},
/**
* Provides a convenient method for performing basic date arithmetic. This method
* does not modify the Date instance being called - it creates and returns
* a new Date instance containing the resulting date value.
*
* Examples:
* <pre><code>
// Basic usage:
var dt = new Date('10/29/2006').add(Date.DAY, 5);
document.write(dt); //returns 'Fri Nov 03 2006 00:00:00'
// Negative values will be subtracted:
var dt2 = new Date('10/1/2006').add(Date.DAY, -5);
document.write(dt2); //returns 'Tue Sep 26 2006 00:00:00'
// You can even chain several calls together in one line:
var dt3 = new Date('10/1/2006').add(Date.DAY, 5).add(Date.HOUR, 8).add(Date.MINUTE, -30);
document.write(dt3); //returns 'Fri Oct 06 2006 07:30:00'
</code></pre>
*
* @param {String} interval A valid date interval enum value.
share/ext-all-debug-w-comments.js view on Meta::CPAN
* @class Ext.data.DataProxy
* @extends Ext.util.Observable
* <p>Abstract base class for implementations which provide retrieval of unformatted data objects.
* This class is intended to be extended and should not be created directly. For existing implementations,
* see {@link Ext.data.DirectProxy}, {@link Ext.data.HttpProxy}, {@link Ext.data.ScriptTagProxy} and
* {@link Ext.data.MemoryProxy}.</p>
* <p>DataProxy implementations are usually used in conjunction with an implementation of {@link Ext.data.DataReader}
* (of the appropriate type which knows how to parse the data object) to provide a block of
* {@link Ext.data.Records} to an {@link Ext.data.Store}.</p>
* <p>The parameter to a DataProxy constructor may be an {@link Ext.data.Connection} or can also be the
* config object to an {@link Ext.data.Connection}.</p>
* <p>Custom implementations must implement either the <code><b>doRequest</b></code> method (preferred) or the
* <code>load</code> method (deprecated). See
* {@link Ext.data.HttpProxy}.{@link Ext.data.HttpProxy#doRequest doRequest} or
* {@link Ext.data.HttpProxy}.{@link Ext.data.HttpProxy#load load} for additional details.</p>
* <p><b><u>Example 1</u></b></p>
* <pre><code>
proxy: new Ext.data.ScriptTagProxy({
{@link Ext.data.Connection#url url}: 'http://extjs.com/forum/topics-remote.php'
}),
* </code></pre>
* <p><b><u>Example 2</u></b></p>
* <pre><code>
proxy : new Ext.data.HttpProxy({
{@link Ext.data.Connection#method method}: 'GET',
{@link Ext.data.HttpProxy#prettyUrls prettyUrls}: false,
{@link Ext.data.Connection#url url}: 'local/default.php', // see options parameter for {@link Ext.Ajax#request}
{@link #api}: {
// all actions except the following will use above url
create : 'local/new.php',
update : 'local/update.php'
}
}),
* </code></pre>
* <p>And <b>new in Ext version 3</b>, attach centralized event-listeners upon the DataProxy class itself! This is a great place
* to implement a <i>messaging system</i> to centralize your application's user-feedback and error-handling.</p>
* <pre><code>
// Listen to all "beforewrite" event fired by all proxies.
Ext.data.DataProxy.on('beforewrite', function(proxy, action) {
console.log('beforewrite: ', action);
});
// Listen to "write" event fired by all proxies
Ext.data.DataProxy.on('write', function(proxy, action, data, res, rs) {
console.info('write: ', action);
});
// Listen to "exception" event fired by all proxies
Ext.data.DataProxy.on('exception', function(proxy, type, action, exception) {
console.error(type + action + ' exception);
});
* </code></pre>
* <b>Note:</b> These three events are all fired with the signature of the corresponding <i>DataProxy instance</i> event {@link #beforewrite beforewrite}, {@link #write write} and {@link #exception exception}.
*/
Ext.data.DataProxy = function(conn){
// make sure we have a config object here to support ux proxies.
// All proxies should now send config into superclass constructor.
conn = conn || {};
// This line caused a bug when people use custom Connection object having its own request method.
// http://extjs.com/forum/showthread.php?t=67194. Have to set DataProxy config
//Ext.applyIf(this, conn);
this.api = conn.api;
this.url = conn.url;
this.restful = conn.restful;
this.listeners = conn.listeners;
// deprecated
this.prettyUrls = conn.prettyUrls;
/**
* @cfg {Object} api
* Specific urls to call on CRUD action methods "read", "create", "update" and "destroy".
* Defaults to:<pre><code>
api: {
read : undefined,
create : undefined,
update : undefined,
destroy : undefined
}
* </code></pre>
* <p>The url is built based upon the action being executed <tt>[load|create|save|destroy]</tt>
* using the commensurate <tt>{@link #api}</tt> property, or if undefined default to the
* configured {@link Ext.data.Store}.{@link Ext.data.Store#url url}.</p><br>
* <p>For example:</p>
* <pre><code>
api: {
load : '/controller/load',
create : '/controller/new', // Server MUST return idProperty of new record
save : '/controller/update',
destroy : '/controller/destroy_action'
}
// Alternatively, one can use the object-form to specify each API-action
api: {
load: {url: 'read.php', method: 'GET'},
create: 'create.php',
destroy: 'destroy.php',
save: 'update.php'
}
* </code></pre>
* <p>If the specific URL for a given CRUD action is undefined, the CRUD action request
* will be directed to the configured <tt>{@link Ext.data.Connection#url url}</tt>.</p>
* <br><p><b>Note</b>: To modify the URL for an action dynamically the appropriate API
* property should be modified before the action is requested using the corresponding before
* action event. For example to modify the URL associated with the load action:
* <pre><code>
// modify the url for the action
myStore.on({
beforeload: {
fn: function (store, options) {
// use <tt>{@link Ext.data.HttpProxy#setUrl setUrl}</tt> to change the URL for *just* this request.
store.proxy.setUrl('changed1.php');
// set optional second parameter to true to make this URL change
// permanent, applying this URL for all subsequent requests.
store.proxy.setUrl('changed1.php', true);
// Altering the proxy API should be done using the public
// method <tt>{@link Ext.data.DataProxy#setApi setApi}</tt>.
share/ext-all-debug-w-comments.js view on Meta::CPAN
//cater for any existing valid arguments to this.sort, massage them into an array of sorter objects
if (Ext.isArray(arguments[0])) {
sorters = arguments[0];
} else if (fieldName == undefined) {
//we preserve the existing sortInfo here because this.sort is called after
//clearGrouping and there may be existing sorting
sorters = this.sortInfo ? [this.sortInfo] : [];
} else {
//TODO: this is lifted straight from Ext.data.Store's singleSort function. It should instead be
//refactored into a common method if possible
var field = this.fields.get(fieldName);
if (!field) return false;
var name = field.name,
sortInfo = this.sortInfo || null,
sortToggle = this.sortToggle ? this.sortToggle[name] : null;
if (!dir) {
if (sortInfo && sortInfo.field == name) { // toggle sort dir
dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
} else {
dir = field.sortDir;
}
}
this.sortToggle[name] = dir;
this.sortInfo = {field: name, direction: dir};
sorters = [this.sortInfo];
}
//add the grouping sorter object as the first multisort sorter
if (this.groupField) {
sorters.unshift({direction: this.groupDir, field: this.groupField});
}
return this.multiSort.call(this, sorters, dir);
},
/**
* @private
* Saves the current grouping field and direction to this.baseParams and this.lastOptions.params
* if we're using remote grouping. Does not actually perform any grouping - just stores values
*/
applyGroupField: function(){
if (this.remoteGroup) {
if(!this.baseParams){
this.baseParams = {};
}
Ext.apply(this.baseParams, {
groupBy : this.groupField,
groupDir: this.groupDir
});
var lo = this.lastOptions;
if (lo && lo.params) {
lo.params.groupDir = this.groupDir;
//this is deleted because of a bug reported at http://www.extjs.com/forum/showthread.php?t=82907
delete lo.params.groupBy;
}
}
},
/**
* @private
* TODO: This function is apparently never invoked anywhere in the framework. It has no documentation
* and should be considered for deletion
*/
applyGrouping : function(alwaysFireChange){
if(this.groupField !== false){
this.groupBy(this.groupField, true, this.groupDir);
return true;
}else{
if(alwaysFireChange === true){
this.fireEvent('datachanged', this);
}
return false;
}
},
/**
* @private
* Returns the grouping field that should be used. If groupOnSort is used this will be sortInfo's field,
* otherwise it will be this.groupField
* @return {String} The group field
*/
getGroupState : function(){
return this.groupOnSort && this.groupField !== false ?
(this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
}
});
Ext.reg('groupingstore', Ext.data.GroupingStore);
/**
* @class Ext.data.DirectProxy
* @extends Ext.data.DataProxy
*/
Ext.data.DirectProxy = function(config){
Ext.apply(this, config);
if(typeof this.paramOrder == 'string'){
this.paramOrder = this.paramOrder.split(/[\s,|]/);
}
Ext.data.DirectProxy.superclass.constructor.call(this, config);
};
Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
/**
* @cfg {Array/String} paramOrder Defaults to <tt>undefined</tt>. A list of params to be executed
* server side. Specify the params in the order in which they must be executed on the server-side
* as either (1) an Array of String values, or (2) a String of params delimited by either whitespace,
* comma, or pipe. For example,
* any of the following would be acceptable:<pre><code>
paramOrder: ['param1','param2','param3']
paramOrder: 'param1 param2 param3'
paramOrder: 'param1,param2,param3'
paramOrder: 'param1|param2|param'
</code></pre>
*/
paramOrder: undefined,
share/ext-all-debug-w-comments.js view on Meta::CPAN
this.activeTab = item;
if(item){
var el = this.getTabEl(item);
Ext.fly(el).addClass('x-tab-strip-active');
this.stack.add(item);
this.layout.setActiveItem(item);
// Need to do this here, since setting the active tab slightly changes the size
this.delegateUpdates();
if(this.scrolling){
this.scrollToTab(item, this.animScroll);
}
}
this.fireEvent('tabchange', this, item);
}
},
/**
* Returns the Component which is the currently active tab. <b>Note that before the TabPanel
* first activates a child Component, this method will return whatever was configured in the
* {@link #activeTab} config option.</b>
* @return {BoxComponent} The currently active child Component if one <i>is</i> active, or the {@link #activeTab} config value.
*/
getActiveTab : function(){
return this.activeTab || null;
},
/**
* Gets the specified tab by id.
* @param {String} id The tab id
* @return {Panel} The tab
*/
getItem : function(item){
return this.getComponent(item);
},
// private
autoScrollTabs : function(){
this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
var count = this.items.length,
ow = this.pos.dom.offsetWidth,
tw = this.pos.dom.clientWidth,
wrap = this.stripWrap,
wd = wrap.dom,
cw = wd.offsetWidth,
pos = this.getScrollPos(),
l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
if(!this.enableTabScroll || cw < 20){ // 20 to prevent display:none issues
return;
}
if(count == 0 || l <= tw){
// ensure the width is set if there's no tabs
wd.scrollLeft = 0;
wrap.setWidth(tw);
if(this.scrolling){
this.scrolling = false;
this.pos.removeClass('x-tab-scrolling');
this.scrollLeft.hide();
this.scrollRight.hide();
// See here: http://extjs.com/forum/showthread.php?t=49308&highlight=isSafari
if(Ext.isAir || Ext.isWebKit){
wd.style.marginLeft = '';
wd.style.marginRight = '';
}
}
}else{
if(!this.scrolling){
this.pos.addClass('x-tab-scrolling');
// See here: http://extjs.com/forum/showthread.php?t=49308&highlight=isSafari
if(Ext.isAir || Ext.isWebKit){
wd.style.marginLeft = '18px';
wd.style.marginRight = '18px';
}
}
tw -= wrap.getMargins('lr');
wrap.setWidth(tw > 20 ? tw : 20);
if(!this.scrolling){
if(!this.scrollLeft){
this.createScrollers();
}else{
this.scrollLeft.show();
this.scrollRight.show();
}
}
this.scrolling = true;
if(pos > (l-tw)){ // ensure it stays within bounds
wd.scrollLeft = l-tw;
}else{ // otherwise, make sure the active tab is still visible
this.scrollToTab(this.activeTab, false);
}
this.updateScrollButtons();
}
},
// private
createScrollers : function(){
this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
var h = this.stripWrap.dom.offsetHeight;
// left
var sl = this.pos.insertFirst({
cls:'x-tab-scroller-left'
});
sl.setHeight(h);
sl.addClassOnOver('x-tab-scroller-left-over');
this.leftRepeater = new Ext.util.ClickRepeater(sl, {
interval : this.scrollRepeatInterval,
handler: this.onScrollLeft,
scope: this
});
this.scrollLeft = sl;
// right
var sr = this.pos.insertFirst({
cls:'x-tab-scroller-right'
});
sr.setHeight(h);
sr.addClassOnOver('x-tab-scroller-right-over');
this.rightRepeater = new Ext.util.ClickRepeater(sr, {
interval : this.scrollRepeatInterval,
handler: this.onScrollRight,
scope: this
});
this.scrollRight = sr;
},
// private
getScrollWidth : function(){
return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
share/ext-all-debug-w-comments.js view on Meta::CPAN
{@link Ext.data.JsonReader#totalProperty totalProperty}: 'results',
...
}),
...
});
var myPageSize = 25; // server script should only send back 25 items at a time
var grid = new Ext.grid.GridPanel({
...
store: myStore,
bbar: new Ext.PagingToolbar({
{@link #store}: myStore, // grid and PagingToolbar using same store
{@link #displayInfo}: true,
{@link #pageSize}: myPageSize,
{@link #prependButtons}: true,
items: [
'text 1'
]
})
});
* </code></pre>
*
* <p>To use paging, pass the paging requirements to the server when the store is first loaded.</p>
* <pre><code>
store.load({
params: {
// specify params for the first page load if using paging
start: 0,
limit: myPageSize,
// other params
foo: 'bar'
}
});
* </code></pre>
*
* <p>If using {@link Ext.data.Store#autoLoad store's autoLoad} configuration:</p>
* <pre><code>
var myStore = new Ext.data.Store({
{@link Ext.data.Store#autoLoad autoLoad}: {params:{start: 0, limit: 25}},
...
});
* </code></pre>
*
* <p>The packet sent back from the server would have this form:</p>
* <pre><code>
{
"success": true,
"results": 2000,
"rows": [ // <b>*Note:</b> this must be an Array
{ "id": 1, "name": "Bill", "occupation": "Gardener" },
{ "id": 2, "name": "Ben", "occupation": "Horticulturalist" },
...
{ "id": 25, "name": "Sue", "occupation": "Botanist" }
]
}
* </code></pre>
* <p><u>Paging with Local Data</u></p>
* <p>Paging can also be accomplished with local data using extensions:</p>
* <div class="mdetail-params"><ul>
* <li><a href="http://extjs.com/forum/showthread.php?t=71532">Ext.ux.data.PagingStore</a></li>
* <li>Paging Memory Proxy (examples/ux/PagingMemoryProxy.js)</li>
* </ul></div>
* @constructor Create a new PagingToolbar
* @param {Object} config The config object
* @xtype paging
*/
(function() {
var T = Ext.Toolbar;
Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
/**
* @cfg {Ext.data.Store} store
* The {@link Ext.data.Store} the paging toolbar should use as its data source (required).
*/
/**
* @cfg {Boolean} displayInfo
* <tt>true</tt> to display the displayMsg (defaults to <tt>false</tt>)
*/
/**
* @cfg {Number} pageSize
* The number of records to display per page (defaults to <tt>20</tt>)
*/
pageSize : 20,
/**
* @cfg {Boolean} prependButtons
* <tt>true</tt> to insert any configured <tt>items</tt> <i>before</i> the paging buttons.
* Defaults to <tt>false</tt>.
*/
/**
* @cfg {String} displayMsg
* The paging status message to display (defaults to <tt>'Displaying {0} - {1} of {2}'</tt>).
* Note that this string is formatted using the braced numbers <tt>{0}-{2}</tt> as tokens
* that are replaced by the values for start, end and total respectively. These tokens should
* be preserved when overriding this string if showing those values is desired.
*/
displayMsg : 'Displaying {0} - {1} of {2}',
/**
* @cfg {String} emptyMsg
* The message to display when no records are found (defaults to 'No data to display')
*/
emptyMsg : 'No data to display',
/**
* @cfg {String} beforePageText
* The text displayed before the input item (defaults to <tt>'Page'</tt>).
*/
beforePageText : 'Page',
/**
* @cfg {String} afterPageText
* Customizable piece of the default paging text (defaults to <tt>'of {0}'</tt>). Note that
* this string is formatted using <tt>{0}</tt> as a token that is replaced by the number of
* total pages. This token should be preserved when overriding this string if showing the
* total page count is desired.
*/
afterPageText : 'of {0}',
/**
* @cfg {String} firstText
* The quicktip text displayed for the first page button (defaults to <tt>'First Page'</tt>).
* <b>Note</b>: quick tips must be initialized for the quicktip to show.
*/
share/ext-all-debug-w-comments.js view on Meta::CPAN
v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
v[2] = parseInt(v[2], 10) || 0;
return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
}
/* Cross-browser dynamic CSS creation
- Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
*/
function createCSS(sel, decl, media, newStyle) {
if (ua.ie && ua.mac) { return; }
var h = doc.getElementsByTagName("head")[0];
if (!h) { return; } // to also support badly authored HTML pages that lack a head element
var m = (media && typeof media == "string") ? media : "screen";
if (newStyle) {
dynamicStylesheet = null;
dynamicStylesheetMedia = null;
}
if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
// create dynamic stylesheet + get a global reference to it
var s = createElement("style");
s.setAttribute("type", "text/css");
s.setAttribute("media", m);
dynamicStylesheet = h.appendChild(s);
if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
}
dynamicStylesheetMedia = m;
}
// add style rule
if (ua.ie && ua.win) {
if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
dynamicStylesheet.addRule(sel, decl);
}
}
else {
if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
}
}
}
function setVisibility(id, isVisible) {
if (!autoHideShow) { return; }
var v = isVisible ? "visible" : "hidden";
if (isDomLoaded && getElementById(id)) {
getElementById(id).style.visibility = v;
}
else {
createCSS("#" + id, "visibility:" + v);
}
}
/* Filter to avoid XSS attacks
*/
function urlEncodeIfNecessary(s) {
var regex = /[\\\"<>\.;]/;
var hasBadChars = regex.exec(s) != null;
return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
}
/* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)
*/
var cleanup = function() {
if (ua.ie && ua.win) {
window.attachEvent("onunload", function() {
// remove listeners to avoid memory leaks
var ll = listenersArr.length;
for (var i = 0; i < ll; i++) {
listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
}
// cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect
var il = objIdArr.length;
for (var j = 0; j < il; j++) {
removeSWF(objIdArr[j]);
}
// cleanup library's main closures to avoid memory leaks
for (var k in ua) {
ua[k] = null;
}
ua = null;
for (var l in swfobject) {
swfobject[l] = null;
}
swfobject = null;
window.detachEvent('onunload', arguments.callee);
});
}
}();
return {
/* Public API
- Reference: http://code.google.com/p/swfobject/wiki/documentation
*/
registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
if (ua.w3 && objectIdStr && swfVersionStr) {
var regObj = {};
regObj.id = objectIdStr;
regObj.swfVersion = swfVersionStr;
regObj.expressInstall = xiSwfUrlStr;
regObj.callbackFn = callbackFn;
regObjArr[regObjArr.length] = regObj;
setVisibility(objectIdStr, false);
}
else if (callbackFn) {
callbackFn({success:false, id:objectIdStr});
}
},
getObjectById: function(objectIdStr) {
if (ua.w3) {
return getObjectById(objectIdStr);
}
},
embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
var callbackObj = {success:false, id:replaceElemIdStr};
if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
setVisibility(replaceElemIdStr, false);
addDomLoadEvent(function() {
widthStr += ""; // auto-convert to string
heightStr += "";
var att = {};
if (attObj && typeof attObj === OBJECT) {
for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
att[i] = attObj[i];
}
}
att.data = swfUrlStr;
att.width = widthStr;
att.height = heightStr;
var par = {};
( run in 0.908 second using v1.01-cache-2.11-cpan-02777c243ea )