diff options
author | Karl 'vollmerk' Vollmer <vollmer@ampache.org> | 2008-02-29 06:14:46 +0000 |
---|---|---|
committer | Karl 'vollmerk' Vollmer <vollmer@ampache.org> | 2008-02-29 06:14:46 +0000 |
commit | 2c337852cff31297d681fb87d3098cc3d9041101 (patch) | |
tree | 9853ce94387c4cc7756575598dfb1e2de44a8589 | |
parent | c1f2b35e2a18b0752746f5db5794cf18714bc71d (diff) | |
download | ampache-2c337852cff31297d681fb87d3098cc3d9041101.tar.gz ampache-2c337852cff31297d681fb87d3098cc3d9041101.tar.bz2 ampache-2c337852cff31297d681fb87d3098cc3d9041101.zip |
major corrections to reading of preferences and a few misc fixes which I have now forgotten
27 files changed, 327 insertions, 476 deletions
diff --git a/docs/CHANGELOG b/docs/CHANGELOG index 15afd05f..57ebdd43 100755 --- a/docs/CHANGELOG +++ b/docs/CHANGELOG @@ -4,6 +4,8 @@ -------------------------------------------------------------------------- v.3.4-Beta2 + - Added Catalog Last Update and Last Add times to API Handshake. + - Fixed Remember Me Cookie so it's actually set - Removed some invalid queries that were not needed, tweaked logic of no_session to avoid useless query - Added Greek Translation ( Thx Panayotis Tsirigotis ) diff --git a/lib/class/access.class.php b/lib/class/access.class.php index 98fd0b39..bfc7beb9 100644 --- a/lib/class/access.class.php +++ b/lib/class/access.class.php @@ -145,7 +145,7 @@ class Access { return false; } if (Config::get('allow_zip_download') AND $GLOBALS['user']->has_access(25)) { - return $GLOBALS['user']->prefs['download']; + return Config::get('download'); } break; default: @@ -237,7 +237,7 @@ class Access { switch ($type) { case 'localplay': // Check their localplay_level - if ($GLOBALS['user']->prefs['localplay_level'] >= $level) { + if (Config::get('localplay_level') >= $level) { return true; } else { diff --git a/lib/class/api.class.php b/lib/class/api.class.php index f1ff7a33..bd1b7ce0 100644 --- a/lib/class/api.class.php +++ b/lib/class/api.class.php @@ -86,13 +86,19 @@ class Api { $data['type'] = 'api'; $data['value'] = $timestamp; $token = vauth::session_create($data); + // Insert the token into the streamer $stream = new Stream(); $stream->user_id = $client->id; $stream->insert_session($token); debug_event('API','Login Success, passphrase matched','1'); - return array('auth'=>$token,'api'=>self::$version); + // We need to also get the 'last update' of the catalog information in an RFC 2822 Format + $sql = "SELECT MAX(`last_update`) AS `update`,MAX(`last_add`) AS `add` FROM `catalog`"; + $db_results = Dba::query($sql); + $row = Dba::fetch_assoc($db_results); + + return array('auth'=>$token,'api'=>self::$version,'update'=>date("r",$row['update']),'add'=>date("r",$row['add'])); } // match } // end while diff --git a/lib/class/browse.class.php b/lib/class/browse.class.php index cf5644b5..98dabce6 100644 --- a/lib/class/browse.class.php +++ b/lib/class/browse.class.php @@ -671,7 +671,7 @@ class Browse { self::$total_objects = count($object_ids); // Limit is based on the users preferences - $limit = $GLOBALS['user']->prefs['offset_limit'] ? $GLOBALS['user']->prefs['offset_limit'] : '25'; + $limit = Config::get('offset_limit') ? Config::get('offset_limit') : '25'; if (count($object_ids) > self::$start) { $object_ids = array_slice($object_ids,self::$start,$limit); diff --git a/lib/class/localplay.class.php b/lib/class/localplay.class.php index 1a4c8bef..7d793fa1 100644 --- a/lib/class/localplay.class.php +++ b/lib/class/localplay.class.php @@ -206,7 +206,7 @@ class Localplay { $this->_player->uninstall(); // If its our current player, reset player to nothing - if ($GLOBALS['user']->prefs['localplay_controller'] == $this->type) { + if (Config::get('localplay_controller') == $this->type) { Preference::update('localplay_controller',$GLOBALS['user']->id,''); } diff --git a/lib/class/metadata.class.php b/lib/class/metadata.class.php index 9e562090..ca7da903 100644 --- a/lib/class/metadata.class.php +++ b/lib/class/metadata.class.php @@ -47,7 +47,7 @@ class metadata { // For now it's only mystrands OpenStrands::set_auth_token(Config::get('mystrands_developer_key')); - $openstrands = new OpenStrands($GLOBALS['user']->prefs['mystrands_user'],$GLOBALS['user']->prefs['mystrands_pass']); + $openstrands = new OpenStrands(Config::get('mystrands_user'),Config::get('mystrands_pass')); // Make sure auth worked if (!$openstrands) { return false; } @@ -101,7 +101,7 @@ class metadata { // For now it's only mystrands OpenStrands::set_auth_token(Config::get('mystrands_developer_key')); - $openstrands = new OpenStrands($GLOBALS['user']->prefs['mystrands_user'],$GLOBALS['user']->prefs['mystrands_pass']); + $openstrands = new OpenStrands(Config::get('mystrands_user'),Config::get('mystrands_pass')); if (!$openstrands) { return false; } diff --git a/lib/class/stream.class.php b/lib/class/stream.class.php index 80d05654..fee74523 100644 --- a/lib/class/stream.class.php +++ b/lib/class/stream.class.php @@ -223,9 +223,6 @@ class Stream { } $song = new Song($song_id); if ($song->type == ".flac") { $song->type = ".ogg"; } - if ($GLOBALS['user']->prefs['play_type'] == 'downsample') { - $ds = $GLOBALS['user']->prefs['sample_rate']; - } echo $song->get_url(); } // end foreach @@ -408,7 +405,7 @@ class Stream { //FIXME: This needs to go in a template, here for now though //FIXME: This preference doesn't even exists, we'll eventually //FIXME: just make it the default - if ($GLOBALS['user']->prefs['embed_xspf'] == 1 ){ + if (Config::get('embed_xspf') == 1 ){ header("Location: ".Config::get('web_path')."/index.php?xspf&play_info=".$GLOBALS['user']->playlist->id); } else { @@ -446,7 +443,7 @@ class Stream { function create_localplay() { // First figure out what their current one is and create the object - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->connect(); //HACK!!! // Yea.. you know the baby jesus... he's crying right meow @@ -526,7 +523,7 @@ class Stream { $max_bitrate = Config::get('max_bit_rate'); $min_bitrate = Config::get('min_bit_rate'); $time = time(); - $user_sample_rate = $GLOBALS['user']->prefs['sample_rate']; + $user_sample_rate = Config::get('sample_rate'); $browser = new Browser(); if (!$song_name) { @@ -705,9 +702,9 @@ class Stream { if (AJAX_INCLUDE != '1') { return false; } // If we're doin the flash magic then run away as well - if ($GLOBALS['user']->prefs['play_type'] == 'xspf_player') { return false; } + if (Config::get('play_type') == 'xspf_player') { return false; } - switch ($GLOBALS['user']->prefs['playlist_method']) { + switch (Config::get('playlist_method')) { default: case 'clear': case 'default': diff --git a/lib/class/vauth.class.php b/lib/class/vauth.class.php index 5f67e442..b670db2d 100644 --- a/lib/class/vauth.class.php +++ b/lib/class/vauth.class.php @@ -236,7 +236,7 @@ class vauth { $session_name = Config::get('session_name'); Config::set('cookie_life',$remember_length,'1'); - setcookie($session_name . '_remember',"Rappelez-vous, rappelez-vous le 27 mars",time() + $remember_length,'/',Config::get('cookie_domain')); + setcookie($session_name . '_remember',"Rappelez-vous, rappelez-vous le 27 mars",time() + $remember_length,'/'); } // create_remember_cookie @@ -301,13 +301,6 @@ class vauth { // No cookie n go! if (!isset($_COOKIE[$session_name])) { return false; } - $key = scrub_in($_COOKIE[$session_name]); - $data = self::get_session_data($key); - - if (!is_array($data)) { - return false; - } - // Check for a remember me if (isset($_COOKIE[$session_name . '_remember'])) { self::create_remember_cookie(); diff --git a/lib/init.php b/lib/init.php index b86c3108..f63c3add 100644 --- a/lib/init.php +++ b/lib/init.php @@ -144,6 +144,7 @@ require_once $prefix . '/modules/infotools/openstrands.class.php'; $results = Preference::fix_preferences($results); Config::set_by_array($results,1); +debug_event('ZZWANG IS',$wang,'1'); // Modules (These are conditionaly included depending upon config values) if (Config::get('ratings')) { @@ -219,11 +220,10 @@ elseif (!Config::get('use_auth')) { // If Auth, but no session is set else { if (isset($_REQUEST['sessid'])) { - $sess_results = vauth::get_session_data($_REQUEST['sessid']); session_name(Config::get('session_name')); session_id(scrub_in($_REQUEST['sessid'])); session_start(); - $GLOBALS['user'] = User::get_from_username($sess_results['username']); + $GLOBALS['user'] = User::get_from_username($_SESSION['userdata']['username']); } else { $GLOBALS['user'] = new User(); @@ -264,5 +264,4 @@ if (! preg_match('/update\.php/', $_SERVER['PHP_SELF'])) { // For the XMLRPC stuff $GLOBALS['xmlrpc_internalencoding'] = Config::get('site_charset'); - ?> diff --git a/lib/localplay.lib.php b/lib/localplay.lib.php deleted file mode 100644 index 1795fc41..00000000 --- a/lib/localplay.lib.php +++ /dev/null @@ -1,136 +0,0 @@ -<?php -/* - - Copyright (c) 2001 - 2006 Ampache.org - All Rights Reserved - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License v2 - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -/** - * insert_locaplay_preferences - * This takes a controller type and inserts the preferences - * Into the database, it is able to handle existing preferences - * It checks before inserting... - */ -function insert_localplay_preferences($type) { - - /* We can't assume the connect so let's just - * create it then get the preferences - */ - $localplay = new Localplay($type); - - $preferences = $localplay->get_preferences(); - - foreach ($preferences as $preference) { - $name = 'localplay_' . $type . '_' . $preference['name']; - /* Check for an existing record */ - $sql = "SELECT id FROM preferences WHERE name = '" . sql_escape($name) . "'"; - $db_results = mysql_query($sql, dbh()); - - if (mysql_num_rows($db_results)) { continue; } - - insert_preference($name,$preference['description'],$preference['default'],'25',$preference['type'],'streaming'); - - } // end foreach preferences - - /* Fix everyones preferences */ - $sql = "SELECT * FROM `user`"; - $db_results = Dba::query($sql); - - $temp_user = new User(); - $temp_user->fix_preferences('-1'); - - while ($r = mysql_fetch_assoc($db_results)) { - $temp_user->fix_preferences($r['username']); - } // end while - - return true; - -} // insert_localplay_preferences - -/** - * remove_localplay_preferences - * This function has two uses, if it is called with a specific type then it - * just removes the preferences for that type, however it if its called with - * nothing then it removes any set of preferences where the module no longer - * exists - */ -function remove_localplay_preferences($type=0) { - - /* If we've gotten a type wipe and go! */ - if ($type) { - $sql = "DELETE FROM preferences WHERE name LIKE 'localplay_" . sql_escape($type) . "_%'"; - $db_results = mysql_query($sql, dbh()); - return true; - } - - - /* Select everything but our two built-in ones - $sql = "SELECT * FROM preferences WHERE name != 'localplay_level' AND name != 'localplay_controller' AND name LIKE 'localplay_%'"; - $db_results = mysql_query($sql, dbh()); - - $results = array(); - - /* We need to organize by module to make it easy - * to figure out which modules no longer exist - * and wack the preferences... unless we've - * specified a name then just wack those - * preferences - */ - while ($r = mysql_fetch_assoc($db_results)) { - - $name = $r['name']; - preg_match("/localplay_([\w\d\-\]+)_.+/",$name,$matches); - $key = $matches['1']; - - $results[$key] = $r; - - } // end while - - /* If we've got a type */ - //FIXME!!! - - -} // remove_localplay_preferences - -/** - * This function stores the Localplay object - * It checks to see what access level you have - * and creates the localplay object based on that - * @package Local Play - */ -function init_localplay($reload=0) { - - static $localplay; - if ($GLOBALS['user']->prefs['localplay_level'] == '0') { return false; } - - if (!strlen($GLOBALS['user']->prefs['localplay_controller'])) { return false; } - - if ($GLOBALS['user']->prefs['localplay_level'] == '1' AND !is_object($localplay)) { - $localplay = new Localplay(conf('localplay_controller')); - $localplay->connect(); - } - - if ($GLOBALS['user']->prefs['localplay_level'] == '2' AND !is_object($localplay)) { - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); - $localplay->connect(); - } - - return $localplay; - -} // function init_localplay - -?> diff --git a/localplay.php b/localplay.php index f1593a4a..9b2e0ed2 100644 --- a/localplay.php +++ b/localplay.php @@ -35,7 +35,7 @@ switch ($_REQUEST['action']) { if (!Access::check('localplay','75')) { access_denied(); break; } // Get the current localplay fields - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $fields = $localplay->get_instance_fields(); require_once Config::get('prefix') . '/templates/show_localplay_add_instance.inc.php'; break; @@ -44,20 +44,20 @@ switch ($_REQUEST['action']) { if (!Access::check('localplay','75')) { access_denied(); break; } // Setup the object - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->add_instance($_POST); break; case 'update_instance': // Make sure they gots them rights if (!Access::check('localplay','75')) { access_denied(); break; } - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->update_instance($_REQUEST['instance'],$_POST); header("Location:" . Config::get('web_path') . "/localplay.php?action=show_instances"); break; case 'edit_instance': // Check to make sure they've got the access if (!Access::check('localplay','75')) { access_denied(); break; } - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $instance = $localplay->get_instance($_REQUEST['instance']); $fields = $localplay->get_instance_fields(); require_once Config::get('prefix') . '/templates/show_localplay_edit_instance.inc.php'; @@ -65,7 +65,7 @@ switch ($_REQUEST['action']) { case 'show_instances': // First build the localplay object and then get the instances if (!Access::check('localplay','5')) { access_denied(); break; } - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $instances = $localplay->get_instances(); $fields = $localplay->get_instance_fields(); require_once Config::get('prefix') . '/templates/show_localplay_instances.inc.php'; @@ -74,7 +74,7 @@ switch ($_REQUEST['action']) { case 'show_playlist': if (!Access::check('localplay','5')) { access_denied(); break; } // Init and then connect to our localplay instance - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->connect(); // Pull the current playlist and require the template diff --git a/modules/localplay/httpq.controller.php b/modules/localplay/httpq.controller.php index 37c7edde..9a67a249 100644 --- a/modules/localplay/httpq.controller.php +++ b/modules/localplay/httpq.controller.php @@ -228,7 +228,7 @@ class AmpacheHttpq extends localplay_controller { */ public function get_instance($instance='') { - $instance = $instance ? $instance : $GLOBALS['user']->prefs['httpq_active']; + $instance = $instance ? $instance : Config::get('httpq_active'); $instance = Dba::escape($instance); $sql = "SELECT * FROM `localplay_httpq` WHERE `id`='$instance'"; diff --git a/modules/localplay/mpd.controller.php b/modules/localplay/mpd.controller.php index a1f45a36..fecc327c 100644 --- a/modules/localplay/mpd.controller.php +++ b/modules/localplay/mpd.controller.php @@ -191,7 +191,7 @@ class AmpacheMpd extends localplay_controller { */ public function get_instance($instance='') { - $instance = $instance ? $instance : $GLOBALS['user']->prefs['mpd_active']; + $instance = $instance ? $instance : Config::get('mpd_active'); $instance = Dba::escape($instance); $sql = "SELECT * FROM `localplay_mpd` WHERE `id`='$instance'"; diff --git a/modules/prototype/prototype.js b/modules/prototype/prototype.js index 5c734629..6385503a 100644 --- a/modules/prototype/prototype.js +++ b/modules/prototype/prototype.js @@ -1,5 +1,5 @@ -/* Prototype JavaScript framework, version 1.6.0 - * (c) 2005-2007 Sam Stephenson +/* Prototype JavaScript framework, version 1.6.0.2 + * (c) 2005-2008 Sam Stephenson * * Prototype is freely distributable under the terms of an MIT-style license. * For details, see the Prototype web site: http://www.prototypejs.org/ @@ -7,7 +7,7 @@ *--------------------------------------------------------------------------*/ var Prototype = { - Version: '1.6.0', + Version: '1.6.0.2', Browser: { IE: !!(window.attachEvent && !window.opera), @@ -36,8 +36,6 @@ var Prototype = { if (Prototype.Browser.MobileSafari) Prototype.BrowserFeatures.SpecificElementExtensions = false; -if (Prototype.Browser.WebKit) - Prototype.BrowserFeatures.XPath = false; /* Based on Alex Arnell's inheritance implementation. */ var Class = { @@ -110,9 +108,9 @@ Object.extend = function(destination, source) { Object.extend(Object, { inspect: function(object) { try { - if (object === undefined) return 'undefined'; + if (Object.isUndefined(object)) return 'undefined'; if (object === null) return 'null'; - return object.inspect ? object.inspect() : object.toString(); + return object.inspect ? object.inspect() : String(object); } catch (e) { if (e instanceof RangeError) return '...'; throw e; @@ -135,7 +133,7 @@ Object.extend(Object, { var results = []; for (var property in object) { var value = Object.toJSON(object[property]); - if (value !== undefined) + if (!Object.isUndefined(value)) results.push(property.toJSON() + ': ' + value); } @@ -173,7 +171,8 @@ Object.extend(Object, { }, isArray: function(object) { - return object && object.constructor === Array; + return object != null && typeof object == "object" && + 'splice' in object && 'join' in object; }, isHash: function(object) { @@ -204,7 +203,7 @@ Object.extend(Function.prototype, { }, bind: function() { - if (arguments.length < 2 && arguments[0] === undefined) return this; + if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; var __method = this, args = $A(arguments), object = args.shift(); return function() { return __method.apply(object, args.concat($A(arguments))); @@ -351,7 +350,7 @@ Object.extend(String.prototype, { sub: function(pattern, replacement, count) { replacement = this.gsub.prepareReplacement(replacement); - count = count === undefined ? 1 : count; + count = Object.isUndefined(count) ? 1 : count; return this.gsub(pattern, function(match) { if (--count < 0) return match[0]; @@ -366,7 +365,7 @@ Object.extend(String.prototype, { truncate: function(length, truncation) { length = length || 30; - truncation = truncation === undefined ? '...' : truncation; + truncation = Object.isUndefined(truncation) ? '...' : truncation; return this.length > length ? this.slice(0, length - truncation.length) + truncation : String(this); }, @@ -486,7 +485,9 @@ Object.extend(String.prototype, { }, isJSON: function() { - var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); + var str = this; + if (str.blank()) return false; + str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); }, @@ -565,7 +566,8 @@ var Template = Class.create({ if (before == '\\') return match[2]; var ctx = object, expr = match[3]; - var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr); + var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; + match = pattern.exec(expr); if (match == null) return before; while (match != null) { @@ -577,7 +579,7 @@ var Template = Class.create({ } return before + String.interpret(ctx); - }.bind(this)); + }); } }); Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; @@ -686,7 +688,7 @@ var Enumerable = { }, inGroupsOf: function(number, fillWith) { - fillWith = fillWith === undefined ? null : fillWith; + fillWith = Object.isUndefined(fillWith) ? null : fillWith; return this.eachSlice(number, function(slice) { while(slice.length < number) slice.push(fillWith); return slice; @@ -713,7 +715,7 @@ var Enumerable = { var result; this.each(function(value, index) { value = iterator(value, index); - if (result == undefined || value >= result) + if (result == null || value >= result) result = value; }); return result; @@ -724,7 +726,7 @@ var Enumerable = { var result; this.each(function(value, index) { value = iterator(value, index); - if (result == undefined || value < result) + if (result == null || value < result) result = value; }); return result; @@ -805,20 +807,20 @@ Object.extend(Enumerable, { function $A(iterable) { if (!iterable) return []; if (iterable.toArray) return iterable.toArray(); - var length = iterable.length, results = new Array(length); + var length = iterable.length || 0, results = new Array(length); while (length--) results[length] = iterable[length]; return results; } if (Prototype.Browser.WebKit) { - function $A(iterable) { + $A = function(iterable) { if (!iterable) return []; if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && iterable.toArray) return iterable.toArray(); - var length = iterable.length, results = new Array(length); + var length = iterable.length || 0, results = new Array(length); while (length--) results[length] = iterable[length]; return results; - } + }; } Array.from = $A; @@ -904,7 +906,7 @@ Object.extend(Array.prototype, { var results = []; this.each(function(object) { var value = Object.toJSON(object); - if (value !== undefined) results.push(value); + if (!Object.isUndefined(value)) results.push(value); }); return '[' + results.join(', ') + ']'; } @@ -984,34 +986,6 @@ function $H(object) { }; var Hash = Class.create(Enumerable, (function() { - if (function() { - var i = 0, Test = function(value) { this.key = value }; - Test.prototype.key = 'foo'; - for (var property in new Test('bar')) i++; - return i > 1; - }()) { - function each(iterator) { - var cache = []; - for (var key in this._object) { - var value = this._object[key]; - if (cache.include(key)) continue; - cache.push(key); - var pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - } - } else { - function each(iterator) { - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - } - } function toQueryPair(key, value) { if (Object.isUndefined(value)) return key; @@ -1023,7 +997,14 @@ var Hash = Class.create(Enumerable, (function() { this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); }, - _each: each, + _each: function(iterator) { + for (var key in this._object) { + var value = this._object[key], pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, set: function(key, value) { return this._object[key] = value; @@ -1187,8 +1168,11 @@ Ajax.Base = Class.create({ Object.extend(this.options, options || { }); this.options.method = this.options.method.toLowerCase(); + if (Object.isString(this.options.parameters)) this.options.parameters = this.options.parameters.toQueryParams(); + else if (Object.isHash(this.options.parameters)) + this.options.parameters = this.options.parameters.toObject(); } }); @@ -1315,7 +1299,7 @@ Ajax.Request = Class.create(Ajax.Base, { var contentType = response.getHeader('Content-type'); if (this.options.evalJS == 'force' - || (this.options.evalJS && contentType + || (this.options.evalJS && this.isSameOrigin() && contentType && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) this.evalResponse(); } @@ -1333,9 +1317,18 @@ Ajax.Request = Class.create(Ajax.Base, { } }, + isSameOrigin: function() { + var m = this.url.match(/^\s*https?:\/\/[^\/]*/); + return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ + protocol: location.protocol, + domain: document.domain, + port: location.port ? ':' + location.port : '' + })); + }, + getHeader: function(name) { try { - return this.transport.getResponseHeader(name); + return this.transport.getResponseHeader(name) || null; } catch (e) { return null } }, @@ -1371,7 +1364,7 @@ Ajax.Response = Class.create({ if(readyState == 4) { var xml = transport.responseXML; - this.responseXML = xml === undefined ? null : xml; + this.responseXML = Object.isUndefined(xml) ? null : xml; this.responseJSON = this._getResponseJSON(); } }, @@ -1408,7 +1401,8 @@ Ajax.Response = Class.create({ if (!json) return null; json = decodeURIComponent(escape(json)); try { - return json.evalJSON(this.request.options.sanitizeJSON); + return json.evalJSON(this.request.options.sanitizeJSON || + !this.request.isSameOrigin()); } catch (e) { this.request.dispatchException(e); } @@ -1417,10 +1411,12 @@ Ajax.Response = Class.create({ _getResponseJSON: function() { var options = this.request.options; if (!options.evalJSON || (options.evalJSON != 'force' && - !(this.getHeader('Content-type') || '').include('application/json'))) - return null; + !(this.getHeader('Content-type') || '').include('application/json')) || + this.responseText.blank()) + return null; try { - return this.transport.responseText.evalJSON(options.sanitizeJSON); + return this.responseText.evalJSON(options.sanitizeJSON || + !this.request.isSameOrigin()); } catch (e) { this.request.dispatchException(e); } @@ -1434,11 +1430,11 @@ Ajax.Updater = Class.create(Ajax.Request, { failure: (container.failure || (container.success ? null : container)) }; - options = options || { }; + options = Object.clone(options); var onComplete = options.onComplete; - options.onComplete = (function(response, param) { + options.onComplete = (function(response, json) { this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, param); + if (Object.isFunction(onComplete)) onComplete(response, json); }).bind(this); $super(url, options); @@ -1460,10 +1456,6 @@ Ajax.Updater = Class.create(Ajax.Request, { } else receiver.update(responseText); } - - if (this.success()) { - if (this.onComplete) this.onComplete.bind(this).defer(); - } } }); @@ -1628,24 +1620,28 @@ Element.Methods = { Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) insertions = {bottom:insertions}; - var content, t, range; + var content, insert, tagName, childNodes; - for (position in insertions) { + for (var position in insertions) { content = insertions[position]; position = position.toLowerCase(); - t = Element._insertionTranslations[position]; + insert = Element._insertionTranslations[position]; if (content && content.toElement) content = content.toElement(); if (Object.isElement(content)) { - t.insert(element, content); + insert(element, content); continue; } content = Object.toHTML(content); - range = element.ownerDocument.createRange(); - t.initializeRange(element, range); - t.insert(element, range.createContextualFragment(content.stripScripts())); + tagName = ((position == 'before' || position == 'after') + ? element.parentNode : element).tagName.toUpperCase(); + + childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); + + if (position == 'top' || position == 'after') childNodes.reverse(); + childNodes.each(insert.curry(element)); content.evalScripts.bind(content).defer(); } @@ -1690,7 +1686,7 @@ Element.Methods = { }, descendants: function(element) { - return $A($(element).getElementsByTagName('*')).each(Element.extend); + return $(element).select("*"); }, firstDescendant: function(element) { @@ -1729,32 +1725,31 @@ Element.Methods = { element = $(element); if (arguments.length == 1) return $(element.parentNode); var ancestors = element.ancestors(); - return expression ? Selector.findElement(ancestors, expression, index) : - ancestors[index || 0]; + return Object.isNumber(expression) ? ancestors[expression] : + Selector.findElement(ancestors, expression, index); }, down: function(element, expression, index) { element = $(element); if (arguments.length == 1) return element.firstDescendant(); - var descendants = element.descendants(); - return expression ? Selector.findElement(descendants, expression, index) : - descendants[index || 0]; + return Object.isNumber(expression) ? element.descendants()[expression] : + element.select(expression)[index || 0]; }, previous: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); var previousSiblings = element.previousSiblings(); - return expression ? Selector.findElement(previousSiblings, expression, index) : - previousSiblings[index || 0]; + return Object.isNumber(expression) ? previousSiblings[expression] : + Selector.findElement(previousSiblings, expression, index); }, next: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); var nextSiblings = element.nextSiblings(); - return expression ? Selector.findElement(nextSiblings, expression, index) : - nextSiblings[index || 0]; + return Object.isNumber(expression) ? nextSiblings[expression] : + Selector.findElement(nextSiblings, expression, index); }, select: function() { @@ -1795,10 +1790,11 @@ Element.Methods = { var attributes = { }, t = Element._attributeTranslations.write; if (typeof name == 'object') attributes = name; - else attributes[name] = value === undefined ? true : value; + else attributes[name] = Object.isUndefined(value) ? true : value; for (var attr in attributes) { - var name = t.names[attr] || attr, value = attributes[attr]; + name = t.names[attr] || attr; + value = attributes[attr]; if (t.values[attr]) name = t.values[attr](element, value); if (value === false || value === null) element.removeAttribute(name); @@ -1867,6 +1863,7 @@ Element.Methods = { descendantOf: function(element, ancestor) { element = $(element), ancestor = $(ancestor); + var originalAncestor = ancestor; if (element.compareDocumentPosition) return (element.compareDocumentPosition(ancestor) & 8) === 8; @@ -1878,11 +1875,12 @@ Element.Methods = { do { ancestor = ancestor.parentNode; } while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode); } - if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex); + if (nextAncestor && nextAncestor.sourceIndex) + return (e > a && e < nextAncestor.sourceIndex); } while (element = element.parentNode) - if (element == ancestor) return true; + if (element == originalAncestor) return true; return false; }, @@ -1921,7 +1919,7 @@ Element.Methods = { if (property == 'opacity') element.setOpacity(styles[property]); else elementStyle[(property == 'float' || property == 'cssFloat') ? - (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : + (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : property] = styles[property]; return element; @@ -2022,7 +2020,7 @@ Element.Methods = { if (element) { if (element.tagName == 'BODY') break; var p = Element.getStyle(element, 'position'); - if (p == 'relative' || p == 'absolute') break; + if (p !== 'static') break; } } while (element); return Element._returnOffset(valueL, valueT); @@ -2171,72 +2169,75 @@ Element._attributeTranslations = { } }; - -if (!document.createRange || Prototype.Browser.Opera) { - Element.Methods.insert = function(element, insertions) { - element = $(element); - - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = { bottom: insertions }; - - var t = Element._insertionTranslations, content, position, pos, tagName; - - for (position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - pos = t[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - pos.insert(element, content); - continue; - } - - content = Object.toHTML(content); - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); - - if (t.tags[tagName]) { - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - if (position == 'top' || position == 'after') fragments.reverse(); - fragments.each(pos.insert.curry(element)); +if (Prototype.Browser.Opera) { + Element.Methods.getStyle = Element.Methods.getStyle.wrap( + function(proceed, element, style) { + switch (style) { + case 'left': case 'top': case 'right': case 'bottom': + if (proceed(element, 'position') === 'static') return null; + case 'height': case 'width': + // returns '0px' for hidden elements; we want it to return null + if (!Element.visible(element)) return null; + + // returns the border-box dimensions rather than the content-box + // dimensions, so we subtract padding and borders from the value + var dim = parseInt(proceed(element, style), 10); + + if (dim !== element['offset' + style.capitalize()]) + return dim + 'px'; + + var properties; + if (style === 'height') { + properties = ['border-top-width', 'padding-top', + 'padding-bottom', 'border-bottom-width']; + } + else { + properties = ['border-left-width', 'padding-left', + 'padding-right', 'border-right-width']; + } + return properties.inject(dim, function(memo, property) { + var val = proceed(element, property); + return val === null ? memo : memo - parseInt(val, 10); + }) + 'px'; + default: return proceed(element, style); } - else element.insertAdjacentHTML(pos.adjacency, content.stripScripts()); - - content.evalScripts.bind(content).defer(); } + ); - return element; - }; -} - -if (Prototype.Browser.Opera) { - Element.Methods._getStyle = Element.Methods.getStyle; - Element.Methods.getStyle = function(element, style) { - switch(style) { - case 'left': - case 'top': - case 'right': - case 'bottom': - if (Element._getStyle(element, 'position') == 'static') return null; - default: return Element._getStyle(element, style); + Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( + function(proceed, element, attribute) { + if (attribute === 'title') return element.title; + return proceed(element, attribute); } - }; - Element.Methods._readAttribute = Element.Methods.readAttribute; - Element.Methods.readAttribute = function(element, attribute) { - if (attribute == 'title') return element.title; - return Element._readAttribute(element, attribute); - }; + ); } else if (Prototype.Browser.IE) { - $w('positionedOffset getOffsetParent viewportOffset').each(function(method) { + // IE doesn't report offsets correctly for static elements, so we change them + // to "relative" to get the values, then change them back. + Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( + function(proceed, element) { + element = $(element); + var position = element.getStyle('position'); + if (position !== 'static') return proceed(element); + element.setStyle({ position: 'relative' }); + var value = proceed(element); + element.setStyle({ position: position }); + return value; + } + ); + + $w('positionedOffset viewportOffset').each(function(method) { Element.Methods[method] = Element.Methods[method].wrap( function(proceed, element) { element = $(element); var position = element.getStyle('position'); - if (position != 'static') return proceed(element); + if (position !== 'static') return proceed(element); + // Trigger hasLayout on the offset parent so that IE6 reports + // accurate offsetTop and offsetLeft values for position: fixed. + var offsetParent = element.getOffsetParent(); + if (offsetParent && offsetParent.getStyle('position') === 'fixed') + offsetParent.setStyle({ zoom: 1 }); element.setStyle({ position: 'relative' }); var value = proceed(element); element.setStyle({ position: position }); @@ -2301,7 +2302,7 @@ else if (Prototype.Browser.IE) { return node ? node.value : ""; }, _getEv: function(element, attribute) { - var attribute = element.getAttribute(attribute); + attribute = element.getAttribute(attribute); return attribute ? attribute.toString().slice(23, -2) : null; }, _flag: function(element, attribute) { @@ -2318,7 +2319,10 @@ else if (Prototype.Browser.IE) { }; Element._attributeTranslations.write = { - names: Object.clone(Element._attributeTranslations.read.names), + names: Object.extend({ + cellpadding: 'cellPadding', + cellspacing: 'cellSpacing' + }, Element._attributeTranslations.read.names), values: { checked: function(element, value) { element.checked = !!value; @@ -2398,7 +2402,7 @@ else if (Prototype.Browser.WebKit) { }; // Safari returns margins on body which is incorrect if the child is absolutely - // positioned. For performance reasons, redefine Position.cumulativeOffset for + // positioned. For performance reasons, redefine Element#cumulativeOffset for // KHTML/WebKit only. Element.Methods.cumulativeOffset = function(element) { var valueT = 0, valueL = 0; @@ -2438,7 +2442,7 @@ if (Prototype.Browser.IE || Prototype.Browser.Opera) { }; } -if (document.createElement('div').outerHTML) { +if ('outerHTML' in document.createElement('div')) { Element.Methods.replace = function(element, content) { element = $(element); @@ -2476,45 +2480,25 @@ Element._returnOffset = function(l, t) { Element._getContentFromAnonymousElement = function(tagName, html) { var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; - div.innerHTML = t[0] + html + t[1]; - t[2].times(function() { div = div.firstChild }); + if (t) { + div.innerHTML = t[0] + html + t[1]; + t[2].times(function() { div = div.firstChild }); + } else div.innerHTML = html; return $A(div.childNodes); }; Element._insertionTranslations = { - before: { - adjacency: 'beforeBegin', - insert: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - initializeRange: function(element, range) { - range.setStartBefore(element); - } + before: function(element, node) { + element.parentNode.insertBefore(node, element); }, - top: { - adjacency: 'afterBegin', - insert: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - initializeRange: function(element, range) { - range.selectNodeContents(element); - range.collapse(true); - } + top: function(element, node) { + element.insertBefore(node, element.firstChild); }, - bottom: { - adjacency: 'beforeEnd', - insert: function(element, node) { - element.appendChild(node); - } + bottom: function(element, node) { + element.appendChild(node); }, - after: { - adjacency: 'afterEnd', - insert: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - initializeRange: function(element, range) { - range.setStartAfter(element); - } + after: function(element, node) { + element.parentNode.insertBefore(node, element.nextSibling); }, tags: { TABLE: ['<table>', '</table>', 1], @@ -2526,7 +2510,6 @@ Element._insertionTranslations = { }; (function() { - this.bottom.initializeRange = this.top.initializeRange; Object.extend(this.tags, { THEAD: this.tags.TBODY, TFOOT: this.tags.TBODY, @@ -2687,10 +2670,11 @@ Element.addMethods = function(methods) { document.viewport = { getDimensions: function() { var dimensions = { }; + var B = Prototype.Browser; $w('width height').each(function(d) { var D = d.capitalize(); - dimensions[d] = self['inner' + D] || - (document.documentElement['client' + D] || document.body['client' + D]); + dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] : + (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D]; }); return dimensions; }, @@ -2719,9 +2703,26 @@ var Selector = Class.create({ this.compileMatcher(); }, + shouldUseXPath: function() { + if (!Prototype.BrowserFeatures.XPath) return false; + + var e = this.expression; + + // Safari 3 chokes on :*-of-type and :empty + if (Prototype.Browser.WebKit && + (e.include("-of-type") || e.include(":empty"))) + return false; + + // XPath can't do namespaced attributes, nor can it read + // the "checked" property from DOM nodes + if ((/(\[[\w-]*?:|:checked)/).test(this.expression)) + return false; + + return true; + }, + compileMatcher: function() { - // Selectors with namespaced attributes can't use the XPath version - if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression)) + if (this.shouldUseXPath()) return this.compileXPathMatcher(); var e = this.expression, ps = Selector.patterns, h = Selector.handlers, @@ -2844,8 +2845,12 @@ Object.extend(Selector, { }, className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", id: "[@id='#{1}']", - attrPresence: "[@#{1}]", + attrPresence: function(m) { + m[1] = m[1].toLowerCase(); + return new Template("[@#{1}]").evaluate(m); + }, attr: function(m) { + m[1] = m[1].toLowerCase(); m[3] = m[5] || m[6]; return new Template(Selector.xpath.operators[m[2]]).evaluate(m); }, @@ -2874,7 +2879,7 @@ Object.extend(Selector, { 'enabled': "[not(@disabled)]", 'not': function(m) { var e = m[6], p = Selector.patterns, - x = Selector.xpath, le, m, v; + x = Selector.xpath, le, v; var exclusion = []; while (e && le != e && (/\S/).test(e)) { @@ -2931,13 +2936,13 @@ Object.extend(Selector, { }, criteria: { - tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', - className: 'n = h.className(n, r, "#{1}", c); c = false;', - id: 'n = h.id(n, r, "#{1}", c); c = false;', - attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', + tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', + className: 'n = h.className(n, r, "#{1}", c); c = false;', + id: 'n = h.id(n, r, "#{1}", c); c = false;', + attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', attr: function(m) { m[3] = (m[5] || m[6]); - return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); + return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m); }, pseudo: function(m) { if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); @@ -2961,7 +2966,8 @@ Object.extend(Selector, { tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, id: /^#([\w\-\*]+)(\b|$)/, className: /^\.([\w\-\*]+)(\b|$)/, - pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/, + pseudo: +/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, attrPresence: /^\[([\w]+)\]/, attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }, @@ -2986,7 +2992,7 @@ Object.extend(Selector, { attr: function(element, matches) { var nodeValue = Element.readAttribute(element, matches[1]); - return Selector.operators[matches[2]](nodeValue, matches[3]); + return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]); } }, @@ -3001,14 +3007,15 @@ Object.extend(Selector, { // marks an array of nodes for counting mark: function(nodes) { + var _true = Prototype.emptyFunction; for (var i = 0, node; node = nodes[i]; i++) - node._counted = true; + node._countedByPrototype = _true; return nodes; }, unmark: function(nodes) { for (var i = 0, node; node = nodes[i]; i++) - node._counted = undefined; + node._countedByPrototype = undefined; return nodes; }, @@ -3016,15 +3023,15 @@ Object.extend(Selector, { // "ofType" flag indicates whether we're indexing for nth-of-type // rather than nth-child index: function(parentNode, reverse, ofType) { - parentNode._counted = true; + parentNode._countedByPrototype = Prototype.emptyFunction; if (reverse) { for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { var node = nodes[i]; - if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; } } else { for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) - if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; } }, @@ -3033,8 +3040,8 @@ Object.extend(Selector, { if (nodes.length == 0) return nodes; var results = [], n; for (var i = 0, l = nodes.length; i < l; i++) - if (!(n = nodes[i])._counted) { - n._counted = true; + if (!(n = nodes[i])._countedByPrototype) { + n._countedByPrototype = Prototype.emptyFunction; results.push(Element.extend(n)); } return Selector.handlers.unmark(results); @@ -3051,7 +3058,7 @@ Object.extend(Selector, { child: function(nodes) { var h = Selector.handlers; for (var i = 0, results = [], node; node = nodes[i]; i++) { - for (var j = 0, children = [], child; child = node.childNodes[j]; j++) + for (var j = 0, child; child = node.childNodes[j]; j++) if (child.nodeType == 1 && child.tagName != '!') results.push(child); } return results; @@ -3086,7 +3093,7 @@ Object.extend(Selector, { // TOKEN FUNCTIONS tagName: function(nodes, root, tagName, combinator) { - tagName = tagName.toUpperCase(); + var uTagName = tagName.toUpperCase(); var results = [], h = Selector.handlers; if (nodes) { if (combinator) { @@ -3099,7 +3106,7 @@ Object.extend(Selector, { if (tagName == "*") return nodes; } for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName.toUpperCase() == tagName) results.push(node); + if (node.tagName.toUpperCase() === uTagName) results.push(node); return results; } else return root.getElementsByTagName(tagName); }, @@ -3146,16 +3153,18 @@ Object.extend(Selector, { return results; }, - attrPresence: function(nodes, root, attr) { + attrPresence: function(nodes, root, attr, combinator) { if (!nodes) nodes = root.getElementsByTagName("*"); + if (nodes && combinator) nodes = this[combinator](nodes); var results = []; for (var i = 0, node; node = nodes[i]; i++) if (Element.hasAttribute(node, attr)) results.push(node); return results; }, - attr: function(nodes, root, attr, value, operator) { + attr: function(nodes, root, attr, value, operator, combinator) { if (!nodes) nodes = root.getElementsByTagName("*"); + if (nodes && combinator) nodes = this[combinator](nodes); var handler = Selector.operators[operator], results = []; for (var i = 0, node; node = nodes[i]; i++) { var nodeValue = Element.readAttribute(node, attr); @@ -3234,7 +3243,7 @@ Object.extend(Selector, { var h = Selector.handlers, results = [], indexed = [], m; h.mark(nodes); for (var i = 0, node; node = nodes[i]; i++) { - if (!node.parentNode._counted) { + if (!node.parentNode._countedByPrototype) { h.index(node.parentNode, reverse, ofType); indexed.push(node.parentNode); } @@ -3272,7 +3281,7 @@ Object.extend(Selector, { var exclusions = new Selector(selector).findElements(root); h.mark(exclusions); for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node._counted) results.push(node); + if (!node._countedByPrototype) results.push(node); h.unmark(exclusions); return results; }, @@ -3306,11 +3315,19 @@ Object.extend(Selector, { '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } }, + split: function(expression) { + var expressions = []; + expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { + expressions.push(m[1].strip()); + }); + return expressions; + }, + matchElements: function(elements, expression) { - var matches = new Selector(expression).findElements(), h = Selector.handlers; + var matches = $$(expression), h = Selector.handlers; h.mark(matches); for (var i = 0, results = [], element; element = elements[i]; i++) - if (element._counted) results.push(element); + if (element._countedByPrototype) results.push(element); h.unmark(matches); return results; }, @@ -3323,10 +3340,7 @@ Object.extend(Selector, { }, findChildElements: function(element, expressions) { - var exprs = expressions.join(','), expressions = []; - exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { - expressions.push(m[1].strip()); - }); + expressions = Selector.split(expressions.join(',')); var results = [], h = Selector.handlers; for (var i = 0, l = expressions.length, selector; i < l; i++) { selector = new Selector(expressions[i].strip()); @@ -3336,6 +3350,25 @@ Object.extend(Selector, { } }); +if (Prototype.Browser.IE) { + Object.extend(Selector.handlers, { + // IE returns comment nodes on getElementsByTagName("*"). + // Filter them out. + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + if (node.tagName !== "!") a.push(node); + return a; + }, + + // IE improperly serializes _countedByPrototype in (inner|outer)HTML. + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node.removeAttribute('_countedByPrototype'); + return nodes; + } + }); +} + function $$() { return Selector.findChildElements(document, $A(arguments)); } @@ -3347,7 +3380,7 @@ var Form = { serializeElements: function(elements, options) { if (typeof options != 'object') options = { hash: !!options }; - else if (options.hash === undefined) options.hash = true; + else if (Object.isUndefined(options.hash)) options.hash = true; var key, value, submitted = false, submit = options.submit; var data = elements.inject({ }, function(result, element) { @@ -3545,17 +3578,17 @@ Form.Element.Serializers = { }, inputSelector: function(element, value) { - if (value === undefined) return element.checked ? element.value : null; + if (Object.isUndefined(value)) return element.checked ? element.value : null; else element.checked = !!value; }, textarea: function(element, value) { - if (value === undefined) return element.value; + if (Object.isUndefined(value)) return element.value; else element.value = value; }, select: function(element, index) { - if (index === undefined) + if (Object.isUndefined(index)) return this[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element); else { @@ -3746,7 +3779,9 @@ Event.Methods = (function() { findElement: function(event, expression) { var element = Event.element(event); - return element.match(expression) ? element : element.up(expression); + if (!expression) return element; + var elements = [element].concat(element.ancestors()); + return Selector.findElement(elements, expression, 0); }, pointer: function(event) { @@ -3809,9 +3844,9 @@ Object.extend(Event, (function() { var cache = Event.cache; function getEventID(element) { - if (element._eventID) return element._eventID; + if (element._prototypeEventID) return element._prototypeEventID[0]; arguments.callee.id = arguments.callee.id || 1; - return element._eventID = ++arguments.callee.id; + return element._prototypeEventID = [++arguments.callee.id]; } function getDOMEventName(eventName) { @@ -3839,7 +3874,7 @@ Object.extend(Event, (function() { return false; Event.extend(event); - handler.call(element, event) + handler.call(element, event); }; wrapper.handler = handler; @@ -3921,11 +3956,12 @@ Object.extend(Event, (function() { if (element == document && document.createEvent && !element.dispatchEvent) element = document.documentElement; + var event; if (document.createEvent) { - var event = document.createEvent("HTMLEvents"); + event = document.createEvent("HTMLEvents"); event.initEvent("dataavailable", true, true); } else { - var event = document.createEventObject(); + event = document.createEventObject(); event.eventType = "ondataavailable"; } @@ -3938,7 +3974,7 @@ Object.extend(Event, (function() { element.fireEvent(event.eventType, event); } - return event; + return Event.extend(event); } }; })()); @@ -3954,20 +3990,21 @@ Element.addMethods({ Object.extend(document, { fire: Element.Methods.fire.methodize(), observe: Element.Methods.observe.methodize(), - stopObserving: Element.Methods.stopObserving.methodize() + stopObserving: Element.Methods.stopObserving.methodize(), + loaded: false }); (function() { /* Support for the DOMContentLoaded event is based on work by Dan Webb, Matthias Miller, Dean Edwards and John Resig. */ - var timer, fired = false; + var timer; function fireContentLoadedEvent() { - if (fired) return; + if (document.loaded) return; if (timer) window.clearInterval(timer); document.fire("dom:loaded"); - fired = true; + document.loaded = true; } if (document.addEventListener) { diff --git a/play/index.php b/play/index.php index b1e2b3f4..2750cec5 100644 --- a/play/index.php +++ b/play/index.php @@ -181,7 +181,7 @@ $song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type; /* If they are just trying to download make sure they have rights * and then present them with the download file */ -if ($_GET['action'] == 'download' AND $GLOBALS['user']->prefs['download']) { +if ($_GET['action'] == 'download' AND Config::get('download')) { // STUPID IE $song->format_pattern(); @@ -199,9 +199,9 @@ if ($_GET['action'] == 'download' AND $GLOBALS['user']->prefs['download']) { } // Check to see if we should be throttling because we can get away with it - if ($GLOBALS['user']->prefs['rate_limit'] > 0) { + if (Config::get('rate_limit') > 0) { while (!feof($fp)) { - echo fread($fp,round($GLOBALS['user']->prefs['rate_limit']*1024)); + echo fread($fp,round(Config::get('rate_limit')*1024)); flush(); sleep(1); } @@ -247,7 +247,7 @@ if (Config::get('downsample_remote')) { } // if downsample remote is enabled // If they are downsampling, or if the song is not a native stream or it's non-local -if (($GLOBALS['user']->prefs['transcode'] == 'always' || !$song->native_stream() || $not_local) && $GLOBALS['user']->prefs['transcode'] != 'never') { +if ((Config::get('transcode') == 'always' || !$song->native_stream() || $not_local) && Config::get('transcode') != 'never') { debug_event('downsample','Starting Downsample...','5'); $fp = Stream::start_downsample($song,$lastid,$song_name,$start); $song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type; @@ -340,7 +340,7 @@ else { /* Clean up any open ends */ -if ($GLOBALS['user']->prefs['play_type'] == 'downsample' || !$song->native_stream()) { +if (Config::get('play_type') == 'downsample' || !$song->native_stream()) { @pclose($fp); } else { diff --git a/preferences.php b/preferences.php index 5ce478b7..af1065c8 100644 --- a/preferences.php +++ b/preferences.php @@ -1,7 +1,7 @@ <?php /* - Copyright (c) 2001 - 2007 Ampache.org + Copyright (c) 2001 - 2008 Ampache.org All rights reserved. This program is free software; you can redistribute it and/or diff --git a/server/localplay.ajax.php b/server/localplay.ajax.php index a9ef949f..d5945a3a 100644 --- a/server/localplay.ajax.php +++ b/server/localplay.ajax.php @@ -34,7 +34,7 @@ switch ($_REQUEST['action']) { $type = $_REQUEST['instance'] ? 'localplay' : 'stream'; - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->set_active_instance($_REQUEST['instance']); Preference::update('play_type',$GLOBALS['user']->id,$type); @@ -54,7 +54,7 @@ switch ($_REQUEST['action']) { exit; } - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->connect(); // Switch on valid commands @@ -102,7 +102,7 @@ switch ($_REQUEST['action']) { debug_event('DENIED','Attempted to delete track without access','1'); exit; } - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->connect(); // Scrub in the delete request @@ -129,7 +129,7 @@ switch ($_REQUEST['action']) { } // Scrub it in - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->delete_instance($_REQUEST['instance']); $key = 'localplay_instance_' . $_REQUEST['instance']; @@ -143,7 +143,7 @@ switch ($_REQUEST['action']) { } // Scrub her in - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->connect(); $localplay->repeat(make_bool($_REQUEST['value'])); @@ -161,7 +161,7 @@ switch ($_REQUEST['action']) { } // Scrub her in - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $localplay->connect(); $localplay->random(make_bool($_REQUEST['value'])); diff --git a/server/stream.ajax.php b/server/stream.ajax.php index c92a654a..7983c2c7 100644 --- a/server/stream.ajax.php +++ b/server/stream.ajax.php @@ -57,7 +57,7 @@ switch ($_REQUEST['action']) { case 'basket': // We need to set the basket up! $_SESSION['iframe']['target'] = Config::get('web_path') . '/stream.php?action=basket&playlist_method=' . scrub_out($_REQUEST['playlist_method']); - $results['rfc3514'] = '<script type="text/javascript">reload_util("'.$_SESSION['iframe']['target'].'")</script>'; + $results['rfc3514'] = '<script type="text/javascript">reload_util(\''.$_SESSION['iframe']['target'] . '\');</script>'; break; default: $results['rfc3514'] = '0x1'; @@ -1,7 +1,7 @@ <?php /* - Copyright (c) 2001 - 2007 ampache.org + Copyright (c) 2001 - 2008 ampache.org All rights reserved. This program is free software; you can redistribute it and/or @@ -18,11 +18,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - require_once 'lib/init.php'; /* If we are running a demo, quick while you still can! */ if (Config::get('demo_mode') || !$GLOBALS['user']->has_access('25')) { + access_denied(); exit; } @@ -62,7 +62,7 @@ switch ($_REQUEST['action']) { } // end foreach // Check to see if 'clear' was passed if it was then we need to reset the basket - if ( ($_REQUEST['playlist_method'] == 'clear' || $GLOBALS['user']->prefs['playlist_method'] == 'clear') AND $GLOBALS['user']->prefs['play_method'] != 'xspf_player') { + if ( ($_REQUEST['playlist_method'] == 'clear' || Config::get('playlist_method') == 'clear') AND Config::get('play_method') != 'xspf_player') { $GLOBALS['user']->playlist->clear(); } @@ -179,15 +179,15 @@ switch ($_REQUEST['method']) { break; case 'democratic': // Don't let them loop it - if ($GLOBALS['user']->prefs['play_type'] == 'democratic') { - $GLOBALS['user']->prefs['play_type'] = 'stream'; + if (Config::get('play_type') == 'democratic') { + Config::set('play_type','stream','1'); } default: - if ($GLOBALS['user']->prefs['play_type'] == 'stream') { - $stream_type = $GLOBALS['user']->prefs['playlist_type']; + if (Config::get('play_type') == 'stream') { + $stream_type = Config::get('playlist_type'); } else { - $stream_type = $GLOBALS['user']->prefs['play_type']; + $stream_type = Config::get('play_type'); } break; } diff --git a/templates/list_header.inc.php b/templates/list_header.inc.php index 551c37bc..e9cad734 100644 --- a/templates/list_header.inc.php +++ b/templates/list_header.inc.php @@ -27,7 +27,7 @@ */ // Pull these variables out to allow shorthand (easier for lazy programmers) -$limit = $GLOBALS['user']->prefs['offset_limit'] ? $GLOBALS['user']->prefs['offset_limit'] : '25'; +$limit = Config::get('offset_limit') ? Config::get('offset_limit') : '25'; $start = Browse::$start; $total = Browse::$total_objects; $uid = Config::get('list_header_uid'); diff --git a/templates/rightbar.inc.php b/templates/rightbar.inc.php index bf1322e1..26ec3691 100644 --- a/templates/rightbar.inc.php +++ b/templates/rightbar.inc.php @@ -70,7 +70,7 @@ </ul> </li> </ul> -<?php if ($GLOBALS['user']->prefs['play_type'] == 'localplay') { require_once Config::get('prefix') . '/templates/show_localplay_control.inc.php'; } ?> +<?php if (Config::get('play_type') == 'localplay') { require_once Config::get('prefix') . '/templates/show_localplay_control.inc.php'; } ?> <ul id="rb_current_playlist"> <?php //FIXME :: this feels kludgy diff --git a/templates/show_localplay.inc.php b/templates/show_localplay.inc.php deleted file mode 100644 index 281a925c..00000000 --- a/templates/show_localplay.inc.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/* - - Copyright (c) 2001 - 2006 Ampache.org - All rights reserved. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -$web_path = conf('web_path'); -$localplay = init_localplay(); -?> -<?php show_box_top(ucfirst($localplay->type) . ' ' . _('Localplay')); ?> -<table> -<tr> - <td valign="top"> - <strong><?php echo _('Actions'); ?>:</strong><br /> - <?php if ($localplay->has_function('delete_all')) { ?> - <div><a class="button" href="<?php echo $web_path; ?>/localplay.php?action=delete_all"><?php echo _('Clear Playlist'); ?></a></div> - <?php } ?> - </td><td> - <?php $add_info = "&return=1"; ?> - <?php require_once(conf('prefix') . '/templates/show_localplay_status.inc.php'); ?> - </td> -</tr> -</table> -<?php show_box_bottom(); ?> - - -<?php show_box_top(_('Current Playlist')); ?> -<div id="lp_playlist"> -<?php require_once(conf('prefix') . '/templates/show_localplay_playlist.inc.php'); ?> -</div> -<?php show_box_bottom(); ?> diff --git a/templates/show_playlist_song_row.inc.php b/templates/show_playlist_song_row.inc.php index e96aa91b..dd92f0fb 100644 --- a/templates/show_playlist_song_row.inc.php +++ b/templates/show_playlist_song_row.inc.php @@ -28,7 +28,7 @@ <td class="cel_track"><?php echo $song->f_track; ?></td> <td class="cel_time"><?php echo $song->f_time; ?></td> <td class="cel_action"> - <?php if ($GLOBALS['user']->prefs['download']) { ?> + <?php if (Config::get('download')) { ?> <a href="<?php echo Config::get('web_path'); ?>/stream.php?action=download&song_id=<?php echo $song->id; ?>"> <?php echo get_user_icon('download',_('Download')); ?> </a> diff --git a/templates/show_playtype_switch.inc.php b/templates/show_playtype_switch.inc.php index 406329e5..7cc1ca88 100644 --- a/templates/show_playtype_switch.inc.php +++ b/templates/show_playtype_switch.inc.php @@ -20,7 +20,7 @@ */ ?> <?php -$name = "is_" . $GLOBALS['user']->prefs['play_type']; +$name = "is_" . Config::get('play_type'); ${$name} = 'selected="selected" '; if (Preference::has_access('play_type')) { @@ -42,6 +42,6 @@ if (Preference::has_access('play_type')) { <?php } // if they have access // Else just show what it currently is -else { echo ucwords($GLOBALS['user']->prefs['play_type']);} +else { echo ucwords(Config::get('play_type'));} ?> </div> diff --git a/templates/show_song_row.inc.php b/templates/show_song_row.inc.php index 1cf863e9..492fff9f 100644 --- a/templates/show_song_row.inc.php +++ b/templates/show_song_row.inc.php @@ -37,7 +37,7 @@ <?php echo get_user_icon('comment',_('Post Shout')); ?> </a> <?php } ?> - <?php if ($GLOBALS['user']->prefs['download']) { ?> + <?php if (Config::get('download')) { ?> <a href="<?php echo Config::get('web_path'); ?>/stream.php?action=download&song_id=<?php echo $song->id; ?>"> <?php echo get_user_icon('download',_('Download')); ?> </a> diff --git a/templates/sidebar_localplay.inc.php b/templates/sidebar_localplay.inc.php index ceaf6901..5e2e79ff 100644 --- a/templates/sidebar_localplay.inc.php +++ b/templates/sidebar_localplay.inc.php @@ -18,14 +18,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - ?> <ul class="sb2" id="sb_localplay"> -<?php if (Config::get('allow_localplay_playback') AND $GLOBALS['user']->prefs['localplay_controller'] AND Access::check('localplay','5')) { ?> +<?php if (Config::get('allow_localplay_playback') AND Config::get('localplay_controller') AND Access::check('localplay','5')) { ?> <?php // Little bit of work to be done here - $localplay = new Localplay($GLOBALS['user']->prefs['localplay_controller']); + $localplay = new Localplay(Config::get('localplay_controller')); $current_instance = $localplay->current_instance(); $class = $current_instance ? '' : ' class="active_instance"'; ?> @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +$wang = 'util'; require_once 'lib/init.php'; header("Expires: Tuesday, 27 Mar 1984 05:00:00 GMT"); |