Version 3.4.5

This commit is contained in:
Neo committed 2025-12-19 00:38:12 -08:00
1 parent fb6b5baabc
commit e4478369d8
1360 files changed
+228921 -179445

No files matched your search

+272 -55
View File
@@ -9,7 +9,7 @@
/* ===================================================================================================== */
/* IPB3 JS Debugging */
var USE_RTE = 0;
var Debug = {
write: function( text ){
if( jsDebug && !Object.isUndefined(window.console) ){
@@ -61,6 +61,12 @@ Prototype.Browser.IE9 = Prototype.Browser.IE && parseInt(navigator.userAgent.sub
/* Add in stuff prototype does not include */
Prototype.Browser.Chrome = Prototype.Browser.WebKit && ( navigator.userAgent.indexOf('Chrome/') > -1 );
/* Older browsers do not have String.trim() */
if ( !String.prototype.trim )
{
String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g, ''); };
}
/* ===================================================================================================== */
/* OVERWRITE getOffsetParent TO FIX TD ISSUE */
@@ -175,6 +181,10 @@ window.IPBoard = Class.create({
/* General links to functions */
$$("[data-clicklaunch]").invoke('clickLaunch');
/* Quote functions */
ipb.global.parseQuoteBoxes();
ipb.global.removeLinkedLightbox();
},
onSuccess: function() {
if ( ! Object.isUndefined( ipb.hoverCard ) ){
@@ -364,7 +374,7 @@ IPBoard.prototype.Cookie = {
{
path = ipb.vars['cookie_path'];
}
document.cookie = ipb.vars['cookie_id'] + name + "=" + escape( value ) + "; path=" + path + expires + domain + ';';
ipb.Cookie.store[ name ] = value;
@@ -765,7 +775,7 @@ IPBoard.prototype.Autocomplete = Class.create( {
if( json == false ){
// No results yet, get them
var request = new Ajax.Request( this.options.url + escape( curValue ),
var request = new Ajax.Request( this.options.url + encodeURIComponent( curValue ),
{
method: 'get',
evalJSON: 'force',
@@ -974,6 +984,26 @@ IPBoard.prototype.Autocomplete = Class.create( {
}
});
/**
* Get query string param
*/
getQueryStringParamByName = function(name)
{
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.search);
if ( results == null )
{
return "";
}
else
{
return decodeURIComponent( results[1].replace(/\+/g, " ") );
}
};
/* ===================================================================================================== */
/* Extended objects */
@@ -991,6 +1021,36 @@ Object.extend( RegExp, {
}
});
// Escape regex
String.prototype.regExpEscape = function()
{
var text = this;
return text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};
// Extend String with HTMLspecial chars
String.prototype.escapeHtml = function()
{
return this
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
};
//Extend String with HTMLspecial chars
String.prototype.unEscapeHtml = function()
{
var _t = this.replace( /&amp;/g, "&" );
return _t
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&quot;/g, '"')
.replace(/&#039;/g, "'")
.replace(/&#39;/g, "'");
};
// Extend String with URL UTF-8 escape
String.prototype.encodeUrl = function()
{
@@ -1026,6 +1086,27 @@ String.prototype.encodeParam = function()
return escape(text).replace(/\+/g, "%2B");
};
// Extend date object to return date and time as object
Date.prototype.getDateAndTime = function( unix )
{
var a = new Date( parseInt( unix ) * 1000 );
var months = ipb.lang['gbl_months'].split(',');
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var hour = a.getHours();
var min = a.getMinutes();
var sec = a.getSeconds();
return { year : year,
monthName: month,
month : ( '0' + a.getMonth() + 1 ).slice( -2 ),
date : ( '0' + date ).slice( -2 ),
hour : ( '0' + hour ).slice( -2 ),
min : ( '0' + min ).slice( -2 ),
sec : ( '0' + sec ).slice( -2 ),
dst : a.getTimezoneOffset() };
};
// Extend Date object with a function to check for DST
Date.prototype.getDST = function()
@@ -1073,7 +1154,7 @@ var Loader = {
).each(
function(s) {
var path = s.src.replace(/ipb\.js(\?.*)?$/,'');
var includes = s.src.match(/\?.*load=([a-zA-Z0-9_,]*)/);
var includes = s.src.match(/\?.*load=([a-zA-Z0-9_,\.]*)/);
if( ! Object.isUndefined(includes) && includes != null && includes[1] )
{
includes[1].split(',').each(
@@ -1104,6 +1185,12 @@ var callback = {
Element.addMethods( {
getInnerText: function(element)
{
element = $(element);
return element.innerText && ! window.opera ? element.innerText : element.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, ' ');
},
defaultize: function( element, lang )
{
if( ipb.global._supportsPlaceholder == null ){
@@ -1170,12 +1257,16 @@ Element.addMethods( {
$(element).store('clickevent', click);
},
confirmAction: function( element )
confirmAction: function( element, callback )
{
var _text = $( element ).readAttribute("data-confirmaction");
var _ok = '';
if ( element.tagName == 'FORM' )
if( callback )
{
_ok = callback;
}
else if ( element.tagName == 'FORM' )
{
_ok = "$('" + element.id +"').submit()";
}
@@ -1183,7 +1274,7 @@ Element.addMethods( {
{
_ok = 'window.location=\'' + element.readAttribute( 'href' ) + '\'';
}
if ( ! _text || _text == 'true' )
{
_text = ipb.lang['gbl_confirm_desc'];
@@ -1192,12 +1283,12 @@ Element.addMethods( {
var _options = { type: 'pane',
modal: true,
/* Inline JS makes it easier even if it is uglier */
initial: '<div><h3>' + ipb.lang['gbl_confirm_text'] + '</h3><div class="ipsPad ipsForm_center"><p>' + _text + '</p><br /><span onclick="ipb.global.popups[\'conact\'].hide()" class="clickable ipsButton_secondary important">' + ipb.lang['gbl_confirm_cancel'] + '</span> &nbsp; <span onclick="' + _ok + '" class="clickable ipsButton_secondary">' + ipb.lang['gbl_confirm_ok'] + '</span></div>',
initial: '<div><h3>' + ipb.lang['gbl_confirm_text'] + '</h3><div class="ipsPad ipsForm_center"><p>' + _text + '</p><br /><span onclick="ipb.global.popups[\'conact\'].hide();" class="clickable ipsButton_secondary important">' + ipb.lang['gbl_confirm_cancel'] + '</span> &nbsp; <span onclick="' + _ok + '" class="clickable ipsButton_secondary">' + ipb.lang['gbl_confirm_ok'] + '</span></div>',
hideAtStart: false,
w: '300px',
h: 150 };
if ( element.tagName == 'FORM' )
if ( element.tagName == 'FORM' || callback )
{
/* Fire immediately */
if ( ! Object.isUndefined( ipb.global.popups['conact'] ) )
@@ -1229,7 +1320,7 @@ Element.addMethods( {
options = Object.extend( {
template: new Template("<div class='ipsTooltip' id='#{id}' style='display: none'><div class='ipsTooltip_inner'>#{content}</div></div>"),
position: 'auto',
content: $( element ).readAttribute("data-tooltip"),
content: $( element ).readAttribute("data-tooltip").stripTags().escapeHTML(),
animate: true,
overrideBrowser: true,
delay: 0.4
@@ -1252,7 +1343,7 @@ Element.addMethods( {
}
if( options.overrideBrowser && $(element).hasAttribute('title') ){
$(element).writeAttribute("data-title", $(element).readAttribute('title')).writeAttribute("title", false);
$(element).writeAttribute("data-title", $(element).readAttribute('title').stripTags().escapeHTML()).writeAttribute("title", false);
}
var tooltip = $(id + '_tooltip').setStyle({position: 'absolute'});
@@ -1379,7 +1470,7 @@ _global.prototype.global = {
ipb.delegate.register(".mini_friend_toggle", ipb.global.toggleFriend);
ipb.delegate.register(".__topic_preview", ipb.global.topicPreview);
ipb.delegate.register('.bbc_spoiler_show', ipb.global.toggleSpoiler);
ipb.delegate.register('a[rel~="external"]', ipb.global.openNewWindow );
ipb.delegate.register('a[rel~="external"]', ipb.global.openNewWindow , 'force' );
ipb.delegate.register('._repLikeMore', ipb.global.repLikeMore);
ipb.delegate.register('a[rel~="quickNavigation"]', ipb.global.openQuickNavigation );
@@ -1451,6 +1542,9 @@ _global.prototype.global = {
$('statusSubmitGlobal').observe( 'click', ipb.global.statusUpdated );
}
ipb.global.parseQuoteBoxes();
ipb.global.removeLinkedLightbox();
/* Attachments wrapped in URL @link http://community.invisionpower.com/tracker/issue-37113-linking-image-attachments-does-not-work/ */
$$('a.resized_img').each( function( elem )
{
@@ -1478,6 +1572,140 @@ _global.prototype.global = {
}
},
/* Make quote boxes all nice */
parseQuoteBoxes: function()
{
$$('blockquote.ipsBlockquote').each( function( el )
{
if ( ! $(el).hasClassName('built') )
{
var author = '';
var cid = '';
var time = 0;
var date = '';
var collapsed = 0;
var _extra = '';
var _a = new Element('span');
try {
author = $(el).getAttribute( 'data-author' ) ? $(el).getAttribute( 'data-author' ).escapeHtml() : '';
cid = $(el).getAttribute( 'data-cid' ) ? $(el).getAttribute( 'data-cid' ).escapeHtml() : '';
time = $(el).getAttribute( 'data-time' ) ? $(el).getAttribute( 'data-time' ).escapeHtml() : 0;
date = $(el).getAttribute( 'data-date' ) ? $(el).getAttribute( 'data-date' ).escapeHtml() : '';
collapsed = $(el).getAttribute( 'data-collapsed' ) ? $(el).getAttribute( 'data-collapsed' ).escapeHtml() : 0;
} catch( aCold ) { }
if ( time )
{
if ( time == parseInt( time ) && time.length == 10 )
{
/* First, determine if we are in DST now */
var _tz = new Date().getTimezoneOffset() * 60;
/* Find out if timestamp was in DST */
var _date = new Date().getDateAndTime( parseInt( time ) );
/* If there isn't a match, figure out the DST offset and then add it back in */
if( _date['dst'] * 60 != _tz )
{
_tz = _tz - _date['dst'] * 60;
_date = new Date().getDateAndTime( parseInt( time ) - parseInt( _tz ) );
}
var _ampm = '';
if( ipb.vars['hour_format'] == "12" )
{
if( _date['hour'] > 12 )
{
_date['hour'] -= 12;
_ampm = ' ' + ipb.lang['date_pm'];
}
else if( _date['hour'] == 12 )
{
_ampm = ' ' + ipb.lang['date_pm'];
}
else if( _date['hour'] == 0 )
{
_date['hour'] = 12;
_ampm = ' ' + ipb.lang['date_am'];
}
else
{
_ampm = ' ' + ipb.lang['date_am'];
}
}
date = _date['date'] + ' ' + _date['monthName'] + ' ' + _date['year'] + ' - ' + _date['hour'] + ':' + _date['min'] + _ampm;
}
}
if ( author && date )
{
_extra = ipb.lang['quote__date_author'].replace( /#name#/, author ).replace( /#date#/, date );
}
else if ( author )
{
_extra = ipb.lang['quote__author'].replace( /#name#/, author );
}
else if ( date )
{
_extra = ipb.lang['quote_title'] + ' (' + date + ')';
}
/* finally.. */
if ( _extra.length == 0 )
{
_extra = ipb.lang['quote_title'];
}
if ( cid && parseInt( cid ) == cid )
{
_a = new Element( 'a', { 'class': 'snapback right', rel: 'citation', href: ipb.vars['board_url'] + '/index.php?app=forums&module=forums&section=findpost&pid=' + cid } );
_a.update( new Element( 'img', { src: ipb.vars['img_url'] + '/snapback.png' } ) );
}
el.insert( { before: new Element( 'p', { 'class': 'citation' } ).update( _extra ).insert( _a ) } );
try
{
el.down('cite').hide();
}
catch(err){}
el.addClassName( 'built' );
if ( collapsed )
{
var wrapper = new Element( 'div', {'class': '_quote-wrapper' } ).update( el.innerHTML );
el.update( wrapper );
el.down('div._quote-wrapper').hide();
el.insert( new Element( 'p', { 'class': '___x clickable' } ).update( ipb.lang['quote_expand'] ) );
el.down('p.___x').on( 'click', function( e, elem )
{
elem.up('blockquote').down('div._quote-wrapper').show();
elem.hide();
} );
}
}
} );
},
/* Remove lightbox if wrapped in a link */
removeLinkedLightbox: function()
{
$$('a.bbc_url').each( function( el )
{
if ( _thislightbox = $(el).down('span[rel~=lightbox]') )
{
var contents = $(el).innerHTML.replace('<span rel="lightbox">', '');
contents = contents.replace('</span>', '');
$(el).innerHTML = contents;
}
} );
},
/* Lightbox has been disabled */
lightBoxIsOff: function()
{
@@ -1485,7 +1713,7 @@ _global.prototype.global = {
{
if ( ! $(elem).down('a') )
{
$(elem).down('img').on( 'click', function(e, el) { window.open(el.src) } );
$(elem).down('img').on( 'click', function(e, el) { window.open(el.src); } );
}
} );
},
@@ -1547,7 +1775,9 @@ _global.prototype.global = {
var su_Twitter = $('su_TwitterGlobal') && $('su_TwitterGlobal').checked ? 1 : 0;
var su_Facebook = $('su_FacebookGlobal') && $('su_FacebookGlobal').checked ? 1 : 0;
new Ajax.Request( ipb.vars['base_url'] + "app=members&section=status&module=ajax&do=new&md5check=" + ipb.vars['secure_hash'] + "&skin_group=boards&return=json&smallSpace=1",
var skin_group = ( $('statusHook') ) ? 'boards' : 'profile';
new Ajax.Request( ipb.vars['base_url'] + "app=members&section=status&module=ajax&do=new&md5check=" + ipb.vars['secure_hash'] + "&skin_group=" + skin_group + "&return=json&smallSpace=1",
{
method: 'post',
evalJSON: 'force',
@@ -1599,6 +1829,8 @@ _global.prototype.global = {
ipb.menus.closeAll(e,true);
ipb.global.showInlineNotification( ipb.lang['status_updated'] );
$('statusUpdateGlobal').value = '';
$('statusUpdateGlobal').defaultize( ipb.lang['global_status_update'] );
}
catch(err)
{
@@ -1615,7 +1847,7 @@ _global.prototype.global = {
changeSkin: function(element, e)
{
Debug.dir( element );
var skinId = $(element).readAttribute( 'data-skinid');
var skinId = $(element).readAttribute('data-skinid');
var url = ipb.vars['base_url'] + 'app=core&module=ajax&section=skin&do=change&skinId=' + skinId + '&secure_key=' + ipb.vars['secure_hash'];
Debug.write( url );
@@ -1920,7 +2152,7 @@ _global.prototype.global = {
if( !id ){ return; }
var url = ipb.vars['base_url'] + '&app=forums&module=ajax&secure_key=' + ipb.vars['secure_hash'] + '&section=forums&do=markRead&fid=' + id;
var url = ipb.vars['base_url'] + '&app=forums&module=ajax&secure_key=' + ipb.vars['secure_hash'] + '&section=markasread&forumid=' + id;
// Send AJAX request
new Ajax.Request( url,
@@ -2158,18 +2390,15 @@ _global.prototype.global = {
options.neverClose = ( Object.isUndefined( options.neverClose ) ) ? false : options.neverClose;
options.displayForSeconds = ( Object.isUndefined( options.displayForSeconds ) ) ? 5 : options.displayForSeconds;
/* Already one open? */
// If there's already one open, close it,
// and add a callback to try again in when its done.
if ( $('ipsGlobalNotification' ) )
{
var span = $('ipsGlobalNotification').down('span');
/* fade out current content and fade in new */
new Effect.Fade( span, { duration: 0.8, afterFinish:
function() {
span.replace( new Element( 'span' ).update( content ) );
new Effect.Appear( $('ipsGlobalNotification').down('span'), { duration: 0.8 } );
}
} );
ipb.global.closeInlineNotification( function(){
ipb.global.showInlineNotification( content, options );
});
return;
}
else
{
@@ -2216,8 +2445,10 @@ _global.prototype.global = {
/**
* Closes a notification
*/
closeInlineNotification: function()
closeInlineNotification: function( callback )
{
callback = callback || Prototype.emptyFunction;
if ( $('ipsGlobalNotification_close') ){
$('ipsGlobalNotification_close').stopObserving('click');
}
@@ -2227,8 +2458,10 @@ _global.prototype.global = {
}
catch(e) {}
new Effect.Fade( 'ipsGlobalNotification', { duration: 1.0 } );
setTimeout( function() { $('ipsGlobalNotification').remove(); }, 2000 );
new Effect.Fade( 'ipsGlobalNotification', { duration: 1.0, afterFinish: function(){
$('ipsGlobalNotification').remove();
callback();
} } );
},
/**
@@ -2476,7 +2709,7 @@ _global.prototype.global = {
{
if( link.readAttribute('type') == "application/rss+xml" )
{
ipb.global.rssItems.push( ipb.templates['rss_item'].evaluate( { url: link.readAttribute('href'), title: link.readAttribute('title') } ) );
ipb.global.rssItems.push( ipb.templates['rss_item'].evaluate( { url: link.readAttribute('href'), title: link.readAttribute('title').escapeHtml() } ) );
}
});
@@ -2913,32 +3146,15 @@ _global.prototype.global = {
pageNum = options.totalPages;
}*/
if( ipb.vars['seo_enabled'] ){
// Bug #33897
// Pagination broken in search results due to use of query string, so here we'll check
// whether QS's are used with regex, and use old style pagination if that's the case.
if( options.url.charAt( options.url.length - 1 ) == '=' || options.url.match(/(&|&amp;)[\d\w]+=/gi) ){
// Bug #31029
// SEO URLs ending with = don't work. Use non-seo urls in this case.
var url = options.url + '&amp;' + options.stKey + '=' + pageNum;
} else {
if( document.location.toString().match( ipb.vars['seo_params']['start'] ) && document.location.toString().match( ipb.vars['seo_params']['end'] ) ){
if ( options.url.match( ipb.vars['seo_params']['varBlock'] ) )
{
var url = options.url + ipb.vars['seo_params']['varSep'] + options.stKey + ipb.vars['seo_params']['varSep'] + pageNum;
}
else
{
var url = options.url + ipb.vars['seo_params']['varBlock'] + options.stKey + ipb.vars['seo_params']['varSep'] + pageNum;
}
} else {
var url = options.url + ipb.vars['seo_params']['varBlock'] + options.stKey + ipb.vars['seo_params']['varSep'] + pageNum;
}
}
} else {
var url = options.url + '&amp;' + options.stKey + '=' + pageNum;
}
/* Probably much easier to let the PHP redirect figure it out
* now we have the new page-2 options. Not an SEO issue as crawlers won't input
* data and not a resouces issue as drop down is hardly a hot spot for traffic
*/
var separator = options.url.indexOf( '&' ) !== -1 ? '&' : '?' ;
var url = options.url + separator + options.stKey + '=' + pageNum;
if( options.anchor )
{
url = url + options.anchor;
@@ -3902,6 +4118,7 @@ _popup.prototype.Popup = Class.create({
if( e ){ Event.stop(e); }
if( this.document_event ){
Event.stopObserving( document, 'click', this.document_event );
Event.stopObserving( document, 'touchstart', this.document_event );
}
if( this.timer['hide'] ){