Version 4.1.19

This commit is contained in:
Neo committed 2025-12-19 05:38:56 -08:00
1 parent 28bd025b35
commit 2bd5025018
2674 files changed
+233518 -77766

No files matched your search

@@ -0,0 +1,428 @@
/*
* IPS embed handling
* http://www.invisionpower.com
*/
( function () {
"use strict";
var _origin;
var _div;
var _posting = false;
var _timer;
var _timeout = 200; //ms
var _embedId = '';
/**
* Init method, called when the document is ready
*
* @returns {void}
*/
function init() {
// Check for postMessage and JSON support
if( !window.postMessage || !window.JSON.parse ){
return;
}
// Work out our URL
_div = utils.get('ipsEmbed');
var url = utils.parseURL( window.location );
if( url.protocol == '' || url.protocol == ':' ){
utils.log( url );
url.protocol = window.location.protocol;
}
// Set our origin
_origin = url.protocol + '//' + url.host;
utils.log( "Origin in loader is " + _origin );
// Hide the content
_div.style.opacity = '0.00001';
};
/**
* Starts our main loop, which posts messages to the parent frame as needed
*
* @returns {void}
*/
function startTimeout() {
var currentSize = 0;
var repeats = 0;
utils.log("Starting timeout...");
// Main loop
_timer = setInterval( function () {
// What we want to do here is make the loading process more pleasant and less jumpy.
// To do that, we'll make the embed invisible until we've fetched the same height 6 times
// in a row (approx 1 second). If that happens we'll assume it has finished loading, and then
// we'll fade it in and start sending the recorded height to the parent for resizing.
var height = utils.getObjHeight( _div );
// If we HAVEN'T started posting our size
if( !_posting ){
if( height == currentSize ){
repeats++;
} else {
// The height has changed, so reset our repeat counter
repeats = 0;
}
if( repeats == 6 ){
_posting = true;
utils.fadeIn( _div );
}
}
currentSize = height;
if( _posting ){
_div.parentNode.className = '';
_postMessage('height', {
height: height
});
}
}, _timeout);
};
/**
* Posts a message to the iframe
*
* @param {number} [pageNo] Page number to load
* @returns {void}
*/
var _postMessage = function (method, obj) {
// Send to parent window
window.top.postMessage( JSON.stringify( utils.extendObj( obj || {}, {
method: method,
embedId: _embedId
} ) ), _origin );
};
/**
* Events sent to the iframe
*/
var messageEvents = {
/**
* The parent is ready for messages
*
* @param {object} data Data from the iframe
* @returns {void}
*/
ready: function (data) {
_embedId = data.embedId;
_postMessage('ok');
startTimeout();
},
stop: function (data) {
clearInterval( _timer );
eventHandler.off( window, 'message', windowMessage );
}
};
/*******************************************************************************************/
/* Boring stuff below */
/**
* Event handling
*/
// http://www.anujgakhar.com/2013/05/22/cross-browser-event-handling-in-javascript/
var eventHandler = {
on: function (el, ev, fn) {
if( window.addEventListener ){
el.addEventListener( ev, fn, false );
} else if( window.attachEvent ){
el.attachEvent( 'on' + ev, fn );
} else {
el[ 'on' + ev ] = fn;
}
},
off: function (el, ev, fn) {
if( window.removeEventListener ){
el.removeEventListener( ev, fn, false );
} else if( window.detachEvent ) {
el.detachEvent( 'on' + ev, fn );
} else {
elem[ 'on' + ev ] = null;
}
},
stop: function (ev) {
var e = ev || window.event;
e.cancelBubble = true;
if( e.stopPropagation ){
e.stopPropagation();
}
}
};
// Main message handler
eventHandler.on( window, 'message', windowMessage );
function windowMessage (e) {
if( e.origin !== _origin ){
utils.log( e.origin + 'does not equal' + _origin );
return;
}
try {
var pmData = JSON.parse( e.data );
var method = pmData.method;
} catch (err) {
utils.error("iframe: invalid data.");
return;
}
if( method && typeof messageEvents[ method ] != 'undefined' ){
utils.log("Called " + method );
messageEvents[ method ].call( this, pmData );
} else {
utils.log("Method " + method + " doesn't exist");
}
};
/**
* Utilities
*/
var utils = {
/**
* Log to console if supported
*
* @param {string} message Message to log
* @returns {void}
*/
log: function (message) {
if( window.console ){
console.log( "(EMBED): " + message );
}
},
/**
* Error to console if supported
*
* @param {string} message Message to log
* @returns {void}
*/
error: function (message) {
if( window.console ){
console.error( message );
}
},
/**
* Gets an element based on ID
*
* @param {string} id Element ID
* @returns {element}
*/
get: function (id) {
return document.getElementById( id );
},
/**
* Extend an object with another object
*
* @param {object} originalObj Original object
* @param {object} newObj New object
* @returns {void}
*/
extendObj: function (originalObj, newObj) {
for( var i in newObj ){
if( newObj.hasOwnProperty(i) ){
originalObj[i] = newObj[i];
}
}
return originalObj;
},
/**
* Returns parsed information about a URL
*
* @param {string} url URL to parse
* @returns {object}
*/
parseURL: function (url) {
var elem = document.createElement('a');
utils.insertBefore( elem, _div );
elem.href = url;
var data = {
protocol: elem.protocol,
hostname: elem.hostname,
port: elem.port,
pathname: elem.pathname,
search: elem.search,
hash: elem.hash,
host: elem.host
};
elem.parentNode.removeChild( elem );
return data;
},
/**
* Returns the document scroll offset
*
* @returns {object}
*/
getScrollOffset: function () {
var doc = document.documentElement;
return {
left: (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),
top: (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
};
},
/**
* Returns the offset relative to the document for an element
*
* @param {element} element Element to get the offset for
* @returns {object}
*/
getOffset: function (element) {
var p = {
left: element.offsetLeft || 0,
top: element.offsetTop || 0
};
while (element = element.offsetParent) {
p.left += element.offsetLeft;
p.top += element.offsetTop;
}
return p;
},
/**
* Returns the outer height of the element
*
* @returns {number}
*/
getObjHeight: function (elem) {
return elem.offsetHeight || 0;
},
/**
* Fade the element in
*
* @returns void
*/
fadeIn: function (elem) {
elem.style.opacity = 0;
var last = +new Date();
var tick = function() {
elem.style.opacity = +elem.style.opacity + (new Date() - last) / 400;
last = +new Date();
if( +elem.style.opacity < 1 ){
( window.requestAnimationFrame && requestAnimationFrame(tick) ) || setTimeout(tick, 16);
}
};
tick();
},
/**
* Returns the document height
*
* @returns {number}
*/
getDocHeight: function () {
var D = document;
return Math.max(
D.body.scrollHeight, D.documentElement.scrollHeight,
D.body.offsetHeight, D.documentElement.offsetHeight,
D.body.clientHeight, D.documentElement.clientHeight
);
},
/**
* Returns the viewport height
*
* @returns {number}
*/
getViewportHeight: function () {
return Math.max( document.documentElement.clientHeight, window.innerHeight || 0 );
},
/**
* Returns attributes for an element
*
* @param {element} element DOM element
* @returns {object}
*/
getAttributes: function (element) {
if( typeof element == 'undefined' ){
return;
}
var attributes = {};
if( element.hasAttributes() ){
var _attr = element.attributes;
for( var i = 0; i < _attr.length; i++ ){
attributes[ _attr[ i ].name.toLowerCase() ] = _attr[ i ].value;
}
}
return attributes;
},
/**
* A simple method to insert an element after another element
*
* @param {element} elem The new element
* @param {element} existing The existing element, after which the new will be inserted
* @returns {void}
*/
insertAfter: function (elem, existing) {
existing.parentNode.insertBefore( elem, existing.nextSibling );
},
/**
* A simple method to insert an element before another element
*
* @param {element} elem The new element
* @param {element} existing The existing element, before which the new will be inserted
* @returns {void}
*/
insertBefore: function (elem, existing) {
existing.parentNode.insertBefore( elem, existing );
},
/**
* Returns a style property value for the given element and style
*
* @param {element} elem Element whose style is to be fetched
* @param {string} style Property to fetch
* @returns {mixed}
*/
getStyle: function (elem, style) {
return window.getComputedStyle( elem, null ).getPropertyValue( style );
},
/*
* Cross-browser 'dom ready' event handler to init the page
*/
/*! contentloaded.min.js - https://github.com/dperini/ContentLoaded - Author: Diego Perini - License: MIT */
contentLoaded: function (b,i) {
var j=false,k=true,a=b.document,l=a.documentElement,f=a.addEventListener,h=f?'addEventListener':'attachEvent',n=f?'removeEventListener':'detachEvent',g=f?'':'on',c=function(d){if(d.type=='readystatechange'&&a.readyState!='complete')return;(d.type=='load'?b:a)[n](g+d.type,c,false);if(!j&&(j=true))i.call(b,d.type||d)},m=function(){try{l.doScroll('left')}catch(e){setTimeout(m,50);return}c('poll')};if(a.readyState=='complete')i.call(b,'lazy');else{if(!f&&l.doScroll){try{k=!b.frameElement}catch(e){}if(k)m()}a[h](g+'DOMContentLoaded',c,false);a[h](g+'readystatechange',c,false);b[h](g+'load',c,false)}
}
};
utils.contentLoaded( window, function () {
init();
});
})();
+12 -3
View File
@@ -2,9 +2,9 @@
/**
* @brief Return JS files
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 1 Aug 2013
* @version SVN_VERSION_NUMBER
*/
@@ -54,6 +54,10 @@ if ( \IPS\Request::i()->src )
$output .= file_get_contents( \IPS\ROOT_PATH . '/applications/' . $app . '/interface/' . implode( '/', $exploded ) ) . "\n\n\n\n";
}
}
elseif ( \IPS\IN_DEV && $exploded[0] == 'ckeditor' && $exploded[1] == 'ckeditor.js' )
{
$output .= file_get_contents( \IPS\ROOT_PATH . '/applications/core/dev/ckeditor/ckeditor.js' ) . "\n\n\n\n";
}
else
{
foreach ( \IPS\Output::i()->js( implode( '/', $exploded ), $app, $location ) as $url )
@@ -61,11 +65,16 @@ if ( \IPS\Request::i()->src )
/* If we are in_dev, ckeditor comes from the /dev/ directory instead */
if ( \IPS\IN_DEV && $exploded[0] == 'ckeditor' && $exploded[1] == 'ckeditor.js' )
{
$url = (string)\IPS\Http\Url::internal( "applications/core/dev/ckeditor/ckeditor.js", 'none' );
continue;
}
try
{
/* Make sure we have a protocol defined. \IPS\Http\Url::external() does not like protocol relative URL's */
if ( mb_substr( $url, 0, 2 ) == '//' )
{
$url = ( \IPS\Request::i()->isSecure() ) ? 'https:' . $url : 'http:' . $url;
}
$output .= loadResource( $url );
}
catch ( \Exception $e )
+2 -2
View File
@@ -2,9 +2,9 @@
/**
* @brief Return JS language strings
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/