diff --git a/e107_admin/header.php b/e107_admin/header.php
index 4010b70c7..3304b9f27 100644
--- a/e107_admin/header.php
+++ b/e107_admin/header.php
@@ -12,9 +12,9 @@
| GNU General Public License (http://gnu.org).
|
| $Source: /cvs_backup/e107_0.8/e107_admin/header.php,v $
-| $Revision: 1.17 $
-| $Date: 2008-08-11 20:45:01 $
-| $Author: e107steved $
+| $Revision: 1.18 $
+| $Date: 2008-11-09 20:31:10 $
+| $Author: secretr $
+---------------------------------------------------------------+
*/
@@ -140,9 +140,14 @@ if (varset($pref['wysiwyg'],FALSE) && check_class($pref['post_html']) && varset(
define("e_WYSIWYG",FALSE);
}
+// Load Javascript Libraries
+$hash = md5(serialize(varset($pref['e_jslib'])).serialize(varset($THEME_JSLIB)).THEME.e_LANGUAGE.ADMIN).'_admin';
+//echo "\n";
+echo "\n";
+
if (strpos(e_SELF.'?'.e_QUERY, 'menus.php?configure') === FALSE) {
- echo "\n";
- echo "\n";
+
+ //echo "\n";
}
if (file_exists(THEME.'theme.js')) { echo "\n"; }
if (is_readable(e_FILE.'user.js') && filesize(e_FILE.'user.js')) { echo "\n"; }
@@ -169,6 +174,23 @@ function savepreset(ps,pid){
\n";
}
+//iepngfix - IE6 only
+if((isset($pref['enable_png_image_fix']) && $pref['enable_png_image_fix'] == true) || (isset($sleight) && $sleight == true)) {
+ /*
+ * The only problem is that the browser is REALLY,
+ * REALLY slow when it has to render more elements
+ * try e.g. "div, img, td, input" (or just *) instead only img rule
+ * However I hope this will force IE6 user to hate it :)
+ */
+ echo "\n";
+}
+
if (function_exists('headerjs')){echo headerjs(); }
//
@@ -258,6 +280,20 @@ $body_onload = "";
//
// J: Send end of
and start of
//
+
+
+/*
+ * Fire Event e107:loaded
+ */
+echo "\n";
+
+
echo "
\n";
$sql->db_Mark_Time("End Head, Start Body");
diff --git a/e107_admin/userclass2.php b/e107_admin/userclass2.php
index e83526ff8..09498f60d 100644
--- a/e107_admin/userclass2.php
+++ b/e107_admin/userclass2.php
@@ -11,12 +11,23 @@
| GNU General Public License (http://gnu.org).
|
| $Source: /cvs_backup/e107_0.8/e107_admin/userclass2.php,v $
-| $Revision: 1.12 $
-| $Date: 2008-07-09 20:37:18 $
-| $Author: e107steved $
+| $Revision: 1.13 $
+| $Date: 2008-11-09 20:31:10 $
+| $Author: secretr $
+----------------------------------------------------------------------------+
*/
+//AJAX check
+if(isset($_REQUEST['ajax_used']))
+{
+ define('e_AJAX_REQUEST', true);
+ $E107['minimal'] = true;
+}
+else
+{
+ define('e_AJAX_REQUEST', false);
+}
+
require_once("../class2.php");
if (!getperms("4"))
{
@@ -25,7 +36,7 @@ if (!getperms("4"))
}
$e_sub_cat = 'userclass';
//define('UC_DEBUG_OPTS',FALSE);
-require_once("auth.php");
+
require_once(e_HANDLER."userclass_class.php"); // Modified class handler
$uclass = new e_userclass; // Class management functions - legacy stuff from 0.7
$e_userclass = new user_class_admin; // Admin functions - should just obliterate any previous object created in class2.php
@@ -33,26 +44,25 @@ $e_userclass = new user_class_admin; // Admin functions - should just obliter
$message = '';
-
-
-function check_allowed($class_id)
+function check_allowed($class_id, $redirect = true)
{
global $sql;
if (!$sql->db_Select('userclass_classes', '*', "userclass_id = {$class_id}"))
{
- header("location:".SITEURL);
+ if(!$redirect) return false;
+ header("location:".SITEURL);
exit;
}
$row = $sql->db_Fetch();
if (!getperms('0') && !check_class($row['userclass_editclass']))
{
+ if(!$redirect) return false;
header("location:".SITEURL);
exit;
}
+ return true;
}
-
-
if (e_QUERY)
{
$uc_qs = explode(".", e_QUERY);
@@ -60,8 +70,47 @@ if (e_QUERY)
$action = varset($uc_qs[0],'config');
$params = varset($uc_qs[1],'');
+if(e_AJAX_REQUEST)
+{
+ $class_num = varset($uc_qs[2],0);
+ if(!$class_num && isset($_POST['edit']))
+ {
+ $params = 'edit';
+ $class_num = varset($_POST['existing'],0);
+ }
+ if ($params == 'edit')
+ {
+ require_once(e_HANDLER.'js_helper.php');
+ $jshelper = new e_jshelper();
+ if(!check_allowed($class_num, false)) {
+ //This will raise an error
+ //'Access denied' is the message which will be thrown
+ //by the JS AJAX handler
+ e_jshelper::sendAjaxError('403', 'Access denied. Form update failed!');
+ }
+ $sql->db_Select('userclass_classes', '*', "userclass_id='".intval($class_num)."' ");
+ $row = $sql->db_Fetch(MYSQL_ASSOC);
+ unset($row['userclass_accum']);
+ $row['createclass'] = UCSLAN_14; //update the submit button value
+ $row['existing'] = $class_num; //required when user tree is clicked
+ //icon
+ $row['iconview'] = $row['userclass_icon'] ? e_IMAGE_ABS.'userclasses/'.$row['userclass_icon'] : e_IMAGE_ABS."generic/blank.gif";
+ $row["uc_icon_select"] = $row['userclass_icon']; //icons select box
+
+ //Send the prefered response type
+ //echo $jshelper->sendJSONResponse('fill-form', $row);
+ echo $jshelper->sendXMLResponse('fill-form', $row);
+ exit;
+ }
+}
+/*
+ * Authorization should be done a bit later!
+ * FIXME - should we call auth.php and header.php separate?
+ * Definitely yes if AJAX is in the game.
+ */
+require_once("auth.php");
//---------------------------------------------------
// Set Initial Classes
@@ -148,7 +197,7 @@ if (isset($_POST['updateclass']) || isset($_POST['createclass']))
$do_tree = FALSE;
- if (isset($_POST['updateclass']))
+ if (isset($_POST['createclass']) && $_POST['userclass_id'])
{
check_allowed($_POST['userclass_id']);
$class_record['userclass_id'] = intval($_POST['userclass_id']);
@@ -263,7 +312,7 @@ switch ($action)
$text .= "".UCSLAN_8.":";
$text .= "';
$text .= "
-
+
".UCSLAN_11."
@@ -361,12 +410,18 @@ switch ($action)
if($params == 'edit')
{
- $text .= "
- ";
+ $text .= "
+
+
+ ";
}
else
{
- $text .= "";
+ $text .= "
+ ";
}
$text .= "";
@@ -899,13 +954,50 @@ require_once("footer.php");
function headerjs()
{
- if (!e_QUERY) return '';
+ /*
+ * e107Ajax.fillForm demonstration
+ * Open Firebug console for Ajax transaction details
+ *
+ */
+ $script_js = "\n";
+ if (!e_QUERY) return $script_js;
$qs = explode('.',e_QUERY);
- if ($qs[0] != 'membs') return '';
-
+ if ($qs[0] != 'membs') return $script_js;
+
// We only want this JS on the class membership selection page
- $script_js = "
+
diff --git a/e107_files/jslib/core/debug.js b/e107_files/jslib/core/debug.js
new file mode 100644
index 000000000..73f4dd1c6
--- /dev/null
+++ b/e107_files/jslib/core/debug.js
@@ -0,0 +1,231 @@
+print_a = function(){
+ if(window.console)
+ $A(arguments).each( function(a) {console.log(a) });
+};
+
+var_dump = print_a;
+
+var e107Debug = {
+ init: function() {
+ //always on top!
+ this.debugE = new Element('div', { 'id': 'e-debug-console', 'style': 'z-index: 9991' } ).update(this._console_header);
+ this.cont = new Element('div', { 'id': 'e-debug-console-cont', 'style': 'z-index: 9990' } ).insert(this.debugE);
+ this.input = new Element('input', { 'id': 'e-debug-console-input', 'type': 'text' } );
+ this.controlC = new Element('a', { 'id': 'e-debug-console-controls-close', 'href': '#' } ).update(' X');
+ this.controlE = new Element('a', { 'id': 'e-debug-console-controls-eval', 'href': '#' } ).update(' Run ');
+ //var controlCC = new Element('div', { 'float': 'right' }).insert(this.controlC);
+ this.cont.insert( new Element('div', { 'id': 'e-debug-console-controls' }).update('>> ').insert(this.input).insert(this.controlE).insert(this.controlC) );
+
+
+ this.commands = new Array('');
+ this.clen = this.commands.length;
+ this.cindex = 0;
+
+ var C = this;
+ (function() {
+ C.controlC.observe('click', function(e) {
+ e.stop();
+ C.hide();
+ });
+
+ C.controlE.observe('click', function(e) {
+ e.stop();
+ C.evalInput(); C.setFocus();
+ });
+ C.input.observe('keydown', function(e) { //supported in all modern browsers
+ var keycode = e.keyCode;
+ var enterKey, escapeKey, keyUp, keyDown;
+ if (e.DOM_VK_RETURN) { // mozilla
+ enterKey = e.DOM_VK_RETURN;
+ escapeKey = e.DOM_VK_ESCAPE;
+ keyUp = e.DOM_VK_UP;
+ keyDown = e.DOM_VK_DOWN;
+ } else { // ie && friends
+ escapeKey = 27;
+ enterKey = 13;
+ keyUp = 38;
+ keyDown = 40;
+ }
+ switch (keycode) {
+ case enterKey:
+ C.evalInput();
+ break;
+ case keyUp:
+ C.chistory(-1);
+ break;
+ case keyDown:
+ C.chistory(1);
+ break;
+ case escapeKey:
+ C.input.value = ''; C.input.blur(); C.input.focus();
+ break;
+ }
+
+ });
+ //TODO - destroy method, console commands (e.g. \run -help), better key navigation (e.g. Ctrl + Shift + Key)
+ }).defer();
+
+ document.observe('dom:loaded', function() {
+ $(document.body).insert(this.cont.hide());
+ if(Prototype.Browser.IE6) this.iecenter();
+ else this.center();
+ }.bind(this));
+
+ this.keyboardNav = this.keyboardNav.bindAsEventListener(this);
+ this.re_center = this.center.bindAsEventListener(this);
+ this.re_iecenter = this.iecenter.bindAsEventListener(this);
+ this.startKeyboardNav();
+ },
+
+ show: function() {
+ if(!this.visible()) {
+ this.startPosObserve();
+ this._toggle();
+ }
+ },
+
+ hide: function() {
+ if(this.visible()) {
+ this.stopPosObserve();
+ this._toggle();
+ }
+ },
+
+ _toggle: function() {
+ var C = this;
+ Effect.toggle(this.cont, 'blind', {
+ duration: 0.4,
+ beforeStart: this.setFocus.bind(C),
+ afterFinish: this.setFocus.bind(C)
+ });
+ this.cindex = 0; //reset commands index
+ },
+
+ visible: function() {
+ return this.cont.visible();
+ },
+
+ center: function() {
+ var w = document.viewport.getWidth(), cw = this.cont.getWidth();
+ var pos = parseInt(w/2 - cw/2);
+ this.cont.setStyle({ 'left': pos + 'px'});
+
+ },
+
+
+ iecenter: function() {
+ var offset = document.body.scrollTop;
+ var w = document.body.clientWidth;
+ if(!this.cd) this.cd = this.cont.getWidth();
+ var left = parseInt(w/2 - this.cd/2);
+ if(left < 0) { //ie6 - sick of it
+ left = 0;
+ }
+ this.cont.setStyle( {
+ 'position': 'absolute',
+ 'top': offset + 'px',
+ 'left': left + 'px'
+ });
+ },
+
+ setFocus: function() {
+ if(this.visible()) { this.input.blur(); this.input.focus(); this.scrollDown(); }
+ else { this.input.value = ''; this.scrollDown(); this.input.blur(); }
+ },
+
+ scrollDown: function() {
+ this.debugE.scrollTop = this.debugE.scrollHeight;
+ },
+
+ log: function(d) {
+ this.show();
+ this.debugE.insert( new Element('div', { 'class': 'console-output' }).update(d) ); //TODO check the type
+ this.scrollDown();
+ },
+
+ syslog: function(msg, error) {
+ var logcol = '#333300';
+ if(error) logcol = '#cc3300';
+ this.log('>> ' + msg + '');
+ },
+
+ clearLog: function(d) {
+ this.debugE.update('');
+ },
+
+ evalInput: function() {
+ var src = this.input.value;
+ if(!src.length) return;
+
+ this.syslog(src);
+ this.input.value = '';
+ try {
+ var ret = eval.call(window, src);
+
+ if(ret) this.log(ret);
+ //setTimeout(src, 0); - Safari only! Not implemented anyway
+ this.clen = this.commands.push(src);
+ this.cindex = 0;
+ } catch(e) {
+ this.syslog(e, true);
+ this.clen = this.commands.push(src);
+ this.cindex = 0;
+ }
+ this.setFocus();
+ },
+
+ startKeyboardNav: function() {
+ document.observe('keydown', this.keyboardNav);
+ return this;
+ },
+
+
+ startPosObserve: function() {
+ if(Prototype.Browser.IE6) {
+ Event.observe(window,"resize", this.re_iecenter);
+ Event.observe(window,"scroll", this.re_iecenter);
+ return this;
+ }
+ Event.observe(window,"resize", this.re_center);
+ return this;
+ },
+
+ stopPosObserve: function() {
+ if(Prototype.Browser.IE6) {
+ Event.stopObserving(window,"scroll", this.re_iecenter);
+ Event.stopObserving(window,"resize", this.re_iecenter);
+ return this;
+ }
+ Event.stopObserving(window,"resize", this.re_center);
+ return this;
+ },
+
+ keyboardNav: function(event) {
+ //TODO - find out what kind of shortcuts are safe to be used (Ctrl + Alt + Shift brings me too much irritation)
+ var keycode = event.keyCode;
+ var key = String.fromCharCode(keycode).toLowerCase();
+ var isShifthPressed = event.shiftKey || (event.keyIdentifier && event.keyIdentifier.toLowerCase() == 'shift'); //ie & friends
+ var isCtrlPressed = event.ctrlKey || (event.keyIdentifier && event.keyIdentifier.toLowerCase() == 'control'); //ie & friends
+ var isAltPressed = event.altKey || (event.keyIdentifier && event.keyIdentifier.toLowerCase() == 'alt'); //ie & friends
+ if(isShifthPressed && isCtrlPressed && isAltPressed && key.match(/c|l/) /* && event.element() != this.input */ ) {
+ if(this.visible()) this.stopPosObserve()._toggle();
+ else this.startPosObserve()._toggle();
+ }
+ },
+
+ chistory: function(index) {
+ var ci = this.clen + this.cindex + index;
+ if(this.commands[ci] || ci === 0 || ci === this.clen) {
+ this.input.value = this.commands[ci] || '';
+ this.cindex += index;
+ }
+ },
+
+ _console_header: '--- e107 Debug Console v1.0.0: session started ---
'
+
+}
+
+e107Debug.init();
+echo = function() {
+ $A(arguments).each( function(a) { e107Debug.log(a) });
+}
\ No newline at end of file
diff --git a/e107_files/jslib/core/decorate.js b/e107_files/jslib/core/decorate.js
new file mode 100644
index 000000000..b9797d5a6
--- /dev/null
+++ b/e107_files/jslib/core/decorate.js
@@ -0,0 +1,147 @@
+/*
+ * DECORATE HTML ELEMENTS
+ * Inspired by Magento' decorate JS functions (www.magentocommerce.com)
+*/
+
+var e107Decorate = {
+
+ /**
+ * Decorate table rows and cells, tbody etc
+ * @see eDecorate()
+ */
+ table: function(table) {
+ var table = $(table);
+ if (!table) return;
+
+ //default options
+ this._options = {
+ 'tbody': false,
+ 'tbody tr': 'odd,even,first,last',
+ 'thead tr': 'first,last',
+ 'tfoot tr': 'first,last',
+ 'tr td': 'last'
+ };
+
+ // overload options
+ Object.extend(this._options, (arguments[1] || {}));
+
+ // decorate
+ if (this._options['tbody']) {
+ this._decorate(table.select('tbody'), this._options['tbody']);
+ }
+ if (this._options['tbody_tr']) {
+ this._decorate(table.select('tbody tr'), this._options['tbody tr']);
+ }
+ if (this._options['thead_tr']) {
+ this._decorate(table.select('thead tr'), this._options['thead tr']);
+ }
+ if (this._options['tfoot_tr']) {
+ this._decorate(table.select('tfoot tr'), this._options['tfoot tr']);
+ }
+ if (this._options['tr_td']) {
+ table.select('tr').each( function(tr) {
+ this._decorate(tr.select('td'), this._options['tr td']);
+ }.bind(this));
+ }
+ },
+
+ /**
+ * Decorate list (ul)
+ * Default decorate CSS classes for list items are "odd", "even" and "last"
+ *
+ * Examples:
+ * eDecorateList('mylist'); //default decorate options over element with id 'mylist'
+ * eDecorateList('mylist', 'odd,even'); //decorate options odd and even only over element with id 'mylist'
+ *
+ * @param list - id/DOM object of list element (ul) to be decorated
+ * [@param options] - string|array decorate options - @see eDecorate()
+ * [@param recursive] - boolean decorate all childs if present
+ */
+ list: function(list) {
+ list = $(list);
+ if (list) {
+ if (typeof(arguments[2]) == 'undefined') {
+ var items = list.select('li')
+ } else {
+ var items = list.childElements();
+ }
+ this._decorate(items, (arguments[1] || 'odd,even,last'));
+ }
+ },
+
+ /**
+ * Set "odd", "even" and "last" CSS classes for list items
+ *
+ * Examples:
+ * eDecorateDataList('mydatalist'); //default decorate options over element with id 'mydatalist'
+ * eDecorateDataList('mydatalist', 'odd,even'); //decorate options odd and even for dt elements, default for dd elements
+ *
+ * [@param dt_options] - string|array dt element decorate options - @see eDecorate()
+ * [@param dd_options] - string|array dd element decorate options - @see eDecorate()
+ */
+ dataList: function(list) {
+ list = $(list);
+ if (list) {
+ this._decorate(list.select('dt'), (arguments[1] || 'odd,even,last'));
+ this._decorate(list.select('dd'), (arguments[2] || 'odd,even,last'));
+ }
+ },
+
+ /**
+ * Add classes to specified elements.
+ * Supported classes are: 'odd', 'even', 'first', 'last'
+ *
+ * @param elements - array of elements to be decorated
+ * [@param decorateParams] - array of classes to be set. If omitted or empty, all available will be used
+ */
+ _decorate: function(elements) {
+ var decorateAllParams = ['odd', 'even', 'first', 'last'];
+ this.decorateParams = [];
+ this.params = {};
+
+ if (!elements.length) return;
+
+ if(!varset(arguments[1])) {
+ this.decorateParams = decorateAllParams;
+ } else if(typeof(arguments[1]) == 'string') {
+ this.decorateParams = arguments[1].replace(/[\s]/, '').split(',');
+ } else {
+ this.decorateParams = arguments[1];
+ }
+
+ decorateAllParams.each( function(v) {
+ this.params[v] = this.decorateParams.include(v);
+ }.bind(this));
+
+ // decorate first
+ if(this.params.first) {
+ Element.addClassName(elements[0], 'first');
+ }
+ // decorate last
+ if(this.params.last) {
+ Element.addClassName(elements[elements.length-1], 'last');
+ }
+
+ if(!this.params.even && !this.params.odd) {
+ return;
+ }
+ //elements.select(_eDecorateIsEven).invoke('addClassName', 'even');
+ var selections = elements.partition(this._isEven);
+ // decorate even
+ if(this.params.even) {
+ selections[0].invoke('addClassName', 'even');
+ }
+ if(this.params.odd) {
+ selections[1].invoke('addClassName', 'odd');
+ }
+ },
+
+ /**
+ * Select/Reject/Partition callback function
+ *
+ * @see eDecorate()
+ */
+ _isEven: function(dummy, i) {
+ return ((i+1) % 2 == 0);
+ }
+}
\ No newline at end of file
diff --git a/e107_files/jslib/e107.js.php b/e107_files/jslib/e107.js.php
new file mode 100644
index 000000000..e342bf9d3
--- /dev/null
+++ b/e107_files/jslib/e107.js.php
@@ -0,0 +1,2380 @@
+/*
+ * Old stuff
+ * FIXME ASAP
+ */
+
+var nowLocal = new Date(); /* time at very beginning of js execution */
+var localTime = Math.floor(nowLocal.getTime()/1000); /* time, in ms -- recorded at top of jscript */
+/* NOTE: if serverDelta is needed for js functions, you must pull it from
+ * the cookie (as calculated during a previous page load!)
+ * The value calculated in SyncWithServerTime is not known until after the
+ * entire page has been processed.
+ */
+function SyncWithServerTime(serverTime)
+{
+ if (serverTime)
+ {
+ /* update time difference cookie */
+ var serverDelta=Math.floor(localTime-serverTime);
+ document.cookie = 'e107_tdOffset='+serverDelta+'; path=/';
+ document.cookie = 'e107_tdSetTime='+(localTime-serverDelta)+'; path=/'; /* server time when set */
+ }
+
+ var tzCookie = 'e107_tzOffset=';
+// if (document.cookie.indexOf(tzCookie) < 0) {
+ /* set if not already set */
+ var timezoneOffset = nowLocal.getTimezoneOffset(); /* client-to-GMT in minutes */
+ document.cookie = tzCookie + timezoneOffset+'; path=/';
+// }
+}
+
+// -------------------------------------------------------------------
+
+/**
+ * Prototype Xtensions
+ * @author Simon Martins
+ * @copyright (c) 2008 Netatoo SARL
+ * @license MIT License
+ *
+ * @desc Used to retrieve the browser version
+ */
+(function() {
+ var nav = navigator;
+ var userAgent = ua = navigator.userAgent;
+ var v = nav.appVersion;
+ var version = parseFloat(v);
+
+ Prototype.Browser = {
+ IE : (Prototype.Browser.IE) ? parseFloat(v.split("MSIE ")[1]) || 0 : 0,
+ Firefox : (Prototype.Browser.Gecko) ? parseFloat(ua.split("Firefox/")[1]) || 0 : 0,
+ Camino : (Prototype.Browser.Gecko) ? parseFloat(ua.split("Camino/")[1]) || 0 : 0,
+ Flock : (Prototype.Browser.Gecko) ? parseFloat(ua.split("Flock/")[1]) || 0 : 0,
+ Opera : (Prototype.Browser.Opera) ? version : 0,
+ AIR : (ua.indexOf("AdobeAIR") >= 0) ? 1 : 0,
+ Mozilla : (Prototype.Browser.Gecko || !this.Khtml) ? version : 0,
+ Khtml : (v.indexOf("Konqueror") >= 0 && this.safari) ? version : 0,
+ Safari : (function() {
+ var safari = Math.max(v.indexOf("WebKit"), v.indexOf("Safari"), 0);
+ return (safari) ? (
+ parseFloat(v.split("Version/")[1]) || ( ( parseFloat(v.substr(safari+7)) >= 419.3 ) ? 3 : 2 ) || 2
+ ) : 0;
+ })()
+ };
+})();
+
+// -------------------------------------------------------------------
+
+/**
+ * Main registry object
+ */
+var e107Registry = {
+
+ //System Path
+ Path: {
+ e_IMAGE: '',
+ e_IMAGE_PACK: '',
+ e_PLUGIN: '',
+ e_FILE: '',
+
+ e_THEME: '',
+ THEME: ''
+ },
+
+ //Language Constants
+ Lan: {},
+
+ //Global Templates
+ Template: {
+ Core: {
+ //e107Helper#duplicateHTML method
+ //TODO CSS - icon , icon.d16, icon.d32, icon.d64, top, middle, bottom definitions
+ duplicateHTML: '' +
+ '#{duplicateBody}' +
+ '

' +
+ '
'
+ },
+
+ //e107Helper#LoadingStatus class
+ CoreLoading: {
+ template: '' +
+ '
' +
+ '
' +
+ '
#{JSLAN_CORE_LOADING_TEXT}' +
+ '
' +
+ '
'
+ }
+ },
+
+ //Cache
+ Cache: new Hash,
+
+ //Cached vars
+ CachedVars: new Hash,
+
+ //Global Preferences
+ Pref: {
+
+ Core: {
+ zIndex: 100 //base system z-index
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+
+/**
+ * Global helpers - server side clonings
+ */
+var isset = function(varname) {
+ return !Object.isUndefined(varname);
+}
+
+var varset = function(varname) {
+ if(Object.isUndefined(varname)) {
+ return (Object.isUndefined(arguments[1]) ? null : arguments[1]);
+ }
+ return varname;
+}
+
+var varsettrue = function(varname) {
+ if(Object.isUndefined(varname) || !varname) {
+ return (Object.isUndefined(arguments[1]) ? null : arguments[1]);
+ }
+ return varname;
+}
+
+var cachevars = function(varname, data) {
+ e107Registry.CachedVars.set(data)
+}
+
+var getcachedvars = function(varname, destroy) {
+ if(destroy)
+ return clearcachedvars(varname);
+ return e107Registry.CachedVars.get(varname);
+}
+
+var clearcachedvars = function(varname) {
+ return e107Registry.CachedVars.unset(varname);
+}
+
+var echo = Prototype.emptyFunction, print_a = Prototype.emptyFunction, var_dump = Prototype.emptyFunction;
+
+// -------------------------------------------------------------------
+
+
+/**
+ * e107 custom events
+ */
+var e107Event = {
+
+ fire: function(eventName, memo, element) {
+ element = $(element) || document;
+ memo = memo || {};
+ return element.fire('e107:' + eventName, memo);
+ },
+
+ observe: function(eventName, handler, element) {
+ element = $(element) || document;
+ element.observe('e107:' + eventName, handler);
+ return this;
+ },
+
+ stopObserving: function(eventName, handler, element) {
+ element = $(element) || document;
+ element.stopObserving('e107:' + eventName, handler);
+ return this;
+ },
+
+ //Server side - e107_event aliases
+ trigger: function(eventName, memo, element) {
+ this.fire(eventName, memo, element);
+ },
+
+ register: function(eventName, handler, element) {
+ this.observe(eventName, handler, element);
+ },
+
+ unregister: function(eventName, handler, element) {
+ this.stopObserving(eventName, handler, element);
+ }
+}
+
+
+
+/**
+ * EventManager
+ * Prototype Xtensions http://www.prototypextensions.com
+ *
+ * @desc Easly event manager for creating custom event on your own class
+ */
+var e107EventManager = Class.create({
+
+ /**
+ * Initialize
+ *
+ * @desc Set scope and events hash
+ */
+ initialize: function(scope) {
+ this.scope = scope;
+ this.events = new Hash();
+ },
+
+ /**
+ * addListener
+ *
+ * @desc Add event observer
+ */
+ addObserver: function(name) {
+ return this.events.set(name, new Hash());
+ },
+
+ /**
+ * observe
+ *
+ * @desc Add an callback for listener 'name'
+ */
+ observe: function(name, callback) {
+ var observers = this.events.get(name);
+
+ if(!observers) observers = this.addObserver(name);
+
+ if(!Object.isFunction(callback)) {
+ throw('e107EventManager.observe : callback must be an js function');
+ }
+
+ var i = this.events.get(name).keys().length;
+ observers.set(i, callback.bind(this.scope));
+
+ return this;
+ },
+
+ /**
+ * notify
+ *
+ * @desc Launch all callbacks for listener 'name'
+ */
+ notify: function(name) {
+ var observers = this.events.get(name);
+
+ if(observers) {
+ var args = $A(arguments).slice(1);
+ observers.each(function(callback) {
+ if(Object.isFunction(callback[1])) {
+ callback[1].apply(this.scope, args);
+ }
+ });
+ }
+
+ return this;
+ }
+
+});
+
+// -------------------------------------------------------------------
+
+
+/**
+ * Base e107 Object - interacts with the registry object
+ */
+var e107Base = {
+
+ setPath: function(path_object) {
+ e107Registry.Path = Object.extend( this.getPathVars(), path_object || {});
+ return this;
+ },
+
+ addPath: function(path_var, path) {
+ //don't allow overwrite
+ if(!e107Registry.Path[path_var]) e107Registry.Path[path_var] = path;
+ return this;
+ },
+
+ getPathVars: function() {
+ return e107Registry.Path;
+ },
+
+ getPath: function(path_name) {
+ return varset(e107Registry.Path[path_name]);
+ },
+
+ _addLan: function(lan_name, lan_value) {
+ e107Registry.Lan[lan_name] = lan_value;
+ return this;
+ },
+
+ _getLan: function(lan_name) {
+ return varsettrue(e107Registry.Lan[lan_name], lan_name);
+ },
+
+ setLan: function(lan_object) {
+ if(!arguments[1]) {
+ Object.keys(lan_object).each(function(key) {
+ this.addLan(key, lan_object[key]);
+ }, this);
+ return this
+ }
+ Object.extend(e107Registry.Lan, (lan_object || {}));
+ return this;
+ },
+
+ addLan: function(lan_name, lan_value) {
+ this._addLan(this.toLanName(lan_name), lan_value);
+ return this;
+ },
+
+ setModLan: function(mod, lan_object) {
+ Object.keys(lan_object).each( function(key) {
+ this.addModLan(mod, key, lan_object[key]);
+ }, this);
+ return this;
+ },
+
+ addModLan: function(mod, lan_name, lan_value) {
+ return this._addLan(this.toModLanName(mod, lan_name), lan_value);
+ },
+
+ getLan: function(lan_name) {
+ return this._getLan(this.toLanName(lan_name));
+ },
+
+ getModLan: function(mod, lan_name) {
+ return this._getLan(this.toModLanName(mod, lan_name));
+ },
+
+ getLanVars: function() {
+ return e107Registry.Lan;
+ },
+
+ getModLanVars: function(mod) {
+ return this.getLanFilter(this.toModLanName(mod));
+ },
+
+ //Example e107.getLanRange('lan1 lan2 ...'); -- { LAN1: 'lan value1', LAN2: 'lan value2', ... }
+ getLanRange: function(lan_keys) {
+ var ret = {};
+ $w(lan_keys).each( function(key) {
+ this[key.toUpperCase()] = e107.getLan(key);
+ }, ret);
+ return ret;
+ },
+
+ //Example e107.getLanFilter('lan_myplug'); -- { LAN_MYPLUG_1: 'lan value1', LAN_MYPLUG_2: 'lan value2', ... }
+ getLanFilter: function(filter) {
+ var ret = {};
+ filter = filter.toUpperCase();
+ $H(e107Registry.Lan).keys().each( function(key) {
+ if(key.startsWith(filter)) {
+ this[key] = e107Registry.Lan[key];
+ }
+ }, ret);
+
+ return ret;
+ },
+
+ setTemplate: function(mod, tmpl_object) {
+ mod = this.toModName(mod);
+ if(!varset(e107Registry.Template[mod])) {
+ e107Registry.Template[mod] = {};
+ }
+ Object.extend(e107Registry.Template[mod], (tmpl_object || {}));
+
+ return this;
+ },
+
+ addTemplate: function(mod, name, tmpl_string) {
+ mod = this.toModName(mod);
+ if(!varset(e107Registry.Template[mod])) {
+ e107Registry.Template[mod] = {};
+ }
+ e107Registry.Template[mod][name] = tmpl_string;
+
+ return this;
+ },
+
+ getTemplates: function(mod) {
+ return varsettrue(e107Registry.Template[this.toModName(mod)], {});
+ },
+
+ getTemplate: function(mod, name) {
+ mod = this.toModName(mod);
+
+ if(varset(e107Registry.Template[mod])) {
+ return varsettrue(e107Registry.Template[mod][name], '');
+ }
+
+ return '';
+ },
+
+ setPref: function(mod, pref_object) {
+ mod = this.toModName(mod);
+ if(!varset(e107Registry.Pref[mod])) {
+ e107Registry.Pref[mod] = {};
+ }
+ Object.extend(e107Registry.Pref[mod] || {}, (pref_object || {}));
+
+ return this;
+ },
+
+ addPref: function(mod, pref_name, pref_value) {
+ mod = this.toModName(mod);
+ if(!varset(e107Registry.Pref[mod])) {
+ e107Registry.Pref[mod] = {};
+ }
+ e107Registry.Pref[mod][pref_name] = pref_value;
+
+ return this;
+ },
+
+ getPrefs: function(mod) {
+ return varsettrue(e107Registry.Pref[this.toModName(mod)], {});
+ },
+
+ getPref: function(mod, pref_name, def) {
+ mod = this.toModName(mod);
+ if(varset(e107Registry.Pref[mod])) {
+ return varsettrue(e107Registry.Pref[mod][pref_name], varset(def, null));
+ }
+ return varset(def, null);
+ },
+
+ setCache: function(cache_str, cache_item) {
+ this.clearCache(cache_str);
+ e107Registry.Cache.set(cache_str, cache_item);
+ return this;
+ },
+
+ getCache: function(cache_str, def) {
+ return varset(e107Registry.Cache.get(cache_str), def);
+ },
+
+ clearCache: function(cache_str, def) {
+ var cached = this.getCache(cache_str);
+ if(null !== cached) {
+ if(cached.destroy) {
+ cached.destroy();
+ }
+ }
+ return varset(e107Registry.Cache.unset(cache_str), def);
+ },
+
+ parseTemplate: function(mod, name, data) {
+ var cacheStr = mod + '_' + name;
+ var cached = this.getCache(cacheStr);
+ if(null === cached) {
+ var tmp = this.getTemplate(mod, name);
+ cached = new Template(tmp);
+ this.setCache(cacheStr, cached);
+ }
+
+ if(varsettrue(arguments[3])) {
+ data = this.getParseData(Object.clone(data || {}));
+ }
+
+ try{
+ return cached.evaluate(data || {});
+ } catch(e) {
+ return '';
+ }
+ },
+
+ getParseData: function (data) {
+ Object.extend(data || {},
+ Object.extend(this.getLanVars(), this.getPathVars())
+ );
+
+ return data;
+ },
+
+ parseLan: function(str) {
+ return String(str).interpolate(this.getLanVars());
+ },
+
+ parsePath: function(str) {
+ return String(str).interpolate(this.getPathVars());
+ },
+
+ toModName: function(mod, raw) {
+ return raw ? mod.dasherize() : mod.dasherize().camelize().ucfirst();
+ },
+
+ toLanName: function(lan) {
+ return 'JSLAN_' + lan.underscore().toUpperCase();
+ },
+
+ toModLanName: function(raw_mod, lan) {
+ return this.toLanName(raw_mod + '_' + varset(lan, ''));
+ }
+};
+
+// -------------------------------------------------------------------
+
+/**
+ * String Extensions
+ *
+ * Methods used later in the core + e107base shorthands
+ */
+Object.extend(String.prototype, {
+
+ //php like
+ ucfirst: function() {
+ return this.charAt(0).toUpperCase() + this.substring(1);
+ },
+
+ //Create element from string - Prototype UI
+ createElement: function() {
+ var wrapper = new Element('div'); wrapper.innerHTML = this;
+ return wrapper.down();
+ },
+
+ parseToElement: function(data) {
+ return this.parseTemplate(data).createElement();
+ },
+
+ parseTemplate: function(data) {
+ return this.interpolate(e107Base.getParseData(data || {}));
+ },
+
+ parsePath: function() {
+ return e107Base.parsePath(this);
+ },
+
+ parseLan: function() {
+ return e107Base.parseLan(this);
+ },
+
+ addLan: function(lan_name) {
+ if(lan_name)
+ e107Base.addLan(lan_name, this);
+ return e107Base.toLanName(lan_name);
+ },
+
+ addModLan: function(mod, lan_name) {
+ if(mod && lan_name)
+ e107Base.addModLan(mod, lan_name, this);
+ return e107Base.toModLanName(mod, lan_name);
+ },
+
+ getLan: function() {
+ return e107Base.getLan(this);
+ },
+
+ getModLan: function(mod) {
+ if(mod)
+ return e107Base.getModLan(mod, this);
+ return this;
+ }
+});
+
+// -------------------------------------------------------------------
+
+/**
+ * e107WidgetAbstract Class
+ */
+var e107WidgetAbstract = Class.create({
+
+ initMod: function(modId, options, inherit) {
+
+ this.mod = e107Base.toModName(modId, true);
+ if(!this.mod) {
+ throw 'Illegal Mod ID';
+ }
+
+ var methods = 'setTemplate addTemplate getTemplate parseTemplate setPref addPref getPref getPrefs getLan getLanVars addLan setLan';
+ var that = this;
+
+ //Some magic
+ $w(methods).each(function(method){
+ var mod_method = method.gsub(/^(set|get|add|parse)(.*)$/, function(match){
+ return match[1] + 'Mod' + match[2];
+ });
+ var parent_method = !e107Base[mod_method] ? method : mod_method;
+ this[mod_method] = e107Base[parent_method].bind(e107Base, this.mod);
+ //console.log(mod_method, parent_method);
+ }.bind(that));
+
+ Object.extend(that, {
+ getModName: function(raw) {
+ return raw ? this.mod : e107Base.toModName(this.mod);
+ },
+
+ parseModLan: function(str) {
+ return String(str).interpolate(e107Base.getModLan(this.mod));
+ },
+
+ setModCache: function(cache_str, cache_item) {
+ return e107Base.setCache(this.getModName(true) + cache_str, cache_item);
+ },
+
+ getModCache: function(cache_str) {
+ return e107Base.getCache(this.getModName(true) + cache_str);
+ },
+
+ clearModCache: function(cache_str) {
+ return e107Base.clearCache(this.getModName(true) + cache_str);
+ }
+ });
+
+ //Merge option object (recursive)
+ this.setOptions(options, inherit);
+ },
+
+
+ setOptions: function(options, inherit) {
+ this.options = {};
+
+ var c = this.constructor;
+
+ if (c.superclass && inherit) {
+ var chain = [], klass = c;
+
+ while (klass = klass.superclass)
+ chain.push(klass);
+
+ chain = chain.reverse();
+ for (var i = 0, len = chain.length; i < len; i++) {
+ if(!chain[i].getModPrefs) chain[i].getModPrefs = Prototype.emptyFunction;
+ //global options if available
+ Object.extend(this.options, chain[i].getModPrefs() || {});
+ }
+ }
+
+ //global options if available
+ if(!this.getModPrefs) { this.getModPrefs = Prototype.emptyFunction; }
+
+ Object.extend(this.options, this.getModPrefs() || {});
+ return Object.extend(this.options, options || {});
+ }
+
+});
+
+// -------------------------------------------------------------------
+
+/**
+ * Core - everything's widget!
+ */
+var e107Core = Class.create(e107WidgetAbstract, {
+ initialize: function() {
+ this.initMod('core');
+ },
+
+ /**
+ * e107:loaded Event observer
+ */
+ runOnLoad: function(handler, element, reload) {
+ e107Event.register('loaded', handler, element || document);
+ if(reload)
+ this.runOnReload(handler, element);
+
+ return this;
+ },
+
+ /**
+ * Ajax after update Event observer
+ */
+ runOnReload: function(handler, element) {
+ e107Event.register('ajax_update_after', handler, element || document);
+ return this;
+ }
+
+});
+
+//e107Core instance
+var e107 = new e107Core();
+
+// -------------------------------------------------------------------
+
+/*
+ * Widgets namespace
+ * @descr should contain only high-level classes
+ */
+ var e107Widgets = {};
+
+/**
+ * Utils namespace
+ * @descr contains low-level classes and non-widget high-level classes/objects
+ */
+var e107Utils = {}
+
+/**
+ * Helper namespace
+ * @descr includes all old e107 functions + some new helper methods/classes
+ */
+var e107Helper = {
+ fxToggle: function(el, fx) {
+ var opt = Object.extend( { effect: 'blind' , options: {duration: 0.5} }, fx || {})
+ Effect.toggle(el, opt.effect, opt.options);
+ }
+}
+
+// -------------------------------------------------------------------
+
+/*
+ * Element extension
+ */
+Element.addMethods( {
+ fxToggle: function(element, options) {
+ e107Helper.fxToggle(element, options);
+ }
+});
+
+// -------------------------------------------------------------------
+
+/**
+ * Backward compatibility
+ */
+Object.extend(e107Helper, {
+
+ toggle: function(el) {
+ var eltoggle;
+ /**
+ * (SecretR) Notice
+ *
+ * Logic mismatch!
+ * Passed element/string should be always the target element (which will be toggled)
+ * OR
+ * anchor: where 'some-id' is the id of the target element
+ * This method will be rewritten after the core is cleaned up. After this point
+ * the target element will be auto-hidden (no need of class="e-hideme")
+ */
+ if(Object.isElement(el) && ($(el).readAttribute('href')) || $(el).nodeName.toLowerCase() == 'a' || $(el).readAttribute('type').toLowerCase() == 'input') {
+ eltoggle = (function(el) {
+ return Try.these(
+ function() { var ret= $(el.readAttribute('href').match(/#(\w.+)$/)[1]); if(ret) { return ret; } throw 'Error';}, //This will be the only valid case in the near future
+ function() { var ret=el.next('.e-expandme'); if(ret) { return ret; } throw 'Error';},
+ function() { var ret=el.next('div'); if(ret) { return ret; } throw 'Error'; }, //backward compatibality - DEPRECATED
+ function() { return null; } //break
+ ) || false;
+ })($(el));
+ } else {
+ var eltoggle = $(el);
+ }
+
+ if(!eltoggle) return;
+
+ var fx = varset(arguments[1], null);
+
+ if(null !== fx)
+ this.fxToggle(eltoggle, fx || {});
+ else
+ $(eltoggle).toggle();
+ },
+
+ /**
+ * added as Element method below
+ * No toggle effects!
+ */
+ downToggle: function(element, selector) {
+ $(element).select(varsettrue(selector, '.e-expandme')).invoke('toggle');
+ return element;
+ },
+
+ /**
+ * Event listener - e107:loaded|e107:ajax_update_after
+ * @see e107Core#addOnLoad
+ */
+ toggleObserver: function(event) {
+ var expandthem = event.memo.element ? $(event.memo.element) : $$('body')[0];
+ expandthem.select('.e-expandit').invoke('observe', 'click', function(e) {
+ var relval = e.element().getAttribute('rel') ? '{' + String(e.element().getAttribute('rel').toJSON()) + '}' : '{}';
+ e.stop();
+ //security - evalJSON(true)
+ this.toggle(e.element(), relval.evalJSON(true) || {});
+ }.bindAsEventListener(e107Helper));
+ },
+
+ /**
+ * Add fx scroll on click event
+ * on all document.body.offsetHeight){ // all but Explorer Mac
+ xScroll = document.body.scrollWidth;
+ yScroll = document.body.scrollHeight;
+ } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
+ xScroll = document.body.offsetWidth;
+ yScroll = document.body.offsetHeight;
+ }
+
+ var windowWidth, windowHeight;
+
+ if (self.innerHeight) { // all except Explorer
+ if(document.documentElement.clientWidth){
+ windowWidth = document.documentElement.clientWidth;
+ } else {
+ windowWidth = self.innerWidth;
+ }
+ windowHeight = self.innerHeight;
+ } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+ windowWidth = document.documentElement.clientWidth;
+ windowHeight = document.documentElement.clientHeight;
+ } else if (document.body) { // other Explorers
+ windowWidth = document.body.clientWidth;
+ windowHeight = document.body.clientHeight;
+ }
+
+ // for small pages with total height less then height of the viewport
+ if(yScroll < windowHeight){
+ pageHeight = windowHeight;
+ } else {
+ pageHeight = yScroll;
+ }
+
+ // for small pages with total width less then width of the viewport
+ if(xScroll < windowWidth){
+ pageWidth = xScroll;
+ } else {
+ pageWidth = windowWidth;
+ }
+
+ return [pageWidth,pageHeight];
+ }
+});
+
+
+// -------------------------------------------------------------------
+
+/*
+ * Element extensions
+ */
+Element.addMethods( {
+ downNoHistory: e107Helper.downNoHistory,
+ downHide: e107Helper.downHide,
+ downShow: e107Helper.downShow,
+ downToggle: e107Helper.downToggle,
+ downExternalLinks: e107Helper.downExternalLinks
+});
+
+Element.addMethods('INPUT', {
+ noHistory: e107Helper.noHistory
+});
+
+Element.addMethods('A', {
+ externalLink: e107Helper.externalLink
+});
+
+// -------------------------------------------------------------------
+
+/**
+ * e107BB helper
+ */
+e107Helper.BB = {
+
+ __selectedInputArea: null,
+
+ store: function(textAr){
+ this.__selectedInputArea = $(textAr);
+ },
+
+ /**
+ * New improved version - fixed scroll to top behaviour when inserting BBcodes
+ * @TODO - improve it further
+ */
+ insert: function(text, emote) {
+ if (!this.__selectedInputArea) {
+ return; //[SecretR] TODO - alert the user
+ }
+ var eField = this.__selectedInputArea, tags = this.parse(text, emote);
+ if(this.insertIE(eField, text, tags)) return;
+
+ var scrollPos = eField.scrollTop, sel = (eField.value).substring(eField.selectionStart, eField.selectionEnd);
+ if (eField.selectionEnd <= 2 && typeof(eField.textLength) != 'undefined') {
+ eField.selectionEnd = eField.textLength;
+ }
+
+ var newStart = eField.selectionStart + tags.start.length + sel.length + tags.end.length;
+ eField.value = (eField.value).substring(0, eField.selectionStart) + tags.start + sel + tags.end + (eField.value).substring(eField.selectionEnd, eField.textLength);
+
+ eField.focus(); eField.selectionStart = newStart; eField.selectionEnd = newStart; eField.scrollTop = scrollPos;
+ return;
+
+ },
+
+ insertIE: function(area, text, tags) {
+ // IE fix
+ if (!document.selection) return false;
+ var eSelection = document.selection.createRange().text;
+ area.focus();
+ if (eSelection) {
+ document.selection.createRange().text = tags.start + eSelection + tags.end;
+ } else {
+ document.selection.createRange().text = tags.start + tags.end;
+ }
+ eSelection = ''; area.blur(); area.focus();
+ return true;
+ },
+
+ parse: function(text, isEmote) {
+ var tOpen = text, tClose = '';
+ if (isEmote != true) { // Split if its a paired bbcode
+ var tmp = text.split('][', 2);
+ tOpen = varset(tmp[1]) ? tmp[0] + ']' : text;
+ tClose = varset(tmp[1]) ? '[' + tmp[1] : '';
+ }
+ return { start: tOpen, end: tClose };
+ },
+
+ //TODO VERY BAD - make it right ASAP!
+ help_old: function(help, tagid, nohtml){
+ if(nohtml) { help = help.escapeHTML(); }
+ if($(tagid)) { $(tagid).value = help; }
+ else if(varset(helpb)) {
+ $('dataform').helpb.value = help;
+ }
+ },
+
+ //FIXME - The new BB help system
+ help: function(help, tagid, nohtml){
+ if(nohtml) { help = help.escapeHTML(); }
+ if(!$(tagid)) return;
+ if(help) {
+ var wrapper = new Element('div', {'style': 'position: absolute'}).update(help);
+ $(tagid).update(wrapper).fxToggle();//TODO - fx
+ } else {
+ $(tagid).update('').fxToggle();//TODO - fx
+ }
+ }
+};
+
+//Iframe Shim - from PrototypeUI
+e107Utils.IframeShim = Class.create({
+ initialize: function() {
+ this.element = new Element('iframe',{
+ style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none;',
+ src: 'javascript:void(0);',
+ frameborder: 0
+ });
+ $(document.body).insert(this.element);
+ },
+ hide: function() {
+ this.element.hide();
+ return this;
+ },
+ show: function() {
+ this.element.show();
+ return this;
+ },
+ positionUnder: function(element) {
+ var element = $(element);
+ var offset = element.cumulativeOffset();
+ var dimensions = element.getDimensions();
+
+ this.element.setStyle({
+ left: offset[0] + 'px',
+ top: offset[1] + 'px',
+ width: dimensions.width + 'px',
+ height: dimensions.height + 'px',
+ zIndex: element.getStyle('zIndex') - 1
+ }).show();
+
+ return this;
+ },
+ setBounds: function(bounds) {
+ for(prop in bounds)
+ bounds[prop] += 'px';
+ this.element.setStyle(bounds);
+ return this;
+ },
+ destroy: function() {
+ if(this.element)
+ this.element.remove();
+ return this;
+ }
+});
+
+// -------------------------------------------------------------------
+
+/**
+ * Show Page/Element loading status (during AJAX call)
+ *
+ * @class e107Utils.LoadingStatus
+ * @widget: core-loading
+ * @version 1.0
+ * @author SecretR
+ * @extends e107WidgetAbstract
+ * @template: 'template'
+ * @cache_string: 'instance-loading-status'
+ */
+
+
+('Loading') .addModLan('core-loading', 'alt');
+('Loading, please wait...').addModLan('core-loading', 'text');
+
+e107Utils.LoadingStatus = Class.create(e107WidgetAbstract, {
+
+ initialize: function(dest_element, options) {
+ this.initMod('core-loading', options);
+ this.cacheStr = 'instance-loading-status';
+
+ this.loading_mask_loader = false;
+ this.loading_mask = $('loading-mask');
+ this.iframeShim = this.getModCache(this.cacheStr + '-iframe');
+ this.destElement = ($(dest_element) || $$('body')[0]);
+
+ //this.addModLan('loading_text', 'Loading, please wait...').addModLan('loading_alt', 'Loading');
+ this.re_center = this.recenter.bindAsEventListener(this);
+
+ this.create();
+ if(this.options.show_auto)
+ this.show();
+ },
+
+ startObserving: function() {
+ Event.observe(window,"resize", this.re_center);
+ if(Prototype.Browser.IE && Prototype.Browser.IE <= 6)
+ Event.observe(window,"scroll", this.re_center);
+ return this;
+ },
+
+ stopObserving: function() {
+ Event.stopObserving(window, "resize", this.re_center);
+ if(Prototype.Browser.IE && Prototype.Browser.IE <= 6)
+ Event.stopObserving(window, "scroll", this.re_center);
+ return this;
+ },
+
+ set_destination: function(dest_element) {
+ this.destElement = $(dest_element) || $$('body')[0];
+ return this;
+ },
+
+ create: function() {
+ if(!this.loading_mask) {
+ var objBody = $$('body')[0];
+ this.loading_mask = this.getModTemplate('template').parseToElement().hide();
+
+ objBody.insert({
+ bottom: this.loading_mask
+ });
+ this.loading_mask.setStyle( { 'opacity': 0.8, zIndex: 9000 } );
+ }
+
+ this.loading_mask_loader = this.loading_mask.down('#loading-mask-loader');
+ this.loading_mask_loader.setStyle( { /*'position': 'fixed', */zIndex: 9100 } );
+ //Create iframeShim if required
+ this.createShim();
+ return this;
+ },
+
+ show: function () {
+ if(this.loading_mask.visible()) return;
+ this.startObserving();
+ this.center();
+ this.loading_mask.show();
+ return this;
+ },
+
+ hide: function () {
+ this.loading_mask.hide();
+ this.stopObserving().positionShim(true);
+ return this;
+ },
+
+ center: function() {
+ //Evil IE6
+ if(!this.iecenter()) {
+ Element.clonePosition(this.loading_mask, this.destElement);
+ this.fixBody().positionShim(false);
+ }
+ return this;
+
+ },
+
+ recenter: function() {
+ if(!this.iecenter()) {
+ Element.clonePosition(this.loading_mask, this.destElement);
+ this.fixBody().positionShim(false);
+ }
+ return this;
+ },
+
+ iecenter: function() {
+ if(Prototype.Browser.IE && Prototype.Browser.IE <= 6) {
+ //The 'freezing' problem solved (opacity = 1 ?!)
+ this.loading_mask.show();
+ var offset = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
+ var destdim = document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
+
+ if(!this.lmh) this.lmh = this.loading_mask_loader.getHeight();
+ var eldim = this.lmh;
+ var toph = parseInt(destdim/2 - eldim/2 + offset );
+ this.loading_mask.setStyle({top: 0, left: 0, 'opacity': 1});
+ this.fixBody(true);
+ this.loading_mask_loader.setStyle( {
+ 'position': 'absolute',
+ 'top': toph + 'px',
+ 'opacity': 1
+ });
+
+ this.positionShim(false);
+ return true;
+ }
+ return false;
+ },
+
+ fixBody: function(force) {
+ if(force || this.destElement.nodeName.toLowerCase() == 'body') {
+ var ps = e107Helper.getPageSize();
+ this.loading_mask.setStyle({ 'width': parseInt(ps[0]) + 'px', 'height': parseInt(ps[1]) + 'px' });
+ }
+ return this;
+ },
+
+ createShim: function() {
+ if(!this.iframeShim) {
+ this.iframeShim = new e107Utils.IframeShim().hide();
+ this.setModCache(this.cacheStr +'-iframe', this.iframeShim);
+ }
+
+ return this;
+ },
+
+ positionShim: function(hide) {
+ if(hide) {
+ this.iframeShim.hide(); return this;
+ }
+ this.iframeShim.positionUnder(this.loading_mask).show();
+ return this;
+ }
+});
+
+/**
+ * Register core loading events
+ */
+e107Event.register('ajax_loading_start', function(event) {
+ var loadingObj = e107.getModCache('ajax-loader');
+ if(!loadingObj) {
+ loadingObj = new e107Utils.LoadingStatus(false, { show_auto: false });
+ e107.setModCache('ajax-loader', loadingObj);
+ }
+ loadingObj.set_destination(event.memo.overlayElement).show();
+});
+
+e107Event.register('ajax_loading_end', function(event) {
+ var loadingObj = e107.getModCache('ajax-loader');
+ if(loadingObj) {
+ window.setTimeout( function(){ loadingObj.hide() }, 200);
+ }
+});
+
+// -------------------------------------------------------------------
+
+// ###### START DEPRECATED - subject of removal!!! ######
+
+//@see e107Helper#toggle, e107Helper#autoToggle
+var expandit = function(curobj, hide) {
+ e107Helper.toggle(curobj, {});
+
+ if(hide) { //don't use it - will be removed
+ hide.replace(/[\s]?,[\s]?/, ' ').strip();
+ $w(hide).each(function(h) {
+ if(Object.isElement($(h))) { $(h).hide(); }
+ });
+ }
+}
+
+//Use Prototype JS instead: $(id).update(txt);
+var setInner = function(id, txt) {
+ $(id).update(txt);
+}
+
+//@see e107Helper#confirm TODO @see e107ModalConfirm#confirm
+var jsconfirm = function(thetext){
+ return e107Helper.confirm(thetext);
+}
+
+//Use Prototype JS instead e.g.: $(tagid).value = str; $(display).hide();
+var insertext = function(str, tagid, display) {
+ e107Helper.insertText(str, tagid, display);
+}
+
+//Use Prototype JS instead e.g.: $(tagid).focus().value += str; $(display).hide();
+var appendtext = function(str, tagid, display) {
+ e107Helper.appendText(str, tagid, display);
+}
+
+//TODO - e107Window class, e107Helper#openWindow proxy
+var open_window = function(url, wth, hgt) {
+ if('full' == wth){
+ pwindow = window.open(url);
+ } else {
+ mywidth = varset(wth, 600);
+ myheight = varset(wth, 400);
+ pwindow = window.open(url,'Name', 'top=100,left=100,resizable=yes,width='+mywidth+',height='+myheight+',scrollbars=yes,menubar=yes')
+ }
+ pwindow.focus();
+}
+
+//TODO Window class
+var closeWindow = function(form){
+ if((window.opener!=null)&&(!window.opener.closed)){
+ window.opener.location.reload();
+ }
+ if(window.opener!=null) {
+ window.close();
+ }else{setWinType(form);form.whatAction.value="Close";form.submit();}
+}
+
+
+//@see e107Helper#urljump
+var urljump = function(url) {
+ e107Helper.urlJump(url);
+}
+
+//@see e107Helper#imagePreload
+var ejs_preload = function(ejs_path, ejs_imageString){
+ e107Helper.imagePreload(ejs_path, ejs_imageString)
+}
+
+//Use Prototype JS e.g.: $(cntfield).value = $(field).value.length;
+var textCounter = function(field,cntfield) {
+ cntfield.value = field.value.length;
+}
+
+//Not used anymore - seek & remove
+/*
+function openwindow() {
+ opener = window.open("htmlarea/index.php", "popup","top=50,left=100,resizable=no,width=670,height=520,scrollbars=no,menubar=no");
+ opener.focus();
+}
+*/
+
+//@see e107Helper#toggleChecked
+var setCheckboxes = function(the_form, do_check, the_cb) { //backward compatibility
+ e107Helper.toggleChecked(the_form, do_check, 'name^=' + the_cb.gsub(/[\[\]]/, ''), false);
+}
+
+//@see e107Helper.BB#storeCaret
+var storeCaret = function(textAr) {
+ e107Helper.BB.store(textAr); return;
+}
+
+//@see e107Helper.BB#insert
+var addtext = function(text, emote) {
+ e107Helper.BB.insert(text, emote); return;
+}
+
+//@see e107Helper.BB#help
+var help = function(help,tagid) {
+ e107Helper.BB.help_old(help, tagid, true);
+}
+
+//Use Prototype JS e.g.: $(object).addClassName(over); $(object).removeClassName(over);
+var eover = function(object, over) {
+ $(object).addClassName(over);
+}
+
+//@see e107Helper#duplicateHTML
+var duplicateHTML = function(copy, paste, baseid) {
+ e107Helper.duplicateHTML(copy,paste,baseid);
+}
+
+var preview_image = function(src_val,img_path, not_found) {
+ e107Helper.previewImage(src_val, img_path, not_found)
+}
+
+var externalLinks = function () {
+ e107Helper.externalLinks();
+};
+// ###### END DEPRECATED ######
+
+// -------------------------------------------------------------------
+
+/**
+ * e107History
+ *
+ * Prototype Xtensions http://www.prototypextensions.com/
+ */
+var e107History = {
+ __altered: false,
+ __currentHash: null,
+ __previousHash: null,
+ __iframe: false,
+ __title: false,
+
+ /**
+ * init()
+ * @desc Initialize the hash. Call this method in first
+ */
+ init: function() {
+ var inst = this;
+ var hash = location.hash.substring(1);
+ this.hash = $H(hash.toQueryParams());
+ this.__currentHash = hash;
+ this.__previousHash = hash;
+
+ this.__title = document.title;
+
+ if(Prototype.Browser.IE && Prototype.Browser.IE < 8) {
+ document.observe('dom:loaded', function(e) {
+ if(!$('e107-px-historyframe')) {
+ e107History.__iframe = new Element('iframe', {
+ name : 'e107-px-historyframe',
+ id : 'e107-px-historyframe',
+ src : '',
+ width : '0',
+ height : '0',
+ style : {
+ visibility: 'hidden'
+ }
+ });
+
+ document.body.appendChild(e107History.__iframe);
+
+ e107History.setHashOnIframe(inst.hash.toQueryString());
+ }
+ });
+ }
+ },
+
+ /**
+ * set( string name, string value )
+ *
+ * @desc Set new value value for parameter name
+ */
+ set: function(name, value) {
+ this.__previousHash = this.hash.toQueryString();
+ this.hash.set(name, value);
+ this.apply();
+ },
+
+ /**
+ * get( string $name )
+ *
+ * @desc Get value parameter $name
+ */
+ get: function(name) {
+ return this.hash.get(name);
+ },
+
+ /**
+ * unset( string $name )
+ *
+ * @desc Unset parameter $name
+ */
+ unset: function(name) {
+ this.hash.unset(name);
+ this.apply();
+ },
+
+ /**
+ * update()
+ *
+ * @desc Updates this.hash with the current hash
+ */
+ update: function() {
+ this.__previousHash = this.hash.toQueryString();
+ var hash = window.location.hash.substring(1);
+
+ // If IE, look in the iframe if the hash is updated
+ if(Prototype.Browser.IE && Prototype.Browser.IE < 8 && this.__iframe) {
+ var hashInFrame = this.getHashOnIframe();
+
+ if(hashInFrame != hash) {
+ hash = hashInFrame;
+ }
+ }
+
+ this.hash = $H(hash.toQueryParams());
+ this.__currentHash = hash;
+ },
+
+ /**
+ * apply()
+ *
+ * @desc Apply this.hash to location.hash
+ */
+ apply: function() {
+ var newHash = this.hash.toQueryString();
+
+ // set new hash
+ window.location.hash = newHash;
+
+ // If IE, apply new hash to frame for history
+ if(Prototype.Browser.IE && Prototype.Browser.IE < 8 && this.__iframe) {
+ if(this.__currentHash != newHash)
+ {
+ this.setHashOnIframe(newHash);
+ }
+ else if(newHash != this.getHashOnIframe())
+ {
+ this.setHashOnIframe(newHash);
+ }
+ }
+ },
+
+ /**
+ * isAltered()
+ *
+ * @desc Return true if current hash is different of previous hash.
+ * this.__altered allows to force the dispatch.
+ */
+ isAltered: function() {
+ if(this.__altered == true) {
+ return true;
+ }
+ this.__altered = false;
+
+ return (e107History.__currentHash != e107History.__previousHash);
+ },
+
+ /**
+ * setHashOnIframe()
+ *
+ * @use For IE compatibility
+ * @desc Set hash value on iframe
+ */
+ setHashOnIframe: function(hash) {
+ try {
+ var doc = e107History.__iframe.contentWindow.document;
+ doc.open();
+ doc.write('' + hash + '');
+ doc.close();
+ } catch(e) {}
+ },
+
+ /**
+ * getHashOnIframe()
+ *
+ * @use For IE compatibility
+ * @desc Get hash value on iframe
+ */
+ getHashOnIframe: function() {
+ var doc = this.__iframe.contentWindow.document;
+ if (doc && doc.body.id == 'history') {
+ return doc.body.innerText;
+ } else {
+ return this.hash.toQueryString();
+ }
+ },
+
+ /**
+ * setTitle()
+ *
+ * @desc Set a new title for window
+ */
+ setTitle: function(title) {
+ if(document.title) {
+ document.title = title;
+ }
+ },
+
+ /**
+ * getTitle()
+ *
+ * @desc Return current window title
+ */
+ getTitle: function() {
+ return this.__title;
+ }
+};
+
+e107History.init();
+
+/**
+ * History.Registry
+ * Prototype Xtensions http://www.prototypextensions.com/
+ *
+ * @desc Used to register a callback for a parameter
+ */
+e107History.Registry =
+{
+ /**
+ * @desc Hash
+ */
+ hash : new Hash(),
+
+ /**
+ * set( string $config )
+ *
+ * @desc Set new value historyId for parameter config
+ */
+ set: function(config) {
+
+ if(typeof(config) != 'object') {
+ throw('e107History.Registry.set : config must be an javascript object');
+ }
+
+ // id
+ if(!config.id || !Object.isString(config.id)) {
+ throw('e107History.Registry.set : config.id must be an string');
+ }
+
+ // onChange
+ if(!config.onStateChange || !Object.isFunction(config.onStateChange)) {
+ throw('e107History.Registry.set : config.onStateChange '
+ + 'must be an javascript callback function');
+ }
+
+ // defaultValue
+ if(!config.defaultValue || !Object.isString(config.defaultValue)) {
+ config.defaultValue = '';
+ }
+
+ this.hash.set(config.id, config);
+ },
+
+ /**
+ * flat version of set method
+ *
+ * @desc Register callback function for historyId
+ */
+ register: function(historyId, callback, defval) {
+ var config = {
+ id: historyId,
+ onStateChange: callback,
+ defaultValue: defval
+ };
+ this.set(config);
+ },
+
+ /**
+ * get( string $id )
+ *
+ * @desc Get value parameter $id
+ */
+ get: function(id) {
+ return this.hash.get(id);
+ },
+
+ /**
+ * unset( string $id )
+ *
+ * @desc Unset parameter $id
+ */
+ unset: function(id) {
+ this.hash.unset(id);
+ }
+}
+
+/**
+ * History.Observer
+ * Prototype Xtensions http://www.prototypextensions.com/
+ *
+ * @desc Used to perform actions defined in the registry,
+ * according to the hash of the url.
+ */
+e107History.Observer = {
+
+ /**
+ * @desc Interval delay in seconds
+ */
+ delay : 0.4,
+
+ /**
+ * @desc Interval timer instance
+ */
+ interval : null,
+
+ /**
+ * @desc If interval is started : true, else false
+ */
+ started : false,
+
+ /**
+ * start()
+ *
+ * @desc Start a interval timer
+ */
+ start: function() {
+ if(this.started) return;
+ this.interval = new PeriodicalExecuter(e107History.Observer.dispatch, this.delay);
+ this.started = true;
+ },
+
+ /**
+ * stop()
+ *
+ * @desc Stop the interval timer
+ */
+ stop: function() {
+ if(!this.started) return;
+ this.interval.stop();
+ this.started = false;
+ },
+
+ /**
+ * dispatch()
+ *
+ * @desc This method is called each time interval,
+ * the dispatch of the registry is implemented only if
+ * the hash has been amended (optimisiation)
+ */
+ dispatch: function() {
+ // Update the hash
+ e107History.update();
+
+ // Dispatch only if location.hash has been altered
+ if(e107History.isAltered()) {
+ e107History.hash.each(function(pair) {
+ var registry = e107History.Registry.get(pair.key);
+ if(registry) {
+ registry.onStateChange.bind(e107History)( pair.value );
+ }
+ });
+ }
+ }
+};
+
+// -------------------------------------------------------------------
+
+/*
+ * AJAX related
+ */
+var e107Ajax = {};
+
+/**
+ * Ajax.History
+ * Prototype Xtensions http://www.prototypextensions.com/
+ *
+ * @desc Provides core methods to easily manage browsing history
+ * with Ajax.History.Request / Updater.
+ */
+e107Ajax.History = {
+
+ /**
+ * @desc Allowed Ajax.History prefix (for validation)
+ */
+ types : ['Request', 'Updater'],
+
+ cacheString: 'ajax-history-',
+
+ /**
+ * observe( string type, string id, string url, object options )
+ *
+ * @desc This method helps manage the browsing history
+ */
+ observe: function(type, id, url, options) {
+
+ var getter = e107.getModCache(this.cacheString + id);
+ var currentVersion = 0;
+ var output = false;
+
+ // Type validation
+ if(this.types.indexOf(type) == -1) {
+ throw('e107Ajax.History.observer: type ' + type + ' is invalid !');
+ }
+
+ // Registry management
+ if(!getter) {
+ currentVersion = (options.history.state) ? options.history.state : 0;
+ var hash = new Hash();
+ hash.set(currentVersion, options);
+ e107.setModCache(this.cacheString + id, hash);
+ //console.log(id, e107.getModCache(this.cacheString + id));
+ } else {
+ currentVersion = (options.history.state)
+ ? options.history.state : this.getCurrentVersion(id);
+ getter.set(currentVersion, options);
+ }
+
+ // add handler on registry
+ this.addCallback(type, id);
+
+ return currentVersion;
+ },
+
+ /**
+ * addCallback( string type, string id )
+ *
+ * @desc This method adds a state for request on History.Registry
+ */
+ addCallback: function(type, id) {
+
+ e107History.Observer.start();
+ // console.log(this.cacheString + id, e107.getModCache(this.cacheString + id).get('0'));
+ // Set history altered state to true : force dispatch
+ e107History.__altered = true;
+
+ // Return void if registry is already set
+ if(!Object.isUndefined(e107History.Registry.get(id))) return;
+
+ // Add this id to history registry
+ var cacheS = this.cacheString + id;
+ e107History.Registry.set({
+ id: id,
+ onStateChange: function(state) {
+ var options = e107.getModCache(cacheS).get(state.toString());
+ var request = null;
+
+ if(Object.isUndefined(options)) return;
+
+ if(options.history.cache == true && options.history.__request) {
+ new Ajax.Cache(options.history.__request);
+ } else {
+ //make a request
+ if(type == 'Request') {
+ request = new Ajax.Request(options.history.__url, options);
+ } else if(type == 'Updater') {
+ request = new Ajax.Updater(options.container, options.history.__url, options);
+ }
+ options.history.__request = request;
+ }
+
+ e107History.__altered = false;
+
+ if (Object.isFunction(options.history.onStateChange)) {
+ options.history.onStateChange(state);
+ }
+ }
+ });
+ },
+
+ /**
+ * getCurrentVersion( string id )
+ *
+ * @desc This method returns the current state in history
+ * (if the state is not defined)
+ */
+ getCurrentVersion: function(id) {
+ var getter = e107.getModCache(this.cacheString + id);
+ return Object.isUndefined(getter) ? 0 : getter.keys().length;
+ }
+};
+
+e107Ajax.ObjectMap = {
+ id : null, // set custom history value for this instance
+ state : false, // set custom state value for this instance
+ cache : false, // enable/disable history cache
+ onStateChange : null, // handler called on history change
+ __url : null,
+ __request : null
+};
+
+/**
+ * Ajax.Cache
+ * Prototype Xtensions http://www.prototypextensions.com/
+ *
+ * @desc Ajax.Cache can "simulate" an Ajax request from an
+ * Ajax.Request/Updater made beforehand.
+ */
+Ajax.Cache = Class.create(Ajax.Base, {
+ _complete: false,
+ initialize: function($super, request) {
+ $super(request.options);
+ request._complete = false;
+ this.transport = request.transport;
+ this.request(request.url);
+ return this;
+ },
+
+ request: function(url) {
+ this.url = url;
+ this.method = this.options.method;
+ var params = Object.clone(this.options.parameters);
+
+ try {
+ var response = new Ajax.Response(this);
+
+ if (this.options.onCreate) this.options.onCreate(response);
+ Ajax.Responders.dispatch('onCreate', this, response);
+
+ if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
+
+ this.onStateChange();
+ }
+ catch (e) {
+ this.dispatchException(e);
+ }
+ }
+});
+
+Object.extend(Ajax.Cache.prototype, {
+ respondToReadyState : Ajax.Request.prototype.respondToReadyState,
+ onStateChange : Ajax.Request.prototype.onStateChange,
+ success : Ajax.Request.prototype.getStatus,
+ getStatus : Ajax.Request.prototype.getStatus,
+ isSameOrigin : Ajax.Request.prototype.isSameOrigin,
+ getHeader : Ajax.Request.prototype.getHeader,
+ evalResponse : Ajax.Request.prototype.evalResponse,
+ dispatchException : Ajax.Request.prototype.dispatchException
+});
+
+/**
+ * Ajax.Request Extended
+ * Prototype Xtensions http://www.prototypextensions.com/
+ *
+ * @desc Just a small change: now Ajax.Request return self scope.
+ * It is required by Ajax.Cache
+ */
+Ajax.Request = Class.create(Ajax.Request, {
+ initialize: function($super, url, options) {
+ $super(url, options);
+ return this;
+ }
+});
+
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+/**
+ * Ajax.Updater Extended
+ * Prototype Xtensions http://www.prototypextensions.com/
+ *
+ * @desc Just a small change: now Ajax.Updater return self scope
+ * It is required by Ajax.Cache
+ */
+Ajax.Updater = Class.create(Ajax.Updater, {
+ initialize: function($super, container, url, options) {
+ $super(container, url, options);
+ return this;
+ }
+});
+
+
+
+//Register Ajax Responder
+(function() {
+
+ var e_responder = {
+ onCreate: function(request) {
+ if(request.options.updateElement) {
+ e107Event.trigger('ajax_update_before', request.options);
+ }
+ if(request.options.overlayElement){
+ e107Event.trigger('ajax_loading_start', request.options);
+ }
+ },
+
+ onComplete: function(request) {
+ if(request.options.updateElement) {
+ e107Event.trigger('ajax_update_after', request.options);
+ }
+ /*Ajax.activeRequestCount == 0 && */
+ if(request.options.overlayElement) {
+ e107Event.trigger('ajax_loading_end', request.options);
+ }
+ },
+
+ onException: function(request, e) {
+ //TODO handle exceptions
+ alert('e107Ajax Exception: ' + e);
+ }
+ }
+
+ Ajax.Responders.register(e_responder);
+})();
+
+/**
+ * e107AjaxAbstract
+ */
+var e107AjaxAbstract = Class.create ({
+ _processResponse: function(transport) {
+ if(transport.responseXML) {
+ this._handleXMLResponse(transport.responseXML);
+ } else if(transport.responseJSON) {
+ this._handleJSONResponse(transport.responseJSON);
+ } else {
+ this._handleTextResponse(transport.responseText);
+ }
+
+ },
+
+ _handleXMLResponse: function (response) {
+ var xfields = $A(response.childNodes[0].childNodes);
+ //getElementsByTagName('e107response')[0]
+ var parsed = {};
+ xfields.each( function(el) {
+ if (el.nodeType == 1 && el.nodeName == 'e107action' && el.getAttribute('name') && el.childNodes) {
+
+ var action = el.getAttribute('name'), items = el.childNodes;
+ if(!varsettrue(parsed[action])) {
+ parsed[action] = {};
+ }
+
+ for(var i=0, len=items.length; i -1,
+ WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 &&
+ navigator.userAgent.indexOf('KHTML') === -1,
+ MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+ },
+
+ BrowserFeatures: {
+ XPath: !!document.evaluate,
+ SelectorsAPI: !!document.querySelector,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ document.createElement('div')['__proto__'] &&
+ document.createElement('div')['__proto__'] !==
+ document.createElement('form')['__proto__']
+ },
+
+ ScriptFragment: '\n";
-}
-if (isset($theme_js_php) && $theme_js_php)
-{
- echo "\n";
-}
-else
-{
- if (file_exists(THEME.'theme.js')) { echo "\n"; }
- if (is_readable(e_FILE.'user.js') && filesize(e_FILE.'user.js')) { echo "\n"; }
- if (file_exists(THEME.'theme.vbs')) { echo "\n"; }
- if (is_readable(e_FILE.'user.vbs') && filesize(e_FILE.'user.vbs')) { echo "\n"; }
-}
+//Core CSS first
+if (!defined("PREVIEWTHEME") && (!isset($no_core_css) || !$no_core_css)) {
-
-if (isset($eplug_js) && $eplug_js)
-{
- echo "\n\n";
- if(is_array($eplug_js))
- {
- $eplug_js_unique = array_unique($eplug_js);
- foreach($eplug_js_unique as $kjs)
- {
- echo ($kjs[0] == "<") ? $kjs : "\n";
- }
- }
- else
- {
- echo "\n";
- }
+ echo "\n";
}
-
-if (!USER && ($pref['user_tracking'] == "session") && varset($pref['password_CHAP'],0))
-{
- if ($pref['password_CHAP'] == 2)
- {
- // *** Add in the code to swap the display tags
- $js_body_onload[] = "expandit('loginmenuchap','nologinmenuchap');";
- }
- echo "\n";
- $js_body_onload[] = "getChallenge();";
-}
-
-
-if((isset($pref['enable_png_image_fix']) && $pref['enable_png_image_fix'] == true) || (isset($sleight) && $sleight == true))
-{
- echo "\n\n";
-}
-
-if (function_exists('headerjs')) {echo headerjs(); }
-
-
-
-//
-// E: Send CSS
-//
-
+//Plugin specific CSS
if (isset($eplug_css) && $eplug_css)
{
if(is_array($eplug_css))
@@ -193,6 +127,7 @@ if (isset($eplug_css) && $eplug_css)
}
+//Theme CSS
if(defined("PREVIEWTHEME")) {
echo "\n";
} else {
@@ -228,18 +163,110 @@ if(defined("PREVIEWTHEME")) {
}
echo "\n";
}
- if (!isset($no_core_css) || !$no_core_css) {
- echo "\n";
+ }
+}
+
+
+// Load Plugin Header Files
+if (varset($pref['e_header_list']) && is_array($pref['e_header_list']))
+{
+ foreach($pref['e_header_list'] as $val)
+ {
+ if(is_readable(e_PLUGIN.$val."/e_header.php"))
+ {
+ require_once(e_PLUGIN.$val."/e_header.php");
}
}
}
+//
+// E: Send JS
+//
+
+// Send Javascript Libraries ALWAYS (for now)
+$hash = md5(serialize(varset($pref['e_jslib'])).serialize(varset($THEME_JSLIB)).THEME.e_LANGUAGE.ADMIN).'_front';
+echo "\n";
+/*
+if (!isset($no_core_js) || !$no_core_js)
+{
+ echo "\n";
+}
+*/
+
+// Send Plugin JS Files
+if (isset($eplug_js) && $eplug_js)
+{
+ echo "\n\n";
+ if(is_array($eplug_js))
+ {
+ $eplug_js_unique = array_unique($eplug_js);
+ foreach($eplug_js_unique as $kjs)
+ {
+ echo ($kjs[0] == "<") ? $kjs : "\n";
+ }
+ }
+ else
+ {
+ echo "\n";
+ }
+}
+
+// Send Theme JS Files
+if (isset($theme_js_php) && $theme_js_php)
+{
+ echo "\n";
+}
+else
+{
+ if (file_exists(THEME.'theme.js')) { echo "\n"; }
+ if (is_readable(e_FILE.'user.js') && filesize(e_FILE.'user.js')) { echo "\n"; }
+ if (file_exists(THEME.'theme.vbs')) { echo "\n"; }
+ if (is_readable(e_FILE.'user.vbs') && filesize(e_FILE.'user.vbs')) { echo "\n"; }
+}
+
+//XXX - CHAP JS
+if (!USER && ($pref['user_tracking'] == "session") && varset($pref['password_CHAP'],0))
+{
+ if ($pref['password_CHAP'] == 2)
+ {
+ // *** Add in the code to swap the display tags
+ $js_body_onload[] = "expandit('loginmenuchap','nologinmenuchap');";
+ }
+ echo "\n";
+ $js_body_onload[] = "getChallenge();";
+}
+
+
+if((isset($pref['enable_png_image_fix']) && $pref['enable_png_image_fix'] == true) || (isset($sleight) && $sleight == true))
+{
+ echo "\n\n";
+}
+
+//IEpngfix - visible by IE6 only
+if((isset($pref['enable_png_image_fix']) && $pref['enable_png_image_fix'] == true) || (isset($sleight) && $sleight == true)) {
+ /*
+ * The only problem is that the browser is REALLY,
+ * REALLY slow when it has to render more elements
+ * try e.g. "div, img, td, input" (or just *) instead only img rule
+ * However I hope it'll force IE6 users to switch to a modern browser...
+ */
+ echo "\n";
+}
+
+//headerjs moved below
+
// Deprecated function finally removed
//if(function_exists('core_head')){ echo core_head(); }
//
-// F: Send Meta Tags and Icon links
+// F: Send Meta Tags, Icon links, headerjs()
//
// Multi-Language meta-tags with merge and override option.
@@ -252,14 +279,17 @@ echo (defined("CORE_LC")) ? " and start of
//
+
+/*
+ * Fire Event e107:loaded
+ */
+echo "\n";
+
echo "
\n";
$sql->db_Mark_Time("Main Page Body");
@@ -370,6 +412,8 @@ if ($e107_popup != 1) {
//
// L: (optional) Body JS to disable right clicks
//
+
+// --------------------- REMOVE IT!!! ------------------------->
if (isset($pref['no_rightclick']) && $pref['no_rightclick']) {
echo "\n";
}
+// --------------------- REMOVE END ------------------------->
//
// M: Send top of body for custom pages and for news