JBoss Rich Faces SVN: r11210 - trunk/docs/userguide.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2008-11-18 08:55:18 -0500 (Tue, 18 Nov 2008)
New Revision: 11210
Modified:
trunk/docs/userguide/pom.xml
Log:
https://jira.jboss.org/jira/browse/RF-4107 - one resources folder was added
Modified: trunk/docs/userguide/pom.xml
===================================================================
--- trunk/docs/userguide/pom.xml 2008-11-18 13:54:25 UTC (rev 11209)
+++ trunk/docs/userguide/pom.xml 2008-11-18 13:55:18 UTC (rev 11210)
@@ -808,7 +808,7 @@
</sourceDocumentName>
<formats>
- <!--format>
+ <format>
<formatName>pdf</formatName>
<stylesheetResource>
classpath:/xslt/org/jboss/pdf.xsl
@@ -819,7 +819,7 @@
<imagePathSettingRequired>
true
</imagePathSettingRequired>
- </format-->
+ </format>
<format>
<formatName>html</formatName>
<stylesheetResource>
@@ -834,7 +834,7 @@
</imagePathSettingRequired>
</format>
- <!--format>
+ <format>
<formatName>html_single</formatName>
<stylesheetResource>
${xsl_html_single}
@@ -848,7 +848,7 @@
<finalName>
index.html
</finalName>
- </format-->
+ </format>
</formats>
<xincludeSupported>true</xincludeSupported>
<options>
17 years, 6 months
JBoss Rich Faces SVN: r11209 - in trunk/docs: common-resources/en/src/main/script and 16 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2008-11-18 08:54:25 -0500 (Tue, 18 Nov 2008)
New Revision: 11209
Added:
trunk/docs/common-resources/en/src/main/images/bg_table.gif
trunk/docs/common-resources/en/src/main/script/swift_lib/
trunk/docs/common-resources/en/src/main/script/swift_lib/EasySwift.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Address.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/AddressContainer.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/(a)PopB4Smtp.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/CRAMMD5.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/LOGIN.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PLAIN.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PopB4Smtp/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PopB4Smtp/Pop3Connection.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BadResponseException.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BatchMailer.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Disk.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/JointOutputStream.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Memory.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/OutputStream.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/CacheFactory.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ClassLoader.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Multi.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/NativeMail.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Rotator.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/SMTP.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Sendmail.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionBase.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionException.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeCommandListener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeSendListener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandEvent.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandListener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectEvent.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectListener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectEvent.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectListener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/Listener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ListenerMapper.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseEvent.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseListener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendEvent.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendListener.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Exception.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/File.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/FileException.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/Array.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/MySQLResult.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log/DefaultLog.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/LogContainer.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Attachment.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/EmbeddedFile.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Encoder.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Headers.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Image.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Mime.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/MimeException.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Part.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/AntiFlood.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/BandwidthMonitor.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/ConnectionRotator.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator/Replacements.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/EasySwiftResponseTracker.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/FileEmbedder.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/MailSend.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Throttler.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/AbstractView.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/DefaultView.php
trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/RecipientList.php
Removed:
trunk/docs/faq/en/src/main/resources/
Modified:
trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl
trunk/docs/faq/pom.xml
Log:
https://jira.jboss.org/jira/browse/RF-4107 - one resources folder was added
Added: trunk/docs/common-resources/en/src/main/images/bg_table.gif
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/bg_table.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/EasySwift.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/EasySwift.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/EasySwift.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,949 @@
+<?php
+
+/**
+ * EasySwift: Swift Mailer Facade
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package EasySwift
+ * @version 1.0.3
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/Swift/ClassLoader.php";
+Swift_ClassLoader::load("Swift");
+Swift_ClassLoader::load("Swift_Connection_SMTP");
+Swift_ClassLoader::load("Swift_Connection_Sendmail");
+
+//Some constants for backwards compatibility with v2 code
+if (!defined("SWIFT_TLS")) define("SWIFT_TLS", Swift_Connection_SMTP::ENC_TLS);
+if (!defined("SWIFT_SSL")) define("SWIFT_SSL", Swift_Connection_SMTP::ENC_SSL);
+if (!defined("SWIFT_OPEN")) define("SWIFT_OPEN", Swift_Connection_SMTP::ENC_OFF);
+if (!defined("SWIFT_SECURE_PORT")) define("SWIFT_SECURE_PORT", Swift_Connection_SMTP::PORT_SECURE);
+if (!defined("SWIFT_DEFAULT_PORT")) define("SWIFT_DEFAULT_PORT", Swift_Connection_SMTP::PORT_DEFAULT);
+
+/**
+ * EasySwift: Facade for Swift Mailer Version 3.
+ * Provides (most of) the API from older versions of Swift, wrapped around the new version 3 API.
+ * Due to the popularity of the new API, EasySwift will not be around indefinitely.
+ * @package EasySwift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @deprecated
+ */
+class EasySwift
+{
+ /**
+ * The instance of Swift this class wrappers
+ * @var Swift
+ */
+ public $swift = null;
+ /**
+ * This value becomes set to true when Swift fails
+ * @var boolean
+ */
+ public $failed = false;
+ /**
+ * The number of loaded plugins
+ * @var int
+ */
+ protected $pluginCount = 0;
+ /**
+ * An instance of Swift_Message
+ * @var Swift_Message
+ */
+ public $message = null;
+ /**
+ * An address list to send to (Cc, Bcc, To..)
+ * @var Swift_RecipientList
+ */
+ public $recipients = null;
+ /**
+ * If all recipients should get the same copy of the message, including headers
+ * This is already implied if any Cc or Bcc recipients are set
+ * @var boolean
+ */
+ protected $exactCopy = false;
+ /**
+ * If EasySwift should get rid of the message and recipients once it's done sending
+ * @var boolean
+ */
+ protected $autoFlush = true;
+ /**
+ * A list of the IDs of all parts added to the message
+ * @var array
+ */
+ protected $partIds = array();
+ /**
+ * A list of all the IDs of the attachments add to the message
+ * @var array
+ */
+ protected $attachmentIds = array();
+ /**
+ * The last response received from the server
+ * @var string
+ */
+ public $lastResponse = "";
+ /**
+ * The 3 digit code in the last response received from the server
+ * @var int
+ */
+ public $responseCode = 0;
+ /**
+ * The list of errors handled at runtime
+ * @var array
+ */
+ public $errors = array();
+ /**
+ * The last error received
+ * @var string
+ */
+ public $lastError = null;
+
+ /**
+ * Constructor
+ * @param Swift_Connection The connection to use
+ * @param string The domain name of this server (not the SMTP server)
+ */
+ public function __construct(Swift_Connection $connection, $domain=null)
+ {
+ try {
+ $this->swift = new Swift($connection, $domain, Swift::ENABLE_LOGGING);
+ Swift_ClassLoader::load("Swift_Plugin_EasySwiftResponseTracker");
+ $this->swift->attachPlugin(new Swift_Plugin_EasySwiftResponseTracker($this), "_ResponseTracker");
+ } catch (Swift_ConnectionException $e) {
+ $this->failed = true;
+ $this->setError("The connection failed to start. An exception was thrown:<br />" . $e->getMessage());
+ }
+ $this->newMessage();
+ $this->newRecipientList();
+ }
+ /**
+ * Set an error message
+ * @param string Error message
+ */
+ public function setError($msg)
+ {
+ $this->errors[] = ($this->lastError = $msg);
+ }
+ /**
+ * Get the full list of errors
+ * @return array
+ */
+ public function getErrors()
+ {
+ return $this->errors;
+ }
+ /**
+ * Get the last error that occured
+ * @return string
+ */
+ public function getLastError()
+ {
+ return $this->lastError;
+ }
+ /**
+ * Clear the current list of errors
+ */
+ public function flushErrors()
+ {
+ $this->errors = null;
+ $this->errors = array();
+ }
+ /**
+ * Turn automatic flsuhing on or off.
+ * This in ON by deault. It removes the message and all parts after sending.
+ * @param boolean
+ */
+ public function autoFlush($flush=true)
+ {
+ $this->autoFlush = $flush;
+ }
+ /**
+ * Set the maximum size of the log
+ * @param int
+ */
+ public function setMaxLogSize($size)
+ {
+ $log = Swift_LogContainer::getLog();
+ $log->setMaxSize($size);
+ }
+ /**
+ * Turn logging on or off (saves memory)
+ * @param boolean
+ */
+ public function useLogging($use=true)
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($use) $log->setLogLevel(Swift_Log::LOG_NETWORK);
+ else $log->setLogLevel(Swift_Log::LOG_NOTHING);
+ }
+ /**
+ * Enable line resizing (on 1000 by default)
+ * @param int The number of characters allowed on a line
+ */
+ public function useAutoLineResizing($size=1000)
+ {
+ $this->message->setLineWrap($size);
+ }
+ /**
+ * Dump the log contents
+ * @deprecated
+ */
+ public function getTransactions()
+ {
+ return $this->dumpLog();
+ }
+ /**
+ * Dump the contents of the log to the browser
+ * The log contains some < and > characters so you may need to view source
+ * Note that this method dumps data to the browser, it does NOT return anything.
+ */
+ public function dumpLog()
+ {
+ $log = Swift_LogContainer::getLog();
+ $log->dump();
+ }
+ /**
+ * This method should be called if you do not wish to send messages in batch mode (i.e. if all recipients should see each others' addresses)
+ * @param boolean If this mode should be used
+ */
+ public function useExactCopy($bool=true)
+ {
+ $this->exactCopy = $bool;
+ }
+ /**
+ * Reset the current message and start a fresh one
+ */
+ public function newMessage($msg=false)
+ {
+ if (!$msg) $msg = new Swift_Message();
+ $this->message = $msg;
+ $this->partIds = array();
+ $this->attachmentIds = array();
+ }
+ /**
+ * Clear out all message parts
+ * @return boolean
+ */
+ public function flushParts()
+ {
+ $success = true;
+ foreach ($this->partIds as $id)
+ {
+ try {
+ $this->message->detach($id);
+ } catch (Swift_Message_MimeException $e) {
+ $success = false;
+ $this->setError("A MIME part failed to detach due to the error:<br />" . $e->getMessage());
+ }
+ }
+ $this->partIds = array();
+ return $success;
+ }
+ /**
+ * Clear out all attachments
+ * @return boolean
+ */
+ public function flushAttachments()
+ {
+ $success = true;
+ foreach ($this->attachmentIds as $id)
+ {
+ try {
+ $this->message->detach($id);
+ } catch (Swift_Message_MimeException $e) {
+ $success = false;
+ $this->setError("An attachment failed to detach due to the error:<br />" . $e->getMessage());
+ }
+ }
+ $this->attachmentIds = array();
+ return $success;
+ }
+ /**
+ * Clear out all message headers
+ * @deprecated
+ */
+ public function flushHeaders()
+ {
+ $this->newMessage();
+ }
+ /**
+ * Reset the current list of recipients and start a new one
+ */
+ public function newRecipientList($list=false)
+ {
+ if (!$list) $list = new Swift_RecipientList();
+ $this->recipients = $list;
+ }
+ /**
+ * Check if Swift has failed or not
+ * This facade stops processing if so
+ * @return boolean
+ */
+ public function hasFailed()
+ {
+ return $this->failed;
+ }
+ /**
+ * Check if the current connection is open or not
+ * @return boolean
+ */
+ public function isConnected()
+ {
+ return (($this->swift !== null) && $this->swift->connection->isAlive());
+ }
+ /**
+ * Connect to the MTA if not already connected
+ */
+ public function connect()
+ {
+ if (!$this->isConnected())
+ {
+ try {
+ $this->swift->connect();
+ return true;
+ } catch (Swift_ConnectionException $e) {
+ $this->failed = true;
+ $this->setError("Swift failed to run the connection process:<br />" . $e->getMessage());
+ }
+ }
+ return false;
+ }
+ /**
+ * Perform the SMTP greeting process (don't do this unless you understand why you're doing it)
+ */
+ public function handshake()
+ {
+ $this->swift->handshake();
+ }
+ /**
+ * Close the connection to the MTA
+ * @return boolean
+ */
+ public function close()
+ {
+ if ($this->isConnected())
+ {
+ try {
+ $this->swift->disconnect();
+ return true;
+ } catch (Swift_ConnectionException $e) {
+ $this->setError("Disconnect failed:<br />" . $e->getMessage());
+ }
+ }
+ return false;
+ }
+ /**
+ * Send a command to Swift and get a response
+ * @param string The command to send (leave of CRLF)
+ * @return string
+ */
+ public function command($command)
+ {
+ if (substr($command, -2) == "\r\n") $command = substr($command, 0, -2);
+
+ try {
+ $rs = $this->swift->command($command);
+ return $rs->getString();
+ } catch (Swift_ConnectionException $e) {
+ $this->setError("Command failed:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ /**
+ * Add a new plugin to respond to events
+ * @param Swift_Events_Listener The plugin to load
+ * @param string The ID to identify the plugin by if needed
+ * @return string The ID of the plugin
+ */
+ public function loadPlugin(Swift_Events_Listener $plugin, $name=null)
+ {
+ $this->pluginCount++;
+ if (!$name) $name = "p" . $this->pluginCount;
+ $this->swift->attachPlugin($plugin, $name);
+ return $name;
+ }
+ /**
+ * Get a reference to the plugin identified by $name
+ * @param string the ID of the plugin
+ * @return Swift_Events_Listener
+ */
+ public function getPlugin($name)
+ {
+ try {
+ $plugin = $this->swift->getPlugin($name);
+ return $plugin;
+ } catch (Exception $e) {
+ return null;
+ }
+ }
+ /**
+ * Remove the plugin identified by $name
+ * @param string The ID of the plugin
+ * @return boolean
+ */
+ public function removePlugin($name)
+ {
+ try {
+ $this->swift->removePlugin($name);
+ return true;
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+ /**
+ * Load in a new authentication mechanism for SMTP
+ * This needn't be called since Swift will locate any available in Swift/Authenticator/*.php
+ * @param Swift_Authenticator The authentication mechanism to load
+ * @throws Exception If the wrong connection is used
+ */
+ public function loadAuthenticator(Swift_Authenticator $auth)
+ {
+ if (method_exists($this->swift->connection, "attachAuthenticator"))
+ {
+ $this->swift->connection->attachAuthenticator($auth);
+ }
+ else throw new Exception("SMTP authentication cannot be used with connection class '" . get_class($this->connection) . "'. Swift_Connection_SMTP is needed");
+ }
+ /**
+ * Authenticate with SMTP authentication
+ * @param string The SMTP username
+ * @param string The SMTP password
+ * @return boolean
+ * @throws Exception If the wrong connection is used
+ */
+ public function authenticate($username, $password)
+ {
+ if (method_exists($this->swift->connection, "runAuthenticators"))
+ {
+ try {
+ $this->swift->connection->runAuthenticators($username, $password, $this->swift);
+ return true;
+ } catch (Swift_ConnectionException $e) {
+ $this->setError("Authentication failed:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ else throw new Exception("SMTP authentication cannot be used with connection class '" . get_class($this->connection) . "'. Swift_Connection_SMTP is needed");
+ }
+ /**
+ * Turn a string representation of an email address into a Swift_Address object
+ * @paramm string The email address
+ * @return Swift_Address
+ */
+ public function stringToAddress($string)
+ {
+ $name = null;
+ $address = null;
+ // Foo Bar <foo@bar>
+ // or: "Foo Bar" <foo@bar>
+ // or: <foo@bar>
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if (preg_match("/^\\s*(\"?)(.*?)\\1 *<(" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . ")>\\s*\$/", $string, $matches))
+ {
+ if (!empty($matches[2])) $name = $matches[2];
+ $address = $matches[3];
+ }
+ elseif (preg_match("/^\\s*" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . "\\s*\$/", $string))
+ {
+ $address = trim($string);
+ }
+ else return false;
+
+ $swift_address = new Swift_Address($address, $name);
+ return $swift_address;
+ }
+ /**
+ * Set the encoding used in the message header
+ * The encoding can be one of Q (quoted-printable) or B (base64)
+ * @param string The encoding to use
+ */
+ public function setHeaderEncoding($mode="B")
+ {
+ switch (strtoupper($mode))
+ {
+ case "Q": case "QP": case "QUOTED-PRINTABLE":
+ $this->message->headers->setEncoding("Q");
+ break;
+ default:
+ $this->message->headers->setEncoding("B");
+ }
+ }
+ /**
+ * Set the return path address (where bounces go to)
+ * @param mixed The address as a string or Swift_Address
+ */
+ public function setReturnPath($address)
+ {
+ return $this->message->setReturnPath($address);
+ }
+ /**
+ * Request for a read recipient to be sent to the reply-to address
+ * @param boolean
+ */
+ public function requestReadReceipt($request=true)
+ {
+ //$this->message->requestReadReceipt(true);
+ }
+ /**
+ * Set the message priority
+ * This is an integer between 1 (high) and 5 (low)
+ * @param int The level of priority to use
+ */
+ public function setPriority($priority)
+ {
+ $this->message->setPriority($priority);
+ }
+ /**
+ * Get the return-path address as a string
+ * @return string
+ */
+ public function getReturnPath()
+ {
+ try {
+ return $this->message->getReturnPath();
+ } catch (Swift_Message_MimeException $e) {
+ return false;
+ }
+ }
+ /**
+ * Set the reply-to header
+ * @param mixed The address replies come to. String, or Swift_Address, or an array of either.
+ */
+ public function setReplyTo($address)
+ {
+ return $this->message->setReplyTo($address);
+ }
+ /**
+ * Get the reply-to address(es) as an array of strings
+ * @return array
+ */
+ public function getReplyTo()
+ {
+ try {
+ return $this->message->getReplyTo();
+ } catch (Swift_Message_MimeException $e) {
+ return false;
+ }
+ }
+ /**
+ * Add To: recipients to the email
+ * @param mixed To address(es)
+ * @return boolean
+ */
+ public function addTo($address)
+ {
+ return $this->addRecipients($address, "To");
+ }
+ /**
+ * Get an array of To addresses
+ * This currently returns an array of Swift_Address objects and may be simplified to an array of strings in later versions
+ * @return array
+ */
+ public function getToAddresses()
+ {
+ return $this->recipients->getTo();
+ }
+ /**
+ * Clear out all To: recipients
+ */
+ public function flushTo()
+ {
+ $this->recipients->flushTo();
+ }
+ /**
+ * Add Cc: recipients to the email
+ * @param mixed Cc address(es)
+ * @return boolean
+ */
+ public function addCc($address)
+ {
+ return $this->addRecipients($address, "Cc");
+ }
+ /**
+ * Get an array of Cc addresses
+ * This currently returns an array of Swift_Address objects and may be simplified to an array of strings in later versions
+ * @return array
+ */
+ public function getCcAddresses()
+ {
+ return $this->recipients->getCc();
+ }
+ /**
+ * Clear out all Cc: recipients
+ */
+ public function flushCc()
+ {
+ $this->recipients->flushCc();
+ }
+ /**
+ * Add Bcc: recipients to the email
+ * @param mixed Bcc address(es)
+ * @return boolean
+ */
+ public function addBcc($address)
+ {
+ return $this->addRecipients($address, "Bcc");
+ }
+ /**
+ * Get an array of Bcc addresses
+ * This currently returns an array of Swift_Address objects and may be simplified to an array of strings in later versions
+ * @return array
+ */
+ public function getBccAddresses()
+ {
+ return $this->recipients->getBcc();
+ }
+ /**
+ * Clear out all Bcc: recipients
+ */
+ public function flushBcc()
+ {
+ $this->recipients->flushBcc();
+ }
+ /**
+ * Add recipients to the email
+ * @param mixed Address(es)
+ * @param string Recipient type (To, Cc, Bcc)
+ * @return boolean
+ */
+ protected function addRecipients($address, $type)
+ {
+ if (!in_array($type, array("To", "Cc", "Bcc"))) return false;
+ $method = "add" . $type;
+
+ if ($address instanceof Swift_Address)
+ {
+ $this->recipients->$method($address);
+ return true;
+ }
+ else
+ {
+ $added = 0;
+ foreach ((array)$address as $addr)
+ {
+ if (is_array($addr))
+ {
+ $addr = array_values($addr);
+ if (count($addr) >= 2)
+ {
+ $this->recipients->$method($addr[0], $addr[1]);
+ $added++;
+ continue;
+ }
+ elseif (count($addr) == 1) $addr = $addr[0];
+ else continue;
+ }
+
+ if (is_string($addr))
+ {
+ $addr = $this->stringToAddress($addr);
+ $this->recipients->$method($addr);
+ $added++;
+ }
+ }
+ return ($added > 0);
+ }
+ }
+ /**
+ * Flush message, recipients and headers
+ */
+ public function flush()
+ {
+ $this->newMessage();
+ $this->newRecipientList();
+ }
+ /**
+ * Get a list of any addresses which have failed since instantiation
+ * @return array
+ */
+ public function getFailedRecipients()
+ {
+ $log = Swift_LogContainer::getLog();
+ return $log->getFailedRecipients();
+ }
+ /**
+ * Set the multipart MIME warning message (only seen by old clients)
+ * @param string The message to show
+ */
+ public function setMimeWarning($text)
+ {
+ $this->message->setMimeWarning($text);
+ }
+ /**
+ * Get the currently set MIME warning (seen by old clients)
+ * @return string
+ */
+ public function getMimeWarning()
+ {
+ return $this->message->getMimeWarning();
+ }
+ /**
+ * Set the charset of the charset to use in the message
+ * @param string The charset (e.g. utf-8, iso-8859-1 etc)
+ * @return boolean
+ */
+ public function setCharset($charset)
+ {
+ try {
+ $this->message->setCharset($charset);
+ return true;
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("Unable to set the message charset:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ /**
+ * Get the charset of the charset to use in the message
+ * @return string
+ */
+ public function getCharset()
+ {
+ return $this->message->getCharset();
+ }
+ /**
+ * Add a new MIME part to the message
+ * @param mixed The part to add. If this is a string it's used as the body. If it's an instance of Swift_Message_Part it's used as the entire part
+ * @param string Content-type, default text/plain
+ * @param string The encoding used (default is to let Swift decide)
+ * @param string The charset to use (default is to let swift decide)
+ */
+ public function addPart($body, $type="text/plain", $encoding=null, $charset=null)
+ {
+ if ($body instanceof Swift_Message_Mime)
+ {
+ try {
+ $this->partIds[] = $this->message->attach($body);
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("A MIME part failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ else
+ {
+ try {
+ $this->partIds[] = $this->message->attach(new Swift_Message_Part($body, $type, $encoding, $charset));
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("A MIME part failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ }
+ /**
+ * Add a new attachment to the message
+ * @param mixed The attachment to add. If this is a string it's used as the file contents. If it's an instance of Swift_Message_Attachment it's used as the entire part. If it's an instance of Swift_File it's used as the contents.
+ * @param string Filename, optional
+ * @param string Content-type. Default application/octet-stream
+ * @param string The encoding used (default is base64)
+ * @return boolean
+ */
+ public function addAttachment($data, $filename=null, $type="application/octet-stream", $encoding=null)
+ {
+ if ($data instanceof Swift_Message_Mime)
+ {
+ try {
+ $this->attachmentIds[] = $this->message->attach($data);
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ else
+ {
+ try {
+ $this->attachmentIds[] = $this->message->attach(new Swift_Message_Attachment($data, $filename, $type, $encoding));
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("An attachment failed to attach<br />" . $e->getMessage());
+ return false;
+ } catch (Swift_FileException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Embed an image into the message and get the src attribute for HTML
+ * Returns FALSE on failure
+ * @param mixed The path to the image, a Swift_Message_Image object or a Swift_File object
+ * @return string
+ */
+ public function addImage($input)
+ {
+ $ret = false;
+ if ($input instanceof Swift_Message_Image)
+ {
+ $ret = $this->message->attach($input);
+ $this->attachmentIds[] = $ret;
+ return $ret;
+ }
+ elseif ($input instanceof Swift_File)
+ {
+ try {
+ $ret = $this->message->attach(new Swift_Message_Image($input));
+ $this->attachmentIds[] = $ret;
+ return $ret;
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ } catch (Swift_FileException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ else
+ {
+ try {
+ $ret = $this->message->attach(new Swift_Message_Image(new Swift_File($input)));
+ $this->attachmentIds[] = $ret;
+ return $ret;
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ } catch (Swift_FileException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ }
+ /**
+ * Embed an inline file into the message, such as a Image or MIDI file
+ * @param mixed The file contents, Swift_File object or Swift_Message_EmbeddedFile object
+ * @param string The content-type of the file, optional
+ * @param string The filename to use, optional
+ * @param string the Content-ID to use, optional
+ * @return string
+ */
+ public function embedFile($data, $type="application/octet-stream", $filename=null, $cid=null)
+ {
+ $ret = false;
+ if ($data instanceof Swift_Message_EmbeddedFile)
+ {
+ $ret = $this->message->attach($data);
+ $this->attachmentIds[] = $ret;
+ return $ret;
+ }
+ elseif ($data instanceof Swift_File)
+ {
+ try {
+ $ret = $this->message->attach(new Swift_Message_EmbeddedFile($data, $filename, $type, $cid));
+ $this->attachmentIds[] = $ret;
+ return $ret;
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ } catch (Swift_FileException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ else
+ {
+ try {
+ $ret = $this->message->attach(new Swift_Message_EmbeddedFile($data, $filename, $type, $cid));
+ $this->attachmentIds[] = $ret;
+ return $ret;
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ } catch (Swift_FileException $e) {
+ $this->setError("An attachment failed to attach:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+ }
+ /**
+ * Add headers to the message
+ * @param string The message headers to append, separated by CRLF
+ * @deprecated
+ */
+ public function addHeaders($string)
+ {
+ //Split at the line ending only if it's not followed by LWSP (as in, a full header)
+ $headers = preg_split("~\r?\n(?![ \t])~", $string);
+ foreach ($headers as $header)
+ {
+ if (empty($header)) continue;
+ //Get the bit before the colon
+ $header_name = substr($header, 0, ($c_pos = strpos($header, ": ")));
+ // ... and trim it away
+ $header = substr($header, $c_pos+2);
+ //Try splitting at "; " for attributes
+ $attribute_pairs = preg_split("~\\s*;\\s+~", $header);
+ //The value would always be right after the colon
+ $header_value = $attribute_pairs[0];
+ $this->message->headers->set($header_name, $header_value);
+ unset($attribute_pairs[0]);
+ foreach ($attribute_pairs as $pair)
+ {
+ //Now try finding the attribute name, and it's value (removing quotes)
+ if (preg_match("~^(.*?)=(\"?)(.*?)\\2\\s*\$~", $pair, $matches))
+ {
+ try {
+ $this->message->headers->setAttribute($header_name, $matches[1], $matches[3]);
+ } catch (Swift_Message_MimeException $e) {
+ $this->setError("There was a problem parsing or setting a header attribute:<br />" . $e->getMessage());
+ //Ignored... it's EasySwift... C'mon ;)
+ }
+ }
+ }
+ }
+ }
+ /**
+ * Set a header in the message
+ * @param string The name of the header
+ * @param string The value of the header (without attributes)
+ * @see {addHeaderAttribute}
+ */
+ public function setHeader($name, $value)
+ {
+ $this->message->headers->set($name, $value);
+ }
+ /**
+ * Set an attribute in the message headers
+ * For example charset in Content-Type: text/html; charset=utf-8 set by $swift->setHeaderAttribute("Content-Type", "charset", "utf-8")
+ * @param string The name of the header
+ * @param string The name of the attribute
+ * @param string The value of the attribute
+ */
+ public function setHeaderAttribute($name, $attribute, $value)
+ {
+ if ($this->message->headers->has($name))
+ $this->message->headers->setAttribute($name, $attribute, $value);
+ }
+ /**
+ * Send an email to a number of recipients
+ * Returns the number of successful recipients, or FALSE on failure
+ * @param mixed The recipients to send to. One of string, array, 2-dimensional array or Swift_Address
+ * @param mixed The address to send from. string or Swift_Address
+ * @param string The message subject
+ * @param string The message body, optional
+ * @return int
+ */
+ public function send($recipients, $from, $subject, $body=null)
+ {
+ $this->addTo($recipients);
+
+ $sender = false;
+ if (is_string($from)) $sender = $this->stringToAddress($from);
+ elseif ($from instanceof Swift_Address) $sender = $from;
+ if (!$sender) return false;
+
+ $this->message->setSubject($subject);
+ if ($body) $this->message->setBody($body);
+ try {
+ if (!$this->exactCopy && !$this->recipients->getCc() && !$this->recipients->getBcc())
+ {
+ $sent = $this->swift->batchSend($this->message, $this->recipients, $sender);
+ }
+ else
+ {
+ $sent = $this->swift->send($this->message, $this->recipients, $sender);
+ }
+ if ($this->autoFlush) $this->flush();
+ return $sent;
+ } catch (Swift_ConnectionException $e) {
+ $this->setError("Sending failed:<br />" . $e->getMessage());
+ return false;
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/EasySwift.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Address.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Address.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Address.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * Swift Mailer Address Container (purely for rigid RFC conformance)
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_AddressContainer");
+
+/**
+ * Swift_Address is just a lone e-mail address reprsented as an object
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Address extends Swift_AddressContainer
+{
+ /**
+ * The e-mail address portion
+ * @var string
+ */
+ protected $address = null;
+ /**
+ * The personal name part
+ * @var string
+ */
+ protected $name = null;
+
+ /**
+ * Constructor
+ * @param string The address portion
+ * @param string The personal name, optional
+ */
+ public function __construct($address, $name=null)
+ {
+ $this->setAddress($address);
+ if ($name !== null) $this->setName($name);
+ }
+ /**
+ * Set the email address
+ * @param string
+ */
+ public function setAddress($address)
+ {
+ $this->address = trim((string)$address);
+ }
+ /**
+ * Get the address portion
+ * @return string
+ */
+ public function getAddress()
+ {
+ return $this->address;
+ }
+ /**
+ * Set the personal name
+ * @param string
+ */
+ public function setName($name)
+ {
+ if ($name !== null) $this->name = (string) $name;
+ else $this->name = null;
+ }
+ /**
+ * Get personal name portion
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+ /**
+ * Build the address the way it should be structured
+ * @param boolean If the string will be sent to a SMTP server as an envelope
+ * @return string
+ */
+ public function build($smtp=false)
+ {
+ if ($smtp)
+ {
+ return "<" . $this->address . ">";
+ }
+ else
+ {
+ if (($this->name !== null))
+ {
+ return $this->name . " <" . $this->address . ">";
+ }
+ else return $this->address;
+ }
+ }
+ /**
+ * PHP's casting conversion
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->build(true);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Address.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/AddressContainer.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/AddressContainer.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/AddressContainer.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * This is purely here for identify reasons on some subclasses
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+abstract class Swift_AddressContainer {}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/AddressContainer.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/(a)PopB4Smtp.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/(a)PopB4Smtp.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/(a)PopB4Smtp.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * Swift Mailer PopB4Smtp Authenticator Mechanism
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Authenticator
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Authenticator");
+Swift_ClassLoader::load("Swift_LogContainer");
+
+/**
+ * Swift PopB4Smtp Authenticator
+ * This form of authentication requires a quick connection to be made with a POP3 server before finally connecting to SMTP
+ * @package Swift_Authenticator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Authenticator_PopB4Smtp implements Swift_Authenticator
+{
+ protected $connection = null;
+ /**
+ * Constructor
+ * @param mixed Swift_Authenticator_PopB4Smtp_Pop3Connection or string FQDN of POP3 server
+ * @param int The remote port number
+ * @param int The level of encryption to use
+ */
+ public function __construct($conn=null, $port=110, $encryption=0)
+ {
+ if (is_object($conn)) $this->connection = $conn;
+ else
+ {
+ Swift_ClassLoader::load("Swift_Authenticator_PopB4Smtp_Pop3Connection");
+ $this->connection = new Swift_Authenticator_PopB4Smtp_Pop3Connection($conn, $port, $encryption);
+ }
+ }
+ /**
+ * Try to authenticate using the username and password
+ * Returns false on failure
+ * @param string The username
+ * @param string The password
+ * @param Swift The instance of Swift this authenticator is used in
+ * @return boolean
+ */
+ public function isAuthenticated($user, $pass, Swift $swift)
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Trying POP3 Before SMTP authentication. Disconnecting from SMTP first.");
+ }
+ $swift->disconnect();
+ try {
+ $this->connection->start();
+ $this->connection->assertOk($this->connection->read());
+ $this->connection->write("USER " . $user);
+ $this->connection->assertOk($this->connection->read());
+ $this->connection->write("PASS " . $pass);
+ $this->connection->assertOk($this->connection->read());
+ $this->connection->write("QUIT");
+ $this->connection->assertOk($this->connection->read());
+ $this->connection->stop();
+ } catch (Swift_ConnectionException $e) {
+ if ($log->hasLevel(Swift_Log::LOG_ERRORS))
+ {
+ $log->add("POP3 authentication failed.");
+ }
+ return false;
+ }
+ $options = $swift->getOptions();
+ $swift->setOptions($options | Swift::NO_POST_CONNECT);
+ $swift->connect();
+ $swift->setOptions($options);
+ return true;
+ }
+ /**
+ * Return the name of the AUTH extension this is for
+ * @return string
+ */
+ public function getAuthExtensionName()
+ {
+ return "*PopB4Smtp";
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/(a)PopB4Smtp.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/CRAMMD5.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/CRAMMD5.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/CRAMMD5.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * Swift Mailer CRAM-MD5 Authenticator Mechanism
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Authenticator
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Authenticator");
+
+/**
+ * Swift CRAM-MD5 Authenticator
+ * This form of authentication is a secure challenge-response method
+ * @package Swift_Authenticator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Authenticator_CRAMMD5 implements Swift_Authenticator
+{
+ /**
+ * Try to authenticate using the username and password
+ * Returns false on failure
+ * @param string The username
+ * @param string The password
+ * @param Swift The instance of Swift this authenticator is used in
+ * @return boolean
+ */
+ public function isAuthenticated($user, $pass, Swift $swift)
+ {
+ try {
+ $encoded_challenge = substr($swift->command("AUTH CRAM-MD5", 334)->getString(), 4);
+ $challenge = base64_decode($encoded_challenge);
+ $response = base64_encode($user . " " . self::generateCRAMMD5Hash($pass, $challenge));
+ $swift->command($response, 235);
+ } catch (Swift_ConnectionException $e) {
+ $swift->reset();
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Return the name of the AUTH extension this is for
+ * @return string
+ */
+ public function getAuthExtensionName()
+ {
+ return "CRAM-MD5";
+ }
+ /**
+ * Generate a CRAM-MD5 hash from a challenge
+ * @param string The string to get a hash from
+ * @param string The challenge to use to make the hash
+ * @return string
+ */
+ public static function generateCRAMMD5Hash($password, $challenge)
+ {
+ if (strlen($password) > 64)
+ $password = pack('H32', md5($password));
+
+ if (strlen($password) < 64)
+ $password = str_pad($password, 64, chr(0));
+
+ $k_ipad = substr($password, 0, 64) ^ str_repeat(chr(0x36), 64);
+ $k_opad = substr($password, 0, 64) ^ str_repeat(chr(0x5C), 64);
+
+ $inner = pack('H32', md5($k_ipad.$challenge));
+ $digest = md5($k_opad.$inner);
+
+ return $digest;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/CRAMMD5.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/LOGIN.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/LOGIN.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/LOGIN.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * Swift Mailer LOGIN Authenticator Mechanism
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Authenticator
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Authenticator");
+
+/**
+ * Swift LOGIN Authenticator
+ * @package Swift_Authenticator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Authenticator_LOGIN implements Swift_Authenticator
+{
+ /**
+ * Try to authenticate using the username and password
+ * Returns false on failure
+ * @param string The username
+ * @param string The password
+ * @param Swift The instance of Swift this authenticator is used in
+ * @return boolean
+ */
+ public function isAuthenticated($user, $pass, Swift $swift)
+ {
+ try {
+ $swift->command("AUTH LOGIN", 334);
+ $swift->command(base64_encode($user), 334);
+ $swift->command(base64_encode($pass), 235);
+ } catch (Swift_ConnectionException $e) {
+ $swift->reset();
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Return the name of the AUTH extension this is for
+ * @return string
+ */
+ public function getAuthExtensionName()
+ {
+ return "LOGIN";
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/LOGIN.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PLAIN.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PLAIN.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PLAIN.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Swift Mailer PLAIN Authenticator Mechanism
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Authenticator
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Authenticator");
+
+/**
+ * Swift PLAIN Authenticator
+ * This form of authentication is unbelievably insecure since everything is done plain-text
+ * @package Swift_Authenticator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Authenticator_PLAIN implements Swift_Authenticator
+{
+ /**
+ * Try to authenticate using the username and password
+ * Returns false on failure
+ * @param string The username
+ * @param string The password
+ * @param Swift The instance of Swift this authenticator is used in
+ * @return boolean
+ */
+ public function isAuthenticated($user, $pass, Swift $swift)
+ {
+ try {
+ //The authorization string uses ascii null as a separator (See RFC 2554)
+ $credentials = base64_encode($user . chr(0) . $user . chr(0) . $pass);
+ $swift->command("AUTH PLAIN " . $credentials, 235);
+ } catch (Swift_ConnectionException $e) {
+ $swift->reset();
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Return the name of the AUTH extension this is for
+ * @return string
+ */
+ public function getAuthExtensionName()
+ {
+ return "PLAIN";
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PLAIN.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PopB4Smtp/Pop3Connection.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PopB4Smtp/Pop3Connection.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PopB4Smtp/Pop3Connection.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,176 @@
+<?php
+
+/**
+ * Swift Mailer PopB4Smtp Pop3 Connection component
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Authenticator
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../../ClassLoader.php";
+
+/**
+ * Swift PopB4Smtp Authenticator Connection Component for the POP3 server
+ * Provides a I/O wrapper for the POP3 connection
+ * @package Swift_Authenticator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Authenticator_PopB4Smtp_Pop3Connection
+{
+ /**
+ * Constant for no encyption
+ */
+ const ENC_OFF = 0;
+ /**
+ * Constant for SSL encryption
+ */
+ const ENC_SSL = 1;
+ /**
+ * The server to connect to (IP or FQDN)
+ * @var string
+ */
+ protected $server = null;
+ /**
+ * The port to connect to
+ * @var int
+ */
+ protected $port = null;
+ /**
+ * The open connection resource from fsockopen()
+ * @var resource
+ */
+ protected $handle = null;
+
+ /**
+ * Constructor
+ * @param string The name of the POP3 server
+ * @param int The port for the POP3 service
+ * @param int The level of encryption to use
+ */
+ public function __construct($server="localhost", $port=110, $encryption=0)
+ {
+ $this->setServer($server);
+ $this->setPort($port);
+ $this->setEncryption($encryption);
+ }
+ /**
+ * Set the server name
+ * @param string The IP or FQDN of the POP3 server
+ */
+ public function setServer($server)
+ {
+ $this->server = (string) $server;
+ }
+ /**
+ * Set the port number for the POP3 server
+ * @param int
+ */
+ public function setPort($port)
+ {
+ $this->port = (int) $port;
+ }
+ /**
+ * Get the server name
+ * @return string
+ */
+ public function getServer()
+ {
+ return $this->server;
+ }
+ /**
+ * Get the remote port number
+ * @return int
+ */
+ public function getPort()
+ {
+ return $this->port;
+ }
+ /**
+ * Set the level of enryption to use (see ENC_OFF or ENC_SSL)
+ * @param int The constant for the encryption level
+ */
+ public function setEncryption($enc)
+ {
+ $this->encryption = (int) $enc;
+ }
+ /**
+ * Get the current encryption level set (corresponds to ENC_SSL or ENC_OFF)
+ * @return int
+ */
+ public function getEncryption()
+ {
+ return $this->encryption;
+ }
+ /**
+ * Check if the response is a +OK response
+ * @throws Swift_ConnectionException Upon bad response
+ */
+ public function assertOk($line)
+ {
+ if (substr($line, 0, 3) != "+OK")
+ {
+ Swift_ClassLoader::load("Swift_ConnectionException");
+ throw new Swift_ConnectionException("The POP3 server did not suitably respond with a +OK response. " .
+ "[" . $line . "]");
+ }
+ }
+ /**
+ * Try to open the connection
+ * @throws Swift_ConnectionException If the connection will not start
+ */
+ public function start()
+ {
+ $url = $this->getServer();
+ if ($this->getEncryption() == self::ENC_SSL) $url = "ssl://" . $url;
+
+ if ((false === $this->handle = fsockopen($url, $this->getPort(), $errno, $errstr, $timeout)))
+ {
+ Swift_ClassLoader::load("Swift_ConnectionException");
+ throw new Swift_ConnectionException("The POP3 connection failed to start. The error string returned from fsockopen() is [" . $errstr . "] #" . $errno);
+ }
+ }
+ /**
+ * Try to close the connection
+ * @throws Swift_ConnectionException If the connection won't close
+ */
+ public function stop()
+ {
+ if ($this->handle !== null)
+ {
+ if (false === fclose($this->handle))
+ {
+ Swift_ClassLoader::load("Swift_ConnectionException");
+ throw new Swift_ConnectionException("The POP3 connection did not close successfully.");
+ }
+ }
+ $this->handle = null;
+ }
+ /**
+ * Return the unread buffer contents
+ * @return string
+ * @throws Swift_ConnectionException If the connection will not allow data to be read
+ */
+ public function read()
+ {
+ if (false === $response = fgets($this->handle))
+ {
+ Swift_ClassLoader::load("Swift_ConnectionException");
+ throw new Swift_ConnectionException("Data could not be read from the POP3 connection.");
+ }
+ return trim($response);
+ }
+ /**
+ * Write a command to the remote socket
+ * @param string the command to send (without CRLF)
+ * @throws Swift_ConnectionException If the command cannot be written
+ */
+ public function write($command)
+ {
+ if (false !== fwrite($this->handle, $command . "\r\n"))
+ {
+ Swift_ClassLoader::load("Swift_ConnectionException");
+ throw new Swift_ConnectionException("Data could not be written to the POP3 connection.");
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator/PopB4Smtp/Pop3Connection.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Swift Mailer Authenticator Interface
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Authenticator
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Swift Authenticator Interface
+ * Lists the methods all authenticators must implement
+ * @package Swift_Authenticator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Authenticator
+{
+ /**
+ * Try to authenticate using the username and password
+ * Returns false on failure
+ * @param string The username
+ * @param string The password
+ * @param Swift The instance of Swift this authenticator is used in
+ * @return boolean
+ */
+ public function isAuthenticated($username, $password, Swift $instance);
+ /**
+ * Return the name of the AUTH extension this is for
+ * @return string
+ */
+ public function getAuthExtensionName();
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Authenticator.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BadResponseException.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BadResponseException.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BadResponseException.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * Swift Bad Response Code Exception
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_ConnectionException");
+
+/**
+ * Swift Bad Response Exception
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_BadResponseException extends Swift_ConnectionException
+{
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BadResponseException.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BatchMailer.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BatchMailer.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BatchMailer.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,229 @@
+<?php
+
+/**
+ * Handles batch mailing with Swift Mailer with fail-safe support.
+ * Restarts the connection if it dies and then continues where it left off.
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+class Swift_BatchMailer
+{
+ /**
+ * The current instance of Swift.
+ * @var Swift
+ */
+ protected $swift;
+ /**
+ * The maximum number of times a single recipient can be attempted before giving up.
+ * @var int
+ */
+ protected $maxTries = 2;
+ /**
+ * The number of seconds to sleep for if an error occurs.
+ * @var int
+ */
+ protected $sleepTime = 0;
+ /**
+ * Failed recipients (undeliverable)
+ * @var array
+ */
+ protected $failed = array();
+ /**
+ * The maximum number of successive failures before giving up.
+ * @var int
+ */
+ protected $maxFails = 0;
+ /**
+ * A temporary copy of some message headers.
+ * @var array
+ */
+ protected $headers = array();
+
+ /**
+ * Constructor.
+ * @param Swift The current instance of Swift
+ */
+ public function __construct(Swift $swift)
+ {
+ $this->setSwift($swift);
+ }
+ /**
+ * Set the current Swift instance.
+ * @param Swift The instance
+ */
+ public function setSwift(Swift $swift)
+ {
+ $this->swift = $swift;
+ }
+ /**
+ * Get the Swift instance which is running.
+ * @return Swift
+ */
+ public function getSwift()
+ {
+ return $this->swift;
+ }
+ /**
+ * Set the maximum number of times a single address is allowed to be retried.
+ * @param int The maximum number of tries.
+ */
+ public function setMaxTries($max)
+ {
+ $this->maxTries = abs($max);
+ }
+ /**
+ * Get the number of times a single address will be attempted in a batch.
+ * @return int
+ */
+ public function getMaxTries()
+ {
+ return $this->maxTries;
+ }
+ /**
+ * Set the amount of time to sleep for if an error occurs.
+ * @param int Number of seconds
+ */
+ public function setSleepTime($secs)
+ {
+ $this->sleepTime = abs($secs);
+ }
+ /**
+ * Get the amount of time to sleep for on errors.
+ * @return int
+ */
+ public function getSleepTime()
+ {
+ return $this->sleepTime;
+ }
+ /**
+ * Log a failed recipient.
+ * @param string The email address.
+ */
+ public function addFailedRecipient($address)
+ {
+ $this->failed[] = $address;
+ $this->failed = array_unique($this->failed);
+ }
+ /**
+ * Get all recipients which failed in this batch.
+ * @return array
+ */
+ public function getFailedRecipients()
+ {
+ return $this->failed;
+ }
+ /**
+ * Clear out the list of failed recipients.
+ */
+ public function flushFailedRecipients()
+ {
+ $this->failed = null;
+ $this->failed = array();
+ }
+ /**
+ * Set the maximum number of times an error can be thrown in succession and still be hidden.
+ * @param int
+ */
+ public function setMaxSuccessiveFailures($fails)
+ {
+ $this->maxFails = abs($fails);
+ }
+ /**
+ * Get the maximum number of times an error can be thrown and still be hidden.
+ * @return int
+ */
+ public function getMaxSuccessiveFailures()
+ {
+ return $this->maxFails;
+ }
+ /**
+ * Restarts Swift forcibly.
+ */
+ protected function forceRestartSwift()
+ {
+ //Pre-empting problems trying to issue "QUIT" to a dead connection
+ $this->swift->connection->stop();
+ $this->swift->connection->start();
+ $this->swift->disconnect();
+ //Restart swift
+ $this->swift->connect();
+ }
+ /**
+ * Takes a temporary copy of original message headers in case an error occurs and they need restoring.
+ * @param Swift_Message The message object
+ */
+ protected function copyMessageHeaders(&$message)
+ {
+ $this->headers["To"] = $message->headers->has("To") ?
+ $message->headers->get("To") : null;
+ $this->headers["Reply-To"] = $message->headers->has("Reply-To") ?
+ $message->headers->get("Reply-To") : null;
+ $this->headers["Return-Path"] = $message->headers->has("Return-Path") ?
+ $message->headers->get("Return-Path") : null;
+ $this->headers["From"] = $message->headers->has("From") ?
+ $message->headers->get("From") : null;
+ }
+ /**
+ * Restore message headers to original values in the event of a failure.
+ * @param Swift_Message The message
+ */
+ protected function restoreMessageHeaders(&$message)
+ {
+ foreach ($this->headers as $name => $value)
+ {
+ $message->headers->set($name, $value);
+ }
+ }
+ /**
+ * Run a batch send in a fail-safe manner.
+ * This operates as Swift::batchSend() except it deals with errors itself.
+ * @param Swift_Message To send
+ * @param Swift_RecipientList Recipients (To: only)
+ * @param Swift_Address The sender's address
+ * @return int The number sent to
+ */
+ public function send(Swift_Message $message, Swift_RecipientList $recipients, $sender)
+ {
+ $sent = 0;
+ $successive_fails = 0;
+
+ $it = $recipients->getIterator("to");
+ while ($it->hasNext())
+ {
+ $it->next();
+ $recipient = $it->getValue();
+ $tried = 0;
+ $loop = true;
+ while ($loop && $tried < $this->getMaxTries())
+ {
+ try {
+ $tried++;
+ $loop = false;
+ $this->copyMessageHeaders($message);
+ $sent += ($n = $this->swift->send($message, $recipient, $sender));
+ if (!$n) $this->addFailedRecipient($recipient->getAddress());
+ $successive_fails = 0;
+ } catch (Exception $e) {
+ $successive_fails++;
+ $this->restoreMessageHeaders($message);
+ if (($max = $this->getMaxSuccessiveFailures())
+ && $successive_fails > $max)
+ {
+ throw new Exception(
+ "Too many successive failures. BatchMailer is configured to allow no more than " . $max .
+ " successive failures.");
+ }
+ //If an exception was thrown, give it one more go
+ if ($t = $this->getSleepTime()) sleep($t);
+ $this->forceRestartSwift();
+ $loop = true;
+ }
+ }
+ }
+
+ return $sent;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/BatchMailer.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Disk.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Disk.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Disk.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,130 @@
+<?php
+
+/**
+ * Swift Mailer disk runtime cache
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Cache
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Cache");
+
+/**
+ * Caches data in files on disk - this is the best approach if possible
+ * @package Swift_Cache
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Cache_Disk extends Swift_Cache
+{
+ /**
+ * Open file handles
+ * @var array
+ */
+ protected $open = array();
+ /**
+ * The prefix to prepend to files
+ * @var string
+ */
+ protected $prefix;
+ /**
+ * The save path on disk
+ * @var string
+ */
+ protected static $save_path = "/tmp";
+
+ /**
+ * Ctor
+ */
+ public function __construct()
+ {
+ $this->prefix = md5(uniqid(microtime(), true));
+ }
+ /**
+ * Set the save path of the disk - this is a global setting and called statically!
+ * @param string The path to a writable directory
+ */
+ public static function setSavePath($path="/tmp")
+ {
+ self::$save_path = realpath($path);
+ }
+ /**
+ * Write data to the cache
+ * @param string The cache key
+ * @param string The data to write
+ */
+ public function write($key, $data)
+ {
+ $handle = fopen(self::$save_path . "/" . $this->prefix . $key, "ab");
+ if (false === fwrite($handle, $data))
+ {
+ Swift_ClassLoader::load("Swift_FileException");
+ throw new Swift_FileException("Disk Caching failed. Tried to write to file at [" .
+ self::$save_path . "/" . $this->prefix . $key . "] but failed. Check the permissions, or don't use disk caching.");
+ }
+ fclose($handle);
+ }
+ /**
+ * Clear the cached data (unlink)
+ * @param string The cache key
+ */
+ public function clear($key)
+ {
+ @unlink(self::$save_path . "/" . $this->prefix . $key);
+ }
+ /**
+ * Check if data is cached for $key
+ * @param string The cache key
+ * @return boolean
+ */
+ public function has($key)
+ {
+ return file_exists(self::$save_path . "/" . $this->prefix . $key);
+ }
+ /**
+ * Read data from the cache for $key
+ * @param string The cache key
+ * @param int The number of bytes to read
+ * @return string
+ */
+ public function read($key, $size=null)
+ {
+ if ($size === null) $size = 8190;
+ if (!$this->has($key)) return false;
+
+ if (!isset($this->open[$key]))
+ {
+ $this->open[$key] = fopen(self::$save_path . "/" . $this->prefix . $key, "rb");
+ }
+ if (feof($this->open[$key]))
+ {
+ fclose($this->open[$key]);
+ unset($this->open[$key]);
+ return false;
+ }
+ $ret = fread($this->open[$key], $size);
+ if ($ret !== false)
+ {
+ return $ret;
+ }
+ else
+ {
+ fclose($this->open[$key]);
+ unset($this->open[$key]);
+ return false;
+ }
+ }
+ /**
+ * Dtor.
+ * Clear out cached data at end of script execution or cache destruction
+ */
+ public function __destruct()
+ {
+ $list = glob(self::$save_path . "/" . $this->prefix . "*");
+ foreach ((array)$list as $f)
+ {
+ @unlink($f);
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Disk.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/JointOutputStream.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/JointOutputStream.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/JointOutputStream.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * Swift Mailer Joint Output stream to chain multiple output streams together
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Cache
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Cache_OutputStream");
+
+/**
+ * Makes multiple output streams act as one super sream
+ * @package Swift_Cache
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Cache_JointOutputStream extends Swift_Cache_OutputStream
+{
+ /**
+ * The streams to join
+ * @var array
+ */
+ protected $streams = array();
+ /**
+ * The current stream in use
+ * @var int
+ */
+ protected $pointer = 0;
+
+ /**
+ * Ctor
+ * @param array An array of Swift_Cache_OutputStream instances
+ */
+ public function __construct($streams=array())
+ {
+ $this->streams = $streams;
+ }
+ /**
+ * Add a new output stream
+ * @param Swift_Cache_OutputStream
+ */
+ public function addStream(Swift_Cache_OutputStream $stream)
+ {
+ $this->streams[] = $stream;
+ }
+ /**
+ * Read data from all streams as if they are one stream
+ * @param int The number of bytes to read from each stream
+ * @return string
+ */
+ public function read($size=null)
+ {
+ $ret = $this->streams[$this->pointer]->read($size);
+ if ($ret !== false)
+ {
+ return $ret;
+ }
+ else
+ {
+ if (isset($this->streams[($this->pointer+1)]))
+ {
+ $this->pointer++;
+ return $this->read($size);
+ }
+ else
+ {
+ $this->pointer = 0;
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/JointOutputStream.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Memory.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Memory.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Memory.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * Swift Mailer Native memory runtime cache
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Cache
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Cache");
+
+/**
+ * Caches data in variables - uses memory!
+ * @package Swift_Cache
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Cache_Memory extends Swift_Cache
+{
+ /**
+ * The storage container for this cache
+ * @var array
+ */
+ protected $store = array();
+ /**
+ * The key which was last requested
+ * @var string
+ */
+ protected $requested;
+
+ /**
+ * Write data to the cache
+ * @param string The cache key
+ * @param string The data to write
+ */
+ public function write($key, $data)
+ {
+ if (!isset($this->store[$key])) $this->store[$key] = $data;
+ else $this->store[$key] .= $data;
+ }
+ /**
+ * Clear the cached data (unset)
+ * @param string The cache key
+ */
+ public function clear($key)
+ {
+ $this->store[$key] = null;
+ unset($this->store[$key]);
+ }
+ /**
+ * Check if data is cached for $key
+ * @param string The cache key
+ * @return boolean
+ */
+ public function has($key)
+ {
+ return array_key_exists($key, $this->store);
+ }
+ /**
+ * Read data from the cache for $key
+ * It makes no difference to memory/speed if data is read in chunks so arguments are ignored
+ * @param string The cache key
+ * @return string
+ */
+ public function read($key, $size=null)
+ {
+ if (!$this->has($key)) return false;
+
+ if ($this->requested == $key)
+ {
+ $this->requested = null;
+ return false;
+ }
+ $this->requested = $key;
+ return $this->store[$key];
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/Memory.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/OutputStream.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/OutputStream.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/OutputStream.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * Swift Mailer Output stream to read bytes from cached data
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Cache
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * The wraps the streaming functionality of the cache
+ * @package Swift_Cache
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Cache_OutputStream
+{
+ /**
+ * The key to read in the actual cache
+ * @var string
+ */
+ protected $key;
+ /**
+ * The cache object to read
+ * @var Swift_Cache
+ */
+ protected $cache;
+
+ /**
+ * Ctor.
+ * @param Swift_Cache The cache to read from
+ * @param string The key for the cached data
+ */
+ public function __construct(Swift_Cache $cache, $key)
+ {
+ $this->cache = $cache;
+ $this->key = $key;
+ }
+ /**
+ * Read bytes from the cache and seek through the buffer
+ * Returns false if EOF is reached
+ * @param int The number of bytes to read (could be ignored)
+ * @return string The read bytes
+ */
+ public function read($size=null)
+ {
+ return $this->cache->read($this->key, $size);
+ }
+ /**
+ * Read the entire cached data as one string
+ * @return string
+ */
+ public function readFull()
+ {
+ $ret = "";
+ while (false !== $bytes = $this->read())
+ $ret .= $bytes;
+ return $ret;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache/OutputStream.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Swift Mailer Runtime caching base component.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Cache
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+
+/**
+ * The interface for any cache mechanisms to follow
+ * @package Swift_Cache
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+abstract class Swift_Cache
+{
+ /**
+ * Append bytes to the cache buffer identified by $key
+ * @param string The Cache key
+ * @param string The bytes to append
+ */
+ abstract public function write($key, $data);
+ /**
+ * Clear out the buffer for $key
+ * @param string The cache key
+ */
+ abstract public function clear($key);
+ /**
+ * Check if there is something in the cache for $key
+ * @param string The cache key
+ * @return boolean
+ */
+ abstract public function has($key);
+ /**
+ * Read bytes from the cached buffer and seek forward in the buffer
+ * Returns false once no more bytes are left to read
+ * @param int The number of bytes to read (may be ignored)
+ * @return string
+ */
+ abstract public function read($key, $size=null);
+ /**
+ * A factory method to return an output stream object for the relevant location in the cache
+ * @param string The cache key to fetch the stream for
+ * @return Swift_Cache_OutputStream
+ */
+ public function getOutputStream($key)
+ {
+ Swift_ClassLoader::load("Swift_Cache_OutputStream");
+ $os = new Swift_Cache_OutputStream($this, $key);
+ return $os;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Cache.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/CacheFactory.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/CacheFactory.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/CacheFactory.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * Swift Mailer Cache Factory class
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Cache
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+
+/**
+ * Makes instances of the cache the user has defined
+ * @package Swift_Cache
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_CacheFactory
+{
+ /**
+ * The name of the class which defines the cache
+ * @var string Case SenSITivE
+ */
+ protected static $className = "Swift_Cache_Memory";
+
+ /**
+ * Set the name of the class which is supposed to be used
+ * This also includes the file
+ * @param string The class name
+ */
+ public static function setClassName($name)
+ {
+ Swift_ClassLoader::load($name);
+ self::$className = $name;
+ }
+ /**
+ * Return a new instance of the cache object
+ * @return Swift_Cache
+ */
+ public static function getCache()
+ {
+ $className = self::$className;
+ Swift_ClassLoader::load($className);
+ $instance = new $className();
+ return $instance;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/CacheFactory.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ClassLoader.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ClassLoader.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ClassLoader.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * Swift Mailer Class Loader for includes
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+if (!defined("SWIFT_ABS_PATH")) define("SWIFT_ABS_PATH", dirname(__FILE__) . "/..");
+
+/**
+ * Locates and includes class files
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_ClassLoader
+{
+ /**
+ * A list of files already located
+ * @var array
+ */
+ protected static $located = array();
+
+ /**
+ * Load a new class into memory
+ * @param string The name of the class, case SenSItivE
+ */
+ public static function load($name)
+ {
+ if (in_array($name, self::$located) || class_exists($name, false) || interface_exists($name, false))
+ return;
+
+ require_once SWIFT_ABS_PATH . "/" . str_replace("_", "/", $name) . ".php";
+ self::$located[] = $name;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ClassLoader.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Multi.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Multi.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Multi.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * Swift Mailer Multiple Redundant Connection component.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_ConnectionBase");
+
+/**
+ * Swift Multi Connection
+ * Tries to connect to a number of connections until one works successfully
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Connection_Multi extends Swift_ConnectionBase
+{
+ /**
+ * The list of available connections
+ * @var array
+ */
+ protected $connections = array();
+ /**
+ * The id of the active connection
+ * @var string
+ */
+ protected $active = null;
+
+ /**
+ * Constructor
+ */
+ public function __construct($connections=array())
+ {
+ foreach ($connections as $id => $conn)
+ {
+ $this->addConnection($connections[$id], $id);
+ }
+ }
+ /**
+ * Add a connection to the list of options
+ * @param Swift_Connection An instance of the connection
+ * @param string An ID to assign to the connection
+ */
+ public function addConnection(Swift_Connection $connection, $id=null)
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Adding new connection of type '" . get_class($connection) . "' to the multi-redundant connection.");
+ }
+ if ($id !== null) $this->connections[$id] = $connection;
+ else $this->connections[] = $connection;
+ }
+ /**
+ * Read a full response from the buffer
+ * @return string
+ * @throws Swift_ConnectionException Upon failure to read
+ */
+ public function read()
+ {
+ if ($this->active === null)
+ {
+ throw new Swift_ConnectionException("None of the connections set have been started");
+ }
+ return $this->connections[$this->active]->read();
+ }
+ /**
+ * Write a command to the server (leave off trailing CRLF)
+ * @param string The command to send
+ * @throws Swift_ConnectionException Upon failure to write
+ */
+ public function write($command, $end="\r\n")
+ {
+ if ($this->active === null)
+ {
+ throw new Swift_ConnectionException("None of the connections set have been started");
+ }
+ return $this->connections[$this->active]->write($command, $end);
+ }
+ /**
+ * Try to start the connection
+ * @throws Swift_ConnectionException Upon failure to start
+ */
+ public function start()
+ {
+ $log = Swift_LogContainer::getLog();
+ $fail_messages = array();
+ foreach ($this->connections as $id => $conn)
+ {
+ try {
+ $this->connections[$id]->start();
+ if ($this->connections[$id]->isAlive())
+ {
+ $this->active = $id;
+ return true;
+ }
+ else
+ {
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Connection (" . $id . ") failed. Will try next connection if available.");
+ }
+ throw new Swift_ConnectionException("The connection started but reported that it was not active");
+ }
+ } catch (Swift_ConnectionException $e) {
+ $fail_messages[] = $id . ": " . $e->getMessage();
+ }
+ }
+ $failure = implode("<br />", $fail_messages);
+ throw new Swift_ConnectionException($failure);
+ }
+ /**
+ * Try to close the connection
+ * @throws Swift_ConnectionException Upon failure to close
+ */
+ public function stop()
+ {
+ if ($this->active !== null) $this->connections[$this->active]->stop();
+ $this->active = null;
+ }
+ /**
+ * Check if the current connection is alive
+ * @return boolean
+ */
+ public function isAlive()
+ {
+ return (($this->active !== null) && $this->connections[$this->active]->isAlive());
+ }
+ /**
+ * Call the current connection's postConnect() method
+ */
+ public function postConnect(Swift $instance)
+ {
+ $this->connections[$this->active]->postConnect($instance);
+ }
+ /**
+ * Call the current connection's setExtension() method
+ */
+ public function setExtension($extension, $attributes=array())
+ {
+ $this->connections[$this->active]->setExtension($extension, $attributes);
+ }
+ /**
+ * Call the current connection's hasExtension() method
+ */
+ public function hasExtension($name)
+ {
+ return $this->connections[$this->active]->hasExtension($name);
+ }
+ /**
+ * Call the current connection's getAttributes() method
+ */
+ public function getAttributes($name)
+ {
+ return $this->connections[$this->active]->getAttributes($name);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Multi.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/NativeMail.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/NativeMail.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/NativeMail.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * Swift Mailer mail() connection component
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_ConnectionBase");
+Swift_ClassLoader::load("Swift_Plugin_MailSend");
+
+/**
+ * Swift mail() Connection
+ * NOTE: This class is nothing more than a stub. The MailSend plugin does the actual sending.
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Connection_NativeMail extends Swift_ConnectionBase
+{
+ /**
+ * The response the stub will be giving next
+ * @var string Response
+ */
+ protected $response = "220 Stubbed";
+ /**
+ * The 5th parameter in mail() is a sprintf() formatted string.
+ * @var string
+ */
+ protected $pluginParams;
+ /**
+ * An instance of the MailSend plugin.
+ * @var Swift_Plugin_MailSend
+ */
+ protected $plugin = null;
+
+ /**
+ * Ctor.
+ * @param string The 5th parameter in mail() as a sprintf() formatted string where %s is the sender address. This only comes into effect if safe_mode is OFF.
+ */
+ public function __construct($additional_params="-oi -f %s")
+ {
+ $this->setAdditionalMailParams($additional_params);
+ }
+ /**
+ * Sets the MailSend plugin in Swift once Swift has connected
+ * @param Swift The current instance of Swift
+ */
+ public function postConnect(Swift $instance)
+ {
+ $this->plugin = new Swift_Plugin_MailSend($this->getAdditionalMailParams());
+ $instance->attachPlugin($this->plugin, "_MAIL_SEND");
+ }
+ /**
+ * Set the 5th parameter in mail() as a sprintf() formatted string. Only used if safe_mode is off.
+ * @param string
+ */
+ public function setAdditionalMailParams($params)
+ {
+ $this->pluginParams = $params;
+ if ($this->plugin !== null)
+ {
+ $this->plugin->setAdditionalParams($params);
+ }
+ }
+ /**
+ * Get the 5th parameter in mail() as a sprintf() formatted string.
+ * @return string
+ */
+ public function getAdditionalMailParams()
+ {
+ return $this->pluginParams;
+ }
+ /**
+ * Read a full response from the buffer (this is spoofed if running in -t mode)
+ * @return string
+ * @throws Swift_ConnectionException Upon failure to read
+ */
+ public function read()
+ {
+ return $this->response;
+ }
+ /**
+ * Set the response this stub will return
+ * @param string The response to send
+ */
+ public function setResponse($int)
+ {
+ $this->response = $int . " Stubbed";
+ }
+ /**
+ * Write a command to the process (leave off trailing CRLF)
+ * @param string The command to send
+ * @throws Swift_ConnectionException Upon failure to write
+ */
+ public function write($command, $end="\r\n")
+ {
+ $command = strtoupper($command);
+ if (strpos($command, " ")) $command = substr($command, 0, strpos($command, " "));
+ switch ($command)
+ {
+ case "DATA":
+ $this->setResponse(354);
+ break;
+ case "EHLO": case "MAIL": case "RCPT": case "QUIT": case "RSET": default:
+ $this->setResponse(250);
+ break;
+ }
+ }
+ /**
+ * Try to start the connection
+ * @throws Swift_ConnectionException Upon failure to start
+ */
+ public function start()
+ {
+ $this->response = "220 Stubbed";
+ }
+ /**
+ * Try to close the connection
+ * @throws Swift_ConnectionException Upon failure to close
+ */
+ public function stop()
+ {
+ $this->response = "220 Stubbed";
+ }
+ /**
+ * Check if the process is still alive
+ * @return boolean
+ */
+ public function isAlive()
+ {
+ return function_exists("mail");
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/NativeMail.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Rotator.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Rotator.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Rotator.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * Swift Mailer Multiple Redundant Cycling Connection component.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_ConnectionBase");
+
+/**
+ * Swift Rotator Connection
+ * Switches through each connection in turn after sending each message
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Connection_Rotator extends Swift_ConnectionBase
+{
+ /**
+ * The list of available connections
+ * @var array
+ */
+ protected $connections = array();
+ /**
+ * The id of the active connection
+ * @var int
+ */
+ protected $active = null;
+ /**
+ * Contains a list of any connections which were tried but found to be dead
+ * @var array
+ */
+ protected $dead = array();
+
+ /**
+ * Constructor
+ */
+ public function __construct($connections=array())
+ {
+ foreach ($connections as $id => $conn)
+ {
+ $this->addConnection($connections[$id], $id);
+ }
+ }
+ /**
+ * Add a connection to the list of options
+ * @param Swift_Connection An instance of the connection
+ */
+ public function addConnection(Swift_Connection $connection)
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Adding new connection of type '" . get_class($connection) . "' to rotator.");
+ }
+ $this->connections[] = $connection;
+ }
+ /**
+ * Rotate to the next working connection
+ * @throws Swift_ConnectionException If no connections are available
+ */
+ public function nextConnection()
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add(" <==> Rotating connection.");
+ }
+
+ $total = count($this->connections);
+ $start = $this->active === null ? 0 : ($this->active + 1);
+ if ($start >= $total) $start = 0;
+
+ $fail_messages = array();
+ for ($id = $start; $id < $total; $id++)
+ {
+ if (in_array($id, $this->dead)) continue; //The connection was previously found to be useless
+ try {
+ if (!$this->connections[$id]->isAlive()) $this->connections[$id]->start();
+ if ($this->connections[$id]->isAlive())
+ {
+ $this->active = $id;
+ return true;
+ }
+ else
+ {
+ $this->dead[] = $id;
+ $this->connections[$id]->stop();
+ throw new Swift_ConnectionException("The connection started but reported that it was not active");
+ }
+ } catch (Swift_ConnectionException $e) {
+ $fail_messages[] = $id . ": " . $e->getMessage();
+ }
+ }
+
+ $failure = implode("<br />", $fail_messages);
+ throw new Swift_ConnectionException("No connections were started.<br />" . $failure);
+ }
+ /**
+ * Read a full response from the buffer
+ * @return string
+ * @throws Swift_ConnectionException Upon failure to read
+ */
+ public function read()
+ {
+ if ($this->active === null)
+ {
+ throw new Swift_ConnectionException("None of the connections set have been started");
+ }
+ return $this->connections[$this->active]->read();
+ }
+ /**
+ * Write a command to the server (leave off trailing CRLF)
+ * @param string The command to send
+ * @throws Swift_ConnectionException Upon failure to write
+ */
+ public function write($command, $end="\r\n")
+ {
+ if ($this->active === null)
+ {
+ throw new Swift_ConnectionException("None of the connections set have been started");
+ }
+ return $this->connections[$this->active]->write($command, $end);
+ }
+ /**
+ * Try to start the connection
+ * @throws Swift_ConnectionException Upon failure to start
+ */
+ public function start()
+ {
+ if ($this->active === null) $this->nextConnection();
+ }
+ /**
+ * Try to close the connection
+ * @throws Swift_ConnectionException Upon failure to close
+ */
+ public function stop()
+ {
+ foreach ($this->connections as $id => $conn)
+ {
+ if ($this->connections[$id]->isAlive()) $this->connections[$id]->stop();
+ }
+ $this->active = null;
+ }
+ /**
+ * Check if the current connection is alive
+ * @return boolean
+ */
+ public function isAlive()
+ {
+ return (($this->active !== null) && $this->connections[$this->active]->isAlive());
+ }
+ /**
+ * Get the ID of the active connection
+ * @return int
+ */
+ public function getActive()
+ {
+ return $this->active;
+ }
+ /**
+ * Call the current connection's postConnect() method
+ */
+ public function postConnect(Swift $instance)
+ {
+ Swift_ClassLoader::load("Swift_Plugin_ConnectionRotator");
+ if (!$instance->getPlugin("_ROTATOR")) $instance->attachPlugin(new Swift_Plugin_ConnectionRotator(), "_ROTATOR");
+ $this->connections[$this->active]->postConnect($instance);
+ }
+ /**
+ * Call the current connection's setExtension() method
+ */
+ public function setExtension($extension, $attributes=array())
+ {
+ $this->connections[$this->active]->setExtension($extension, $attributes);
+ }
+ /**
+ * Call the current connection's hasExtension() method
+ */
+ public function hasExtension($name)
+ {
+ return $this->connections[$this->active]->hasExtension($name);
+ }
+ /**
+ * Call the current connection's getAttributes() method
+ */
+ public function getAttributes($name)
+ {
+ return $this->connections[$this->active]->getAttributes($name);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Rotator.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/SMTP.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/SMTP.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/SMTP.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,452 @@
+<?php
+
+/**
+ * Swift Mailer SMTP Connection component.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_ConnectionBase");
+Swift_ClassLoader::load("Swift_Authenticator");
+
+/**
+ * Swift SMTP Connection
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Connection_SMTP extends Swift_ConnectionBase
+{
+ /**
+ * Constant for TLS connections
+ */
+ const ENC_TLS = 2;
+ /**
+ * Constant for SSL connections
+ */
+ const ENC_SSL = 4;
+ /**
+ * Constant for unencrypted connections
+ */
+ const ENC_OFF = 8;
+ /**
+ * Constant for the default SMTP port
+ */
+ const PORT_DEFAULT = 25;
+ /**
+ * Constant for the default secure SMTP port
+ */
+ const PORT_SECURE = 465;
+ /**
+ * Constant for auto-detection of paramters
+ */
+ const AUTO_DETECT = -2;
+ /**
+ * A connection handle
+ * @var resource
+ */
+ protected $handle = null;
+ /**
+ * The remote port number
+ * @var int
+ */
+ protected $port = null;
+ /**
+ * Encryption type to use
+ * @var int
+ */
+ protected $encryption = null;
+ /**
+ * A connection timeout
+ * @var int
+ */
+ protected $timeout = 15;
+ /**
+ * A username to authenticate with
+ * @var string
+ */
+ protected $username = false;
+ /**
+ * A password to authenticate with
+ * @var string
+ */
+ protected $password = false;
+ /**
+ * Loaded authentication mechanisms
+ * @var array
+ */
+ protected $authenticators = array();
+ /**
+ * Fsockopen() error codes.
+ * @var int
+ */
+ protected $errno;
+ /**
+ * Fsockopen() error codes.
+ * @var string
+ */
+ protected $errstr;
+
+ /**
+ * Constructor
+ * @param string The remote server to connect to
+ * @param int The remote port to connect to
+ * @param int The encryption level to use
+ */
+ public function __construct($server="localhost", $port=null, $encryption=null)
+ {
+ $this->setServer($server);
+ $this->setEncryption($encryption);
+ $this->setPort($port);
+ }
+ /**
+ * Set the timeout to connect in seconds
+ * @param int Timeout to use
+ */
+ public function setTimeout($time)
+ {
+ $this->timeout = (int) $time;
+ }
+ /**
+ * Get the timeout currently set for connecting
+ * @return int
+ */
+ public function getTimeout()
+ {
+ return $this->timeout;
+ }
+ /**
+ * Set the remote server to connect to as a FQDN
+ * @param string Server name
+ */
+ public function setServer($server)
+ {
+ if ($server == self::AUTO_DETECT)
+ {
+ $server = @ini_get("SMTP");
+ if (!$server) $server = "localhost";
+ }
+ $this->server = (string) $server;
+ }
+ /**
+ * Get the remote server name
+ * @return string
+ */
+ public function getServer()
+ {
+ return $this->server;
+ }
+ /**
+ * Set the remote port number to connect to
+ * @param int Port number
+ */
+ public function setPort($port)
+ {
+ if ($port == self::AUTO_DETECT)
+ {
+ $port = @ini_get("SMTP_PORT");
+ }
+ if (!$port) $port = ($this->getEncryption() == self::ENC_OFF) ? self::PORT_DEFAULT : self::PORT_SECURE;
+ $this->port = (int) $port;
+ }
+ /**
+ * Get the remote port number currently used to connect
+ * @return int
+ */
+ public function getPort()
+ {
+ return $this->port;
+ }
+ /**
+ * Provide a username for authentication
+ * @param string The username
+ */
+ public function setUsername($user)
+ {
+ $this->setRequiresEHLO(true);
+ $this->username = $user;
+ }
+ /**
+ * Get the username for authentication
+ * @return string
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+ /**
+ * Set the password for SMTP authentication
+ * @param string Password to use
+ */
+ public function setPassword($pass)
+ {
+ $this->setRequiresEHLO(true);
+ $this->password = $pass;
+ }
+ /**
+ * Get the password for authentication
+ * @return string
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+ /**
+ * Add an authentication mechanism to authenticate with
+ * @param Swift_Authenticator
+ */
+ public function attachAuthenticator(Swift_Authenticator $auth)
+ {
+ $this->authenticators[$auth->getAuthExtensionName()] = $auth;
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Authentication mechanism '" . $auth->getAuthExtensionName() . "' attached.");
+ }
+ }
+ /**
+ * Set the encryption level to use on the connection
+ * See the constants ENC_TLS, ENC_SSL and ENC_OFF
+ * NOTE: PHP needs to have been compiled with OpenSSL for SSL and TLS to work
+ * NOTE: Some PHP installations will not have the TLS stream wrapper
+ * @param int Level of encryption
+ */
+ public function setEncryption($enc)
+ {
+ if (!$enc) $enc = self::ENC_OFF;
+ $this->encryption = (int) $enc;
+ }
+ /**
+ * Get the current encryption level used
+ * This method returns an integer corresponding to one of the constants ENC_TLS, ENC_SSL or ENC_OFF
+ * @return int
+ */
+ public function getEncryption()
+ {
+ return $this->encryption;
+ }
+ /**
+ * Read a full response from the buffer
+ * inner !feof() patch provided by Christian Rodriguez:
+ * <a href="http://www.flyspray.org/">www.flyspray.org</a>
+ * @return string
+ * @throws Swift_ConnectionException Upon failure to read
+ */
+ public function read()
+ {
+ if (!$this->handle) throw new Swift_ConnectionException(
+ "The SMTP connection is not alive and cannot be read from." . $this->smtpErrors());
+ $ret = "";
+ $line = 0;
+ while (!feof($this->handle))
+ {
+ $line++;
+ stream_set_timeout($this->handle, $this->timeout);
+ $tmp = @fgets($this->handle);
+ if ($tmp === false && !feof($this->handle))
+ {
+ throw new Swift_ConnectionException(
+ "There was a problem reading line " . $line . " of an SMTP response. The response so far was:<br />[" . $ret .
+ "]. It appears the connection has died without saying goodbye to us! Too many emails in one go perhaps?" .
+ $this->smtpErrors());
+ }
+ $ret .= trim($tmp) . "\r\n";
+ if ($tmp{3} == " ") break;
+ }
+ return $ret = substr($ret, 0, -2);
+ }
+ /**
+ * Write a command to the server (leave off trailing CRLF)
+ * @param string The command to send
+ * @throws Swift_ConnectionException Upon failure to write
+ */
+ public function write($command, $end="\r\n")
+ {
+ if (!$this->handle) throw new Swift_ConnectionException(
+ "The SMTP connection is not alive and cannot be written to." .
+ $this->smtpErrors());
+ if (!@fwrite($this->handle, $command . $end) && !empty($command)) throw new Swift_ConnectionException("The SMTP connection did not allow the command '" . $command . "' to be sent." . $this->smtpErrors());
+ }
+ /**
+ * Try to start the connection
+ * @throws Swift_ConnectionException Upon failure to start
+ */
+ public function start()
+ {
+ if ($this->port === null)
+ {
+ switch ($this->encryption)
+ {
+ case self::ENC_TLS: case self::ENC_SSL:
+ $this->port = 465;
+ break;
+ case null: default:
+ $this->port = 25;
+ break;
+ }
+ }
+
+ $server = $this->server;
+ if ($this->encryption == self::ENC_TLS) $server = "tls://" . $server;
+ elseif ($this->encryption == self::ENC_SSL) $server = "ssl://" . $server;
+
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_log::LOG_EVERYTHING))
+ {
+ $log->add("Trying to connect to SMTP server at '" . $server . ":" . $this->port);
+ }
+
+ if (!$this->handle = @fsockopen($server, $this->port, $errno, $errstr, $this->timeout))
+ {
+ $error_msg = "The SMTP connection failed to start [" . $server . ":" . $this->port . "]: fsockopen returned Error Number " . $errno . " and Error String '" . $errstr . "'";
+ if ($log->isEnabled())
+ {
+ $log->add($error_msg, Swift_Log::ERROR);
+ }
+ $this->handle = null;
+ throw new Swift_ConnectionException($error_msg);
+ }
+ $this->errno =& $errno;
+ $this->errstr =& $errstr;
+ }
+ /**
+ * Get the smtp error string as recorded by fsockopen()
+ * @return string
+ */
+ public function smtpErrors()
+ {
+ return " (fsockopen: " . $this->errstr . "#" . $this->errno . ") ";
+ }
+ /**
+ * Authenticate if required to do so
+ * @param Swift An instance of Swift
+ * @throws Swift_ConnectionException If authentication fails
+ */
+ public function postConnect(Swift $instance)
+ {
+ if ($this->getUsername() && $this->getPassword())
+ {
+ $this->runAuthenticators($this->getUsername(), $this->getPassword(), $instance);
+ }
+ }
+ /**
+ * Run each authenticator in turn an try for a successful login
+ * If none works, throw an exception
+ * @param string Username
+ * @param string Password
+ * @param Swift An instance of swift
+ * @throws Swift_ConnectionException Upon failure to authenticate
+ */
+ public function runAuthenticators($user, $pass, Swift $swift)
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Trying to authenticate with username '" . $user . "'.");
+ }
+ //Load in defaults
+ if (empty($this->authenticators))
+ {
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("No authenticators loaded; looking for defaults.");
+ }
+ $dir = dirname(__FILE__) . "/../Authenticator";
+ $handle = opendir($dir);
+ while (false !== $file = readdir($handle))
+ {
+ if (preg_match("/^[A-Za-z0-9-]+\\.php\$/", $file))
+ {
+ $name = preg_replace('/[^a-zA-Z0-9]+/', '', substr($file, 0, -4));
+ require_once $dir . "/" . $file;
+ $class = "Swift_Authenticator_" . $name;
+ $this->attachAuthenticator(new $class());
+ }
+ }
+ closedir($handle);
+ }
+
+ $tried = 0;
+ $looks_supported = true;
+
+ //Allow everything we have if the server has the audacity not to help us out.
+ if (!$this->hasExtension("AUTH"))
+ {
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Server (perhaps wrongly) is not advertising AUTH... manually overriding.");
+ }
+ $looks_supported = false;
+ $this->setExtension("AUTH", array_keys($this->authenticators));
+ }
+
+ foreach ($this->authenticators as $name => $obj)
+ {
+ //Server supports this authentication mechanism
+ if (in_array($name, $this->getAttributes("AUTH")) || $name{0} == "*")
+ {
+ $tried++;
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Trying '" . $name . "' authentication...");
+ }
+ if ($this->authenticators[$name]->isAuthenticated($user, $pass, $swift))
+ {
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Success! Authentication accepted.");
+ }
+ return true;
+ }
+ }
+ }
+
+ //Server doesn't support authentication
+ if (!$looks_supported && $tried == 0)
+ throw new Swift_ConnectionException("Authentication is not supported by the server but a username and password was given.");
+
+ if ($tried == 0)
+ throw new Swift_ConnectionException("No authentication mechanisms were tried since the server did not support any of the ones loaded. " .
+ "Loaded authenticators: [" . implode(", ", array_keys($this->authenticators)) . "]");
+ else
+ throw new Swift_ConnectionException("Authentication failed using username '" . $user . "' and password '". str_repeat("*", strlen($pass)) . "'");
+ }
+ /**
+ * Try to close the connection
+ * @throws Swift_ConnectionException Upon failure to close
+ */
+ public function stop()
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Closing down SMTP connection.");
+ }
+ if ($this->handle)
+ {
+ if (!fclose($this->handle))
+ {
+ throw new Swift_ConnectionException("The SMTP connection could not be closed for an unknown reason." . $this->smtpErrors());
+ }
+ $this->handle = null;
+ }
+ }
+ /**
+ * Check if the SMTP connection is alive
+ * @return boolean
+ */
+ public function isAlive()
+ {
+ return ($this->handle !== null);
+ }
+ /**
+ * Destructor.
+ * Cleans up any open connections.
+ */
+ public function __destruct()
+ {
+ $this->stop();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/SMTP.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Sendmail.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Sendmail.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Sendmail.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,352 @@
+<?php
+
+/**
+ * Swift Mailer Sendmail Connection component.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_ConnectionBase");
+
+/**
+ * Swift Sendmail Connection
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Connection_Sendmail extends Swift_ConnectionBase
+{
+ /**
+ * Constant for auto-detection of paths
+ */
+ const AUTO_DETECT = -2;
+ /**
+ * Flags for the MTA (options such as bs or t)
+ * @var string
+ */
+ protected $flags = null;
+ /**
+ * The full path to the MTA
+ * @var string
+ */
+ protected $path = null;
+ /**
+ * The type of last request sent
+ * For example MAIL, RCPT, DATA
+ * @var string
+ */
+ protected $request = null;
+ /**
+ * The process handle
+ * @var resource
+ */
+ protected $proc;
+ /**
+ * I/O pipes for the process
+ * @var array
+ */
+ protected $pipes;
+ /**
+ * Switches to true for just one command when DATA has been issued
+ * @var boolean
+ */
+ protected $send = false;
+ /**
+ * The timeout in seconds before giving up
+ * @var int Seconds
+ */
+ protected $timeout = 10;
+
+ /**
+ * Constructor
+ * @param string The command to execute
+ * @param int The timeout in seconds before giving up
+ */
+ public function __construct($command="/usr/sbin/sendmail -bs", $timeout=10)
+ {
+ $this->setCommand($command);
+ $this->setTimeout($timeout);
+ }
+ /**
+ * Set the timeout on the process
+ * @param int The number of seconds
+ */
+ public function setTimeout($secs)
+ {
+ $this->timeout = (int)$secs;
+ }
+ /**
+ * Get the timeout on the process
+ * @return int
+ */
+ public function getTimeout()
+ {
+ return $this->timeout;
+ }
+ /**
+ * Set the operating flags for the MTA
+ * @param string
+ */
+ public function setFlags($flags)
+ {
+ $this->flags = $flags;
+ }
+ /**
+ * Get the operating flags for the MTA
+ * @return string
+ */
+ public function getFlags()
+ {
+ return $this->flags;
+ }
+ /**
+ * Set the path to the binary
+ * @param string The path (must be absolute!)
+ */
+ public function setPath($path)
+ {
+ if ($path == self::AUTO_DETECT) $path = $this->findSendmail();
+ $this->path = $path;
+ }
+ /**
+ * Get the path to the binary
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+ /**
+ * For auto-detection of sendmail path
+ * Thanks to "Joe Cotroneo" for providing the enhancement
+ * @return string
+ */
+ public function findSendmail()
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Sendmail path auto-detection in progress. Trying `which sendmail`");
+ }
+ $path = @trim(shell_exec('which sendmail'));
+ if (!is_executable($path))
+ {
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("No luck so far, trying some common paths...");
+ }
+ $common_locations = array(
+ '/usr/bin/sendmail',
+ '/usr/lib/sendmail',
+ '/var/qmail/bin/sendmail',
+ '/bin/sendmail',
+ '/usr/sbin/sendmail',
+ '/sbin/sendmail'
+ );
+ foreach ($common_locations as $path)
+ {
+ if (is_executable($path)) return $path;
+ }
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Falling back to /usr/sbin/sendmail (but it doesn't look good)!");
+ }
+ //Fallback (swift will still throw an error)
+ return "/usr/sbin/sendmail";
+ }
+ else return $path;
+ }
+ /**
+ * Set the sendmail command (path + flags)
+ * @param string Command
+ * @throws Swift_ConnectionException If the command is not correctly structured
+ */
+ public function setCommand($command)
+ {
+ if ($command == self::AUTO_DETECT) $command = $this->findSendmail() . " -bs";
+
+ if (!strrpos($command, " -"))
+ {
+ throw new Swift_ConnectionException("Cannot set sendmail command with no command line flags. e.g. /usr/sbin/sendmail -t");
+ }
+ $path = substr($command, 0, strrpos($command, " -"));
+ $flags = substr($command, strrpos($command, " -")+2);
+ $this->setPath($path);
+ $this->setFlags($flags);
+ }
+ /**
+ * Get the sendmail command (path + flags)
+ * @return string
+ */
+ public function getCommand()
+ {
+ return $this->getPath() . " -" . $this->getFlags();
+ }
+ /**
+ * Write a command to the open pipe
+ * @param string The command to write
+ * @throws Swift_ConnectionException If the pipe cannot be written to
+ */
+ protected function pipeIn($command, $end="\r\n")
+ {
+ if (!$this->isAlive()) throw new Swift_ConnectionException("The sendmail process is not alive and cannot be written to.");
+ if (!@fwrite($this->pipes[0], $command . $end) && !empty($command)) throw new Swift_ConnectionException("The sendmail process did not allow the command '" . $command . "' to be sent.");
+ fflush($this->pipes[0]);
+ }
+ /**
+ * Read data from the open pipe
+ * @return string
+ * @throws Swift_ConnectionException If the pipe is not operating as expected
+ */
+ protected function pipeOut()
+ {
+ if (strpos($this->getFlags(), "t") !== false) return;
+ if (!$this->isAlive()) throw new Swift_ConnectionException("The sendmail process is not alive and cannot be read from.");
+ $ret = "";
+ $line = 0;
+ while (true)
+ {
+ $line++;
+ stream_set_timeout($this->pipes[1], $this->timeout);
+ $tmp = @fgets($this->pipes[1]);
+ if ($tmp === false)
+ {
+ throw new Swift_ConnectionException("There was a problem reading line " . $line . " of a sendmail SMTP response. The response so far was:<br />[" . $ret . "]. It appears the process has died.");
+ }
+ $ret .= trim($tmp) . "\r\n";
+ if ($tmp{3} == " ") break;
+ }
+ fflush($this->pipes[1]);
+ return $ret = substr($ret, 0, -2);
+ }
+ /**
+ * Read a full response from the buffer (this is spoofed if running in -t mode)
+ * @return string
+ * @throws Swift_ConnectionException Upon failure to read
+ */
+ public function read()
+ {
+ if (strpos($this->getFlags(), "t") !== false)
+ {
+ switch (strtolower($this->request))
+ {
+ case null:
+ return "220 Greetings";
+ case "helo": case "ehlo":
+ return "250 hello";
+ case "mail": case "rcpt": case "rset":
+ return "250 ok";
+ case "quit":
+ return "221 bye";
+ case "data":
+ $this->send = true;
+ return "354 go ahead";
+ default:
+ return "250 ok";
+ }
+ }
+ else return $this->pipeOut();
+ }
+ /**
+ * Write a command to the process (leave off trailing CRLF)
+ * @param string The command to send
+ * @throws Swift_ConnectionException Upon failure to write
+ */
+ public function write($command, $end="\r\n")
+ {
+ if (strpos($this->getFlags(), "t") !== false)
+ {
+ if (!$this->send && strpos($command, " ")) $command = substr($command, strpos($command, " ")+1);
+ elseif ($this->send)
+ {
+ $this->pipeIn($command);
+ }
+ $this->request = $command;
+ $this->send = (strtolower($command) == "data");
+ }
+ else $this->pipeIn($command, $end);
+ }
+ /**
+ * Try to start the connection
+ * @throws Swift_ConnectionException Upon failure to start
+ */
+ public function start()
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Trying to start a sendmail process.");
+ }
+ if (!$this->getPath() || !$this->getFlags())
+ {
+ throw new Swift_ConnectionException("Sendmail cannot be started without a path to the binary including flags.");
+ }
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Trying to stat the executable '" . $this->getPath() . "'.");
+ }
+ if (!@lstat($this->getPath()))
+ {
+ throw new Swift_ConnectionException(
+ "Sendmail cannot be seen with lstat(). The command given [" . $this->getCommand() . "] does not appear to be valid.");
+ }
+
+ $pipes_spec = array(
+ array("pipe", "r"),
+ array("pipe", "w"),
+ array("pipe", "w")
+ );
+
+ $this->proc = proc_open($this->getCommand(), $pipes_spec, $this->pipes);
+
+ if (!$this->isAlive())
+ {
+ throw new Swift_ConnectionException(
+ "The sendmail process failed to start. Please verify that the path exists and PHP has permission to execute it.");
+ }
+ }
+ /**
+ * Try to close the connection
+ */
+ public function stop()
+ {
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Terminating sendmail process.");
+ }
+ foreach ((array)$this->pipes as $pipe)
+ {
+ @fclose($pipe);
+ }
+
+ if ($this->proc)
+ {
+ proc_close($this->proc);
+ $this->pipes = null;
+ $this->proc = null;
+ }
+ }
+ /**
+ * Check if the process is still alive
+ * @return boolean
+ */
+ public function isAlive()
+ {
+ return ($this->proc !== false
+ && is_resource($this->proc)
+ && is_resource($this->pipes[0])
+ && is_resource($this->pipes[1])
+ && $this->proc !== null);
+ }
+ /**
+ * Destructor.
+ * Cleans up by stopping any running processes.
+ */
+ public function __destruct()
+ {
+ $this->stop();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection/Sendmail.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Swift Mailer Connection Interface
+ * All connection handlers extend this abstract class
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Swift Connection Interface
+ * Lists methods which are required by any connections
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Connection
+{
+ /**
+ * Try to start the connection
+ * @throws Swift_ConnectionException If the connection cannot be started
+ */
+ public function start();
+ /**
+ * Return the contents of the buffer
+ * @return string
+ * @throws Swift_ConnectionException If the buffer cannot be read
+ */
+ public function read();
+ /**
+ * Write a command to the buffer
+ * @param string The command to send
+ * @throws Swift_ConnectionException If the write fails
+ */
+ public function write($command, $end="\r\n");
+ /**
+ * Try to stop the connection
+ * @throws Swift_ConnectionException If the connection cannot be closed/stopped
+ */
+ public function stop();
+ /**
+ * Check if the connection is up or not
+ * @return boolean
+ */
+ public function isAlive();
+ /**
+ * Add an extension which is available on this connection
+ * @param string The name of the extension
+ * @param array The list of attributes for the extension
+ */
+ public function setExtension($name, $list=array());
+ /**
+ * Check if an extension exists by the name $name
+ * @param string The name of the extension
+ * @return boolean
+ */
+ public function hasExtension($name);
+ /**
+ * Get the list of attributes for the extension $name
+ * @param string The name of the extension
+ * @return array
+ * @throws Swift_ConnectionException If no such extension can be found
+ */
+ public function getAttributes($name);
+ /**
+ * Execute logic needed after SMTP greetings
+ * @param Swift An instance of Swift
+ */
+ public function postConnect(Swift $instance);
+ /**
+ * Returns TRUE if the connection needs a EHLO greeting.
+ * @return boolean
+ */
+ public function getRequiresEHLO();
+ /**
+ * Set if the connection needs a EHLO greeting.
+ * @param boolean
+ */
+ public function setRequiresEHLO($set);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Connection.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionBase.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionBase.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionBase.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * Swift Mailer Connection Base Class
+ * All connection handlers extend this abstract class
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_LogContainer");
+Swift_ClassLoader::load("Swift_Connection");
+Swift_ClassLoader::load("Swift_ConnectionException");
+
+/**
+ * Swift Connection Base Class
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+abstract class Swift_ConnectionBase implements Swift_Connection
+{
+ /**
+ * Any extensions the server might support
+ * @var array
+ */
+ protected $extensions = array();
+ /**
+ * True if the connection is ESMTP.
+ * @var boolean
+ */
+ protected $isESMTP = false;
+
+ /**
+ * Set an extension which the connection reports to support
+ * @param string Extension name
+ * @param array Attributes of the extension
+ */
+ public function setExtension($name, $options=array())
+ {
+ $this->extensions[$name] = $options;
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("SMTP extension '" . $name . "' reported with attributes [" . implode(", ", $options) . "].");
+ }
+ }
+ /**
+ * Check if a given extension has been set as available
+ * @param string The name of the extension
+ * @return boolean
+ */
+ public function hasExtension($name)
+ {
+ return array_key_exists($name, $this->extensions);
+ }
+ /**
+ * Execute any needed logic after connecting and handshaking
+ */
+ public function postConnect(Swift $instance) {}
+ /**
+ * Get the list of attributes supported by the given extension
+ * @param string The name of the connection
+ * @return array The list of attributes
+ * @throws Swift_ConnectionException If the extension cannot be found
+ */
+ public function getAttributes($extension)
+ {
+ if ($this->hasExtension($extension))
+ {
+ return $this->extensions[$extension];
+ }
+ else
+ {
+ throw new Swift_ConnectionException(
+ "Unable to locate any attributes for the extension '" . $extension . "' since the extension cannot be found. " .
+ "Consider using hasExtension() to check.");
+ }
+ }
+ /**
+ * Returns TRUE if the connection needs a EHLO greeting.
+ * @return boolean
+ */
+ public function getRequiresEHLO()
+ {
+ return $this->isESMTP;
+ }
+ /**
+ * Set TRUE if the connection needs a EHLO greeting.
+ * @param boolean
+ */
+ public function setRequiresEHLO($set)
+ {
+ $this->isESMTP = (bool) $set;
+ $log = Swift_LogContainer::getLog();
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING))
+ {
+ $log->add("Forcing ESMTP mode. HELO is EHLO.");
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionBase.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionException.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionException.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionException.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * Swift Connection Exception
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_Exception");
+
+/**
+ * Swift Connection Exception
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_ConnectionException extends Swift_Exception
+{
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/ConnectionException.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeCommandListener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeCommandListener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeCommandListener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * Swift Mailer Before Command Event Listener Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Contains the list of methods a plugin requiring the use of a CommandEvent, before it is sent must implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_BeforeCommandListener extends Swift_Events_Listener
+{
+ /**
+ * Executes just before Swift sends a command
+ * @param Swift_Events_CommandEvent Information about the being command sent
+ */
+ public function beforeCommandSent(Swift_Events_CommandEvent $e);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeCommandListener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeSendListener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeSendListener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeSendListener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * Swift Mailer Before Send Event Listener Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Contains the list of methods a plugin requiring the use of a SendEvent before the message is sent must implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_BeforeSendListener extends Swift_Events_Listener
+{
+ /**
+ * Executes just before Swift sends a message
+ * @param Swift_Events_SendEvent Information about the message being sent
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $e);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/BeforeSendListener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandEvent.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandEvent.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandEvent.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * Swift Mailer Command Event
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Generated when Swift is sending a command
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Events_CommandEvent extends Swift_Events
+{
+ /**
+ * Contains the command being sent
+ * @var string
+ */
+ protected $string = null;
+ /**
+ * Contains the expected response code (or null)
+ * @var int
+ */
+ protected $code = null;
+
+ /**
+ * Constructor
+ * @param string The command being sent
+ * @param int The expected code
+ */
+ public function __construct($string, $code=null)
+ {
+ $this->setString($string);
+ $this->setCode($code);
+ }
+ /**
+ * Set the command being sent (without CRLF)
+ * @param string The command being sent
+ */
+ public function setString($string)
+ {
+ $this->string = (string) $string;
+ }
+ /**
+ * Get the command being sent
+ * @return string
+ */
+ public function getString()
+ {
+ return $this->string;
+ }
+ /**
+ * Set response code which is expected
+ * @param int The response code
+ */
+ public function setCode($code)
+ {
+ if ($code === null) $this->code = null;
+ else $this->code = (int) $code;
+ }
+ /**
+ * Get the expected response code
+ * @return int
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandEvent.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandListener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandListener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandListener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * Swift Mailer Command Event Listener Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Contains the list of methods a plugin requiring the use of a CommandEvent must implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_CommandListener extends Swift_Events_Listener
+{
+ /**
+ * Executes when Swift sends a command
+ * @param Swift_Events_CommandEvent Information about the command sent
+ */
+ public function commandSent(Swift_Events_CommandEvent $e);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/CommandListener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectEvent.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectEvent.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectEvent.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Swift Mailer Connect Event
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Generated every time Swift connects with a MTA
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Events_ConnectEvent extends Swift_Events
+{
+ /**
+ * A reference to the connection object
+ * @var Swift_Connection
+ */
+ protected $connection = null;
+
+ /**
+ * Constructor
+ * @param Swift_Connection The new connection
+ */
+ public function __construct(Swift_Connection $connection)
+ {
+ $this->connection = $connection;
+ }
+ /**
+ * Get the connection object
+ * @return Swift_Connection
+ */
+ public function getConnection()
+ {
+ return $this->connection;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectEvent.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectListener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectListener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectListener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * Swift Mailer Connect Event Listener Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Contains the list of methods a plugin requiring the use of a ConnectEvent must implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_ConnectListener extends Swift_Events_Listener
+{
+ /**
+ * Executes when Swift initiates a connection
+ * @param Swift_Events_ConnectEvent Information about the connection
+ */
+ public function connectPerformed(Swift_Events_ConnectEvent $e);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ConnectListener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectEvent.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectEvent.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectEvent.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Swift Mailer Disconnect Event
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Generated every time Swift disconnects from a MTA
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Events_DisconnectEvent extends Swift_Events
+{
+ /**
+ * A reference to the connection object
+ * @var Swift_Connection
+ */
+ protected $connection = null;
+
+ /**
+ * Constructor
+ * @param Swift_Connection The dead connection
+ */
+ public function __construct(Swift_Connection $connection)
+ {
+ $this->connection = $connection;
+ }
+ /**
+ * Get the connection object
+ * @return Swift_Connection
+ */
+ public function getConnection()
+ {
+ return $this->connection;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectEvent.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectListener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectListener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectListener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * Swift Mailer Disconnect Event Listener Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Contains the list of methods a plugin requiring the use of a DisconnectEvent must implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_DisconnectListener extends Swift_Events_Listener
+{
+ /**
+ * Executes when Swift closes a connection
+ * @param Swift_Events_DisconnectEvent Information about the connection
+ */
+ public function disconnectPerformed(Swift_Events_DisconnectEvent $e);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/DisconnectListener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/Listener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/Listener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/Listener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * Swift Mailer Event Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Used for identity only
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_Listener {}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/Listener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ListenerMapper.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ListenerMapper.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ListenerMapper.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * Swift Mailer Mapper for Event Listeners
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Maps event listener names to the methods they implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Events_ListenerMapper
+{
+ /**
+ * Get the mapped names (Class => Method(s))
+ * @return array
+ */
+ public static function getMap()
+ {
+ $map = array(
+ "SendListener" => "sendPerformed",
+ "BeforeSendListener" => "beforeSendPerformed",
+ "CommandListener" => "commandSent",
+ "BeforeCommandListener" => "beforeCommandSent",
+ "ResponseListener" => "responseReceived",
+ "ConnectListener" => "connectPerformed",
+ "DisconnectListener" => "disconnectPerformed"
+ );
+ return $map;
+ }
+
+ /**
+ * Get the name of the method which needs running based upon the listener name
+ * @return string
+ */
+ public static function getNotifyMethod($listener)
+ {
+ $map = self::getMap();
+ if (isset($map[$listener])) return $map[$listener];
+ else return false;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ListenerMapper.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseEvent.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseEvent.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseEvent.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * Swift Mailer Response Event
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Generated when Swift receives a server response
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Events_ResponseEvent extends Swift_Events
+{
+ /**
+ * Contains the response received
+ * @var string
+ */
+ protected $string = null;
+ /**
+ * Contains the response code
+ * @var int
+ */
+ protected $code = null;
+
+ /**
+ * Constructor
+ * @param string The received response
+ */
+ public function __construct($string)
+ {
+ $this->setString($string);
+ $this->setCode(substr($string, 0, 3));
+ }
+ /**
+ * Set the response received
+ * @param string The response
+ */
+ public function setString($string)
+ {
+ $this->string = (string) $string;
+ }
+ /**
+ * Get the received response
+ * @return string
+ */
+ public function getString()
+ {
+ return $this->string;
+ }
+ /**
+ * Set response code
+ * @param int The response code
+ */
+ public function setCode($code)
+ {
+ $this->code = (int) $code;
+ }
+ /**
+ * Get the response code
+ * @return int
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseEvent.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseListener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseListener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseListener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * Swift Mailer Response Event Listener Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Contains the list of methods a plugin requiring the use of a ResponseEvent must implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_ResponseListener extends Swift_Events_Listener
+{
+ /**
+ * Executes when Swift receives a response
+ * @param Swift_Events_ResponseEvent Information about the response
+ */
+ public function responseReceived(Swift_Events_ResponseEvent $e);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/ResponseListener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendEvent.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendEvent.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendEvent.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,116 @@
+<?php
+
+/**
+ * Swift Mailer Send Event
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Generated every time a message is sent with Swift
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Events_SendEvent extends Swift_Events
+{
+ /**
+ * A reference to the message being sent
+ * @var Swift_Message
+ */
+ protected $message = null;
+ /**
+ * A reference to the sender address object
+ * @var Swift_Address
+ */
+ protected $sender = null;
+ /**
+ * A reference to the recipients being sent to
+ * @var Swift_RecipientList
+ */
+ protected $recipients = null;
+ /**
+ * The number of recipients sent to so
+ * @var int
+ */
+ protected $sent = null;
+ /**
+ * Recipients we couldn't send to
+ * @var array
+ */
+ protected $failed = array();
+
+ /**
+ * Constructor
+ * @param Swift_Message The message being sent
+ * @param Swift_RecipientList The recipients
+ * @param Swift_Address The sender address
+ * @param int The number of addresses sent to
+ */
+ public function __construct(Swift_Message $message, Swift_RecipientList $list, Swift_Address $from, $sent=0)
+ {
+ $this->message = $message;
+ $this->recipients = $list;
+ $this->sender = $from;
+ $this->sent = $sent;
+ }
+ /**
+ * Get the message being sent
+ * @return Swift_Message
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+ /**
+ * Get the list of recipients
+ * @return Swift_RecipientList
+ */
+ public function getRecipients()
+ {
+ return $this->recipients;
+ }
+ /**
+ * Get the sender's address
+ * @return Swift_Address
+ */
+ public function getSender()
+ {
+ return $this->sender;
+ }
+ /**
+ * Set the number of recipients to how many were sent
+ * @param int
+ */
+ public function setNumSent($sent)
+ {
+ $this->sent = (int) $sent;
+ }
+ /**
+ * Get the total number of addresses to which the email sent successfully
+ * @return int
+ */
+ public function getNumSent()
+ {
+ return $this->sent;
+ }
+ /**
+ * Add an email address to the failed recipient list for this send
+ * @var string The email address
+ */
+ public function addFailedRecipient($address)
+ {
+ $this->failed[] = $address;
+ }
+ /**
+ * Get an array of failed recipients for this send
+ * @return array
+ */
+ public function getFailedRecipients()
+ {
+ return $this->failed;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendEvent.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendListener.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendListener.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendListener.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * Swift Mailer Send Event Listener Interface
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Contains the list of methods a plugin requiring the use of a SendEvent must implement
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Events_SendListener extends Swift_Events_Listener
+{
+ /**
+ * Executes when Swift sends a message
+ * @param Swift_Events_SendEvent Information about the message being sent
+ */
+ public function sendPerformed(Swift_Events_SendEvent $e);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events/SendListener.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * Swift Mailer Events Layer
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Events
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Provides core functionality for Swift generated events for plugins
+ * @package Swift_Events
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+abstract class Swift_Events
+{
+ /**
+ * An instance of Swift
+ * @var Swift
+ */
+ protected $swift = null;
+
+ /**
+ * Provide a reference to te currently running Swift this event was generated from
+ * @param Swift
+ */
+ public function setSwift(Swift $swift)
+ {
+ $this->swift = $swift;
+ }
+ /**
+ * Get the current instance of swift
+ * @return Swift
+ */
+ public function getSwift()
+ {
+ return $this->swift;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Events.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Exception.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Exception.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Exception.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * Swift Mailer Logging Layer Interface
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Log
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_LogContainer");
+
+/**
+ * The Logger Interface
+ * @package Swift_Log
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Exception extends Exception
+{
+ /**
+ * Constructor.
+ * Creates the exception and appends log information if available.
+ * @param string Message
+ * @param int Code
+ */
+ public function __construct($message, $code = 0)
+ {
+ if (($log = Swift_LogContainer::getLog()) && $log->isEnabled())
+ {
+ $message .= "<h3>Log Information</h3>";
+ $message .= "<pre>" . htmlentities($log->dump(true)) . "</pre>";
+ }
+ parent::__construct($message, $code);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Exception.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/File.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/File.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/File.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,215 @@
+<?php
+
+/**
+ * Swift Mailer File Stream Wrapper
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_FileException");
+
+/**
+ * Swift File stream abstraction layer
+ * Reads bytes from a file
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_File
+{
+ /**
+ * The accessible path to the file
+ * @var string
+ */
+ protected $path = null;
+ /**
+ * The name of the file
+ * @var string
+ */
+ protected $name = null;
+ /**
+ * The resource returned by fopen() against the path
+ * @var resource
+ */
+ protected $handle = null;
+ /**
+ * The status of magic_quotes in php.ini
+ * @var boolean
+ */
+ protected $magic_quotes = false;
+
+ /**
+ * Constructor
+ * @param string The path the the file
+ * @throws Swift_FileException If the file cannot be found
+ */
+ public function __construct($path)
+ {
+ $this->setPath($path);
+ $this->magic_quotes = get_magic_quotes_runtime();
+ }
+ /**
+ * Set the path to the file
+ * @param string The path to the file
+ * @throws Swift_FileException If the file cannot be found
+ */
+ public function setPath($path)
+ {
+ if (!file_exists($path))
+ {
+ throw new Swift_FileException("No such file '" . $path ."'");
+ }
+ $this->handle = null;
+ $this->path = $path;
+ $this->name = null;
+ $this->name = $this->getFileName();
+ }
+ /**
+ * Get the path to the file
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+ /**
+ * Get the name of the file without it's full path
+ * @return string
+ */
+ public function getFileName()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+ else
+ {
+ return basename($this->getPath());
+ }
+ }
+ /**
+ * Establish an open file handle on the file if the file is not yet opened
+ * @throws Swift_FileException If the file cannot be opened for reading
+ */
+ protected function createHandle()
+ {
+ if ($this->handle === null)
+ {
+ if (!$this->handle = fopen($this->path, "rb"))
+ {
+ throw new Swift_FileException("Unable to open file '" . $this->path . " for reading. Check the file permissions.");
+ }
+ }
+ }
+ /**
+ * Check if the pointer as at the end of the file
+ * @return boolean
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function EOF()
+ {
+ $this->createHandle();
+ return feof($this->handle);
+ }
+ /**
+ * Get a single byte from the file
+ * Returns false past EOF
+ * @return string
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function getByte()
+ {
+ $this->createHandle();
+ return $this->read(1);
+ }
+ /**
+ * Read one full line from the file including the line ending
+ * Returns false past EOF
+ * @return string
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function readln()
+ {
+ set_magic_quotes_runtime(0);
+ $this->createHandle();
+ if (!$this->EOF())
+ {
+ $ret = fgets($this->handle);
+ }
+ else $ret = false;
+
+ set_magic_quotes_runtime($this->magic_quotes);
+
+ return $ret;
+ }
+ /**
+ * Get the entire file contents as a string
+ * @return string
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function readFull()
+ {
+ $ret = "";
+ set_magic_quotes_runtime(0);
+ while (false !== $chunk = $this->read(8192, false)) $ret .= $chunk;
+ set_magic_quotes_runtime($this->magic_quotes);
+ return $ret;
+ }
+ /**
+ * Read a given number of bytes from the file
+ * Returns false past EOF
+ * @return string
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function read($bytes, $unquote=true)
+ {
+ if ($unquote) set_magic_quotes_runtime(0);
+ $this->createHandle();
+ if (!$this->EOF())
+ {
+ $ret = fread($this->handle, $bytes);
+ }
+ else $ret = false;
+
+ if ($unquote) set_magic_quotes_runtime($this->magic_quotes);
+
+ return $ret;
+ }
+ /**
+ * Get the size of the file in bytes
+ * @return int
+ */
+ public function length()
+ {
+ return filesize($this->path);
+ }
+ /**
+ * Close the open handle on the file
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function close()
+ {
+ $this->createHandle();
+ fclose($this->handle);
+ $this->handle = null;
+ }
+ /**
+ * Reset the file pointer back to zero
+ */
+ public function reset()
+ {
+ $this->createHandle();
+ fseek($this->handle, 0);
+ }
+ /**
+ * Destructor
+ * Closes the file
+ */
+ public function __destruct()
+ {
+ if ($this->handle !== null) $this->close();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/File.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/FileException.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/FileException.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/FileException.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * Swift File Exception
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_Exception");
+
+/**
+ * Swift File Exception
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_FileException extends Swift_Exception
+{
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/FileException.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/Array.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/Array.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/Array.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * Swift Mailer Array Iterator Interface
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Iterator");
+
+/**
+ * Swift Array Iterator Interface
+ * Iterates over a standard PHP array.
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Iterator_Array implements Swift_Iterator
+{
+ /**
+ * All keys in this array.
+ * @var array
+ */
+ protected $keys;
+ /**
+ * All values in this array.
+ * @var array
+ */
+ protected $values;
+ /**
+ * The current array position.
+ * @var int
+ */
+ protected $pos = -1;
+
+ /**
+ * Ctor.
+ * @param array The array to iterate over.
+ */
+ public function __construct($input)
+ {
+ $input = (array) $input;
+ $this->keys = array_keys($input);
+ $this->values = array_values($input);
+ }
+ /**
+ * Returns the original array.
+ * @return array
+ */
+ public function getArray()
+ {
+ return array_combine($this->keys, $this->values);
+ }
+ /**
+ * Returns true if there is a value after the current one.
+ * @return boolean
+ */
+ public function hasNext()
+ {
+ return array_key_exists($this->pos + 1, $this->keys);
+ }
+ /**
+ * Moves to the next array element if possible.
+ * @return boolean
+ */
+ public function next()
+ {
+ if ($this->hasNext())
+ {
+ ++$this->pos;
+ return true;
+ }
+
+ return false;
+ }
+ /**
+ * Goes directly to the given element in the array if possible.
+ * @param int Numeric position
+ * @return boolean
+ */
+ public function seekTo($pos)
+ {
+ if (array_key_exists($pos, $this->keys))
+ {
+ $this->pos = $pos;
+ return true;
+ }
+
+ return false;
+ }
+ /**
+ * Returns the value at the current position, or NULL otherwise.
+ * @return mixed.
+ */
+ public function getValue()
+ {
+ if (array_key_exists($this->pos, $this->values))
+ return $this->values[$this->pos];
+ else return null;
+ }
+ /**
+ * Gets the current numeric position within the array.
+ * @return int
+ */
+ public function getPosition()
+ {
+ return $this->pos;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/Array.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/MySQLResult.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/MySQLResult.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/MySQLResult.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * Swift Mailer MySQL Resultset Iterator
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Iterator");
+
+/**
+ * Swift Mailer MySQL Resultset Iterator.
+ * Iterates over MySQL Resultset from mysql_query().
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Iterator_MySQLResult implements Swift_Iterator
+{
+ /**
+ * The MySQL resource.
+ * @var resource
+ */
+ protected $resultSet;
+ /**
+ * The current row (array) in the resultset.
+ * @var array
+ */
+ protected $currentRow = array(null, null);
+ /**
+ * The current array position.
+ * @var int
+ */
+ protected $pos = -1;
+ /**
+ * The total number of rows in the resultset.
+ * @var int
+ */
+ protected $numRows = 0;
+
+ /**
+ * Ctor.
+ * @param resource The resultset iterate over.
+ */
+ public function __construct($rs)
+ {
+ $this->resultSet = $rs;
+ $this->numRows = mysql_num_rows($rs);
+ }
+ /**
+ * Get the resultset.
+ * @return resource
+ */
+ public function getResultSet()
+ {
+ return $this->resultSet;
+ }
+ /**
+ * Returns true if there is a value after the current one.
+ * @return boolean
+ */
+ public function hasNext()
+ {
+ return (($this->pos + 1) < $this->numRows);
+ }
+ /**
+ * Moves to the next array element if possible.
+ * @return boolean
+ */
+ public function next()
+ {
+ if ($this->hasNext())
+ {
+ $this->currentRow = mysql_fetch_array($this->resultSet);
+ $this->pos++;
+ return true;
+ }
+
+ return false;
+ }
+ /**
+ * Goes directly to the given element in the array if possible.
+ * @param int Numeric position
+ * @return boolean
+ */
+ public function seekTo($pos)
+ {
+ if ($pos >= 0 && $pos < $this->numRows)
+ {
+ mysql_data_seek($this->resultSet, $pos);
+ $this->currentRow = mysql_fetch_array($this->resultSet);
+ mysql_data_seek($this->resultSet, $pos);
+ $this->pos = $pos;
+ return true;
+ }
+
+ return false;
+ }
+ /**
+ * Returns the value at the current position, or NULL otherwise.
+ * @return mixed.
+ */
+ public function getValue()
+ {
+ $row = $this->currentRow;
+ if ($row[0] !== null)
+ return new Swift_Address($row[0], isset($row[1]) ? $row[1] : null);
+ else
+ return null;
+ }
+ /**
+ * Gets the current numeric position within the array.
+ * @return int
+ */
+ public function getPosition()
+ {
+ return $this->pos;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator/MySQLResult.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * Swift Mailer Iterator Interface
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * Swift Iterator Interface
+ * Provides the interface for iterators used for retrieving addresses in batch sends.
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+interface Swift_Iterator
+{
+ /**
+ * Check if there is a value in the list after the current one.
+ * @return boolean
+ */
+ public function hasNext();
+ /**
+ * Move to the next position in the list if possible.
+ * @return boolean
+ */
+ public function next();
+ /**
+ * Seek to the given numeric index in the list of possible.
+ * @return boolean
+ */
+ public function seekTo($pos);
+ /**
+ * Get the value of the list at the current position.
+ * @return mixed
+ */
+ public function getValue();
+ /**
+ * Get the current list position.
+ * @return int
+ */
+ public function getPosition();
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Iterator.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log/DefaultLog.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log/DefaultLog.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log/DefaultLog.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * Swift Mailer Default Logger
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Log
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Log");
+
+/**
+ * The Default Logger class
+ * @package Swift_Log
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Log_DefaultLog extends Swift_Log
+{
+ /**
+ * Lines in the log
+ * @var array
+ */
+ protected $entries = array();
+
+ /**
+ * Add a log entry
+ * @param string The text for this entry
+ * @param string The label for the type of entry
+ */
+ public function add($text, $type = self::NORMAL)
+ {
+ $this->entries[] = $type . " " . $text;
+ if ($this->getMaxSize() > 0) $this->entries = array_slice($this->entries, (-1 * $this->getMaxSize()));
+ }
+ /**
+ * Dump the contents of the log to the browser.
+ * @param boolean True if the string should be returned rather than output.
+ */
+ public function dump($return_only=false)
+ {
+ $ret = implode("\n", $this->entries);
+ if (!$return_only) echo $ret;
+ else return $ret;
+ }
+ /**
+ * Empty the log
+ */
+ public function clear()
+ {
+ $this->failedRecipients = null;
+ $this->failedRecipients = array();
+ $this->entries = null;
+ $this->entries = array();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log/DefaultLog.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * Swift Mailer Logging Layer base class.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Log
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * The Logger class/interface.
+ * @package Swift_Log
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+abstract class Swift_Log
+{
+ /**
+ * A command type entry
+ */
+ const COMMAND = ">>";
+ /**
+ * A response type entry
+ */
+ const RESPONSE = "<<";
+ /**
+ * An error type entry
+ */
+ const ERROR = "!!";
+ /**
+ * A standard entry
+ */
+ const NORMAL = "++";
+ /**
+ * Logging is off.
+ */
+ const LOG_NOTHING = 0;
+ /**
+ * Only errors are logged.
+ */
+ const LOG_ERRORS = 1;
+ /**
+ * Errors + sending failures.
+ */
+ const LOG_FAILURES = 2;
+ /**
+ * All SMTP instructions + failures + errors.
+ */
+ const LOG_NETWORK = 3;
+ /**
+ * Runtime info + SMTP instructions + failures + errors.
+ */
+ const LOG_EVERYTHING = 4;
+ /**
+ * Failed recipients
+ * @var array
+ */
+ protected $failedRecipients = array();
+ /**
+ * The maximum number of log entries
+ * @var int
+ */
+ protected $maxSize = 50;
+ /**
+ * The level of logging currently set.
+ * @var int
+ */
+ protected $logLevel = self::LOG_NOTHING;
+
+ /**
+ * Add a new entry to the log
+ * @param string The information to log
+ * @param string The type of entry (see the constants: COMMAND, RESPONSE, ERROR, NORMAL)
+ */
+ abstract public function add($text, $type = self::NORMAL);
+ /**
+ * Dump the contents of the log to the browser.
+ * @param boolean True if the string should be returned rather than output.
+ */
+ abstract public function dump($return_only=false);
+ /**
+ * Empty the log contents
+ */
+ abstract public function clear();
+ /**
+ * Check if logging is enabled.
+ */
+ public function isEnabled()
+ {
+ return ($this->logLevel > self::LOG_NOTHING);
+ }
+ /**
+ * Add a failed recipient to the list
+ * @param string The address of the recipient
+ */
+ public function addFailedRecipient($address)
+ {
+ $this->failedRecipients[$address] = null;
+ $this->add("Recipient '" . $address . "' rejected by connection.", self::ERROR);
+ }
+ /**
+ * Get the list of failed recipients
+ * @return array
+ */
+ public function getFailedRecipients()
+ {
+ return array_keys($this->failedRecipients);
+ }
+ /**
+ * Set the maximum size of this log (zero is no limit)
+ * @param int The maximum entries
+ */
+ public function setMaxSize($size)
+ {
+ $this->maxSize = (int) $size;
+ }
+ /**
+ * Get the current maximum allowed log size
+ * @return int
+ */
+ public function getMaxSize()
+ {
+ return $this->maxSize;
+ }
+ /**
+ * Set the log level to one of the constants provided.
+ * @param int Level
+ */
+ public function setLogLevel($level)
+ {
+ $level = (int)$level;
+ $this->add("Log level changed to " . $level, self::NORMAL);
+ $this->logLevel = $level;
+ }
+ /**
+ * Get the current log level.
+ * @return int
+ */
+ public function getLogLevel()
+ {
+ return $this->logLevel;
+ }
+ /**
+ * Check if the log level includes the one given.
+ * @param int Level
+ * @return boolean
+ */
+ public function hasLevel($level)
+ {
+ return ($this->logLevel >= ((int)$level));
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Log.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/LogContainer.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/LogContainer.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/LogContainer.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * A registry for the logger object.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Log
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_Log_DefaultLog");
+
+/**
+ * A registry holding the current instance of the log.
+ * @package Swift_Log
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_LogContainer
+{
+ /**
+ * The log instance.
+ * @var Swift_Log
+ */
+ protected static $log = null;
+
+ /**
+ * Registers the logger.
+ * @param Swift_Log The log
+ */
+ public static function setLog(Swift_Log $log)
+ {
+ self::$log = $log;
+ }
+ /**
+ * Returns the current instance of the log, or lazy-loads the default one.
+ * @return Swift_Log
+ */
+ public static function getLog()
+ {
+ if (self::$log === null)
+ {
+ self::setLog(new Swift_Log_DefaultLog());
+ }
+ return self::$log;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/LogContainer.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Attachment.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Attachment.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Attachment.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * Swift Mailer Message Attachment
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Attachment component for Swift Mailer
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message_Attachment extends Swift_Message_Mime
+{
+ /**
+ * A numeric counter, incremented by 1 when a filename is made.
+ * @var int
+ */
+ protected static $fileId = 0;
+
+ /**
+ * Constructor
+ * @param mixed The data to use in the body
+ * @param string Mime type
+ * @param string The encoding format used
+ * @param string The charset used
+ */
+ public function __construct($data=null, $name=null, $type="application/octet-stream", $encoding="base64", $disposition="attachment")
+ {
+ parent::__construct();
+
+ $this->setContentType($type);
+ $this->setEncoding($encoding);
+ $this->setDescription($name);
+ $this->setDisposition($disposition);
+ $this->setFileName($name);
+
+ if ($data !== null) $this->setData($data, ($name === null));
+ }
+ /**
+ * Get a unique filename (just a sequence)
+ * @param string the prefix for the filename
+ * @return string
+ */
+ public static function generateFileName($prefix="file")
+ {
+ return $prefix . (self::$fileId++);
+ }
+ /**
+ * Get the level in the MIME hierarchy at which this section should appear.
+ * @return string
+ */
+ public function getLevel()
+ {
+ return Swift_Message_Mime::LEVEL_MIXED;
+ }
+ /**
+ * Overrides setData() in MIME so that a filename can be set
+ * @param mixed The data to set for the body
+ * @param boolean If the stream is a file, should it's filename be used?
+ * @throws Swift_FileException If the stream cannot be read
+ */
+ public function setData($data, $read_filename=true)
+ {
+ parent::setData($data);
+ if ($read_filename && ($data instanceof Swift_file))
+ {
+ $this->setFileName($data->getFileName());
+ }
+ }
+ /**
+ * Set the name (and description) used to identify the file
+ * This method overrides any value previously set with setDescription()
+ * @param string The filename including it's extension if any
+ * @throws Swift_Message_MimeException If some required headers have been deliberately removed
+ */
+ public function setFileName($name)
+ {
+ $this->headers->setAttribute("Content-Type", "name", $name);
+ $this->setDescription($name);
+ if ($this->headers->has("Content-Disposition"))
+ {
+ $this->headers->setAttribute("Content-Disposition", "filename", $name);
+ }
+ }
+ /**
+ * Get the filename of this attachment
+ * @return string
+ * @throws Swift_Message_MimeException If some vital headers have been removed
+ */
+ public function getFileName()
+ {
+ if ($this->headers->hasAttribute("Content-Type", "name"))
+ {
+ return $this->headers->getAttribute("Content-Type", "name");
+ }
+ else return null;
+ }
+ /**
+ * Set the Content-Description header
+ * @param string The description in the header (filename usually!)
+ */
+ public function setDescription($desc)
+ {
+ $this->headers->set("Content-Description", $desc);
+ }
+ /**
+ * Return the description in the headers
+ * @return string
+ */
+ public function getDescription()
+ {
+ if ($this->headers->has("Content-Description"))
+ {
+ return $this->headers->get("Content-Description");
+ }
+ else return null;
+ }
+ /**
+ * Set the disposition of the attachment (usually inline or attachment)
+ * @param string The value to use in the Content-Disposition field
+ */
+ public function setDisposition($disposition)
+ {
+ $this->headers->set("Content-Disposition", $disposition);
+ }
+ /**
+ * Get the disposition used in the attachment (usually inline or attachment)
+ * @return string
+ */
+ public function getDisposition()
+ {
+ if ($this->headers->has("Content-Disposition"))
+ {
+ return $this->headers->get("Content-Disposition");
+ }
+ else return null;
+ }
+ /**
+ * Execute needed logic prior to building
+ */
+ public function preBuild()
+ {
+ if ($this->getFileName() === null)
+ {
+ if ($this->getData() instanceof Swift_File)
+ {
+ $this->setFileName($this->getData()->getFileName());
+ }
+ else
+ {
+ $this->setFileName(self::generateFileName("file.att."));
+ }
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Attachment.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/EmbeddedFile.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/EmbeddedFile.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/EmbeddedFile.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * Swift Mailer Embedded File (like an image or a midi file)
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Message_Attachment");
+
+/**
+ * Embedded File component for Swift Mailer
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message_EmbeddedFile extends Swift_Message_Attachment
+{
+ /**
+ * The content-id in the headers (used in <img src=...> values)
+ * @var string
+ */
+ protected $cid = null;
+
+ /**
+ * Constructor
+ * @param mixed The input source. Can be a file or a string
+ * @param string The filename to use, optional
+ * @param string The MIME type to use, optional
+ * @param string The Content-ID to use, optional
+ * @param string The encoding format to use, optional
+ */
+ public function __construct($data=null, $name=null, $type="application/octet-stream", $cid=null, $encoding="base64")
+ {
+ parent::__construct($data, $name, $type, $encoding, "inline");
+
+ if ($cid === null)
+ {
+ $cid = self::generateFileName("swift-" . uniqid(time()) . ".");
+ $cid = urlencode($cid) . "@" . (!empty($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : "swift");
+ }
+ $this->setContentId($cid);
+
+ if ($name === null && !($data instanceof Swift_File)) $this->setFileName($cid);
+
+ $this->headers->set("Content-Description", null);
+ }
+ /**
+ * Get the level in the MIME hierarchy at which this section should appear.
+ * @return string
+ */
+ public function getLevel()
+ {
+ return Swift_Message_Mime::LEVEL_RELATED;
+ }
+ /**
+ * Set the Content-Id to use
+ * @param string The content-id
+ */
+ public function setContentId($id)
+ {
+ $id = (string) $id;
+ $this->cid = $id;
+ $this->headers->set("Content-ID", "<" . $id . ">");
+ }
+ /**
+ * Get the content-id of this file
+ * @return string
+ */
+ public function getContentId()
+ {
+ return $this->cid;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/EmbeddedFile.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Encoder.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Encoder.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Encoder.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,455 @@
+<?php
+
+/**
+ * Swift Mailer Message Encoder
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_File");
+
+/**
+ * Encodes strings in a variety of formats and detects some encoding formats
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message_Encoder
+{
+ /**
+ * A regular expression which matches valid e-mail addresses (including some unlikely ones)
+ */
+ const CHEAP_ADDRESS_RE = '(?#Start of dot-atom
+ )[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+(?:\.[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+)*(?#
+ End of dot-atom)(?:@(?#Start of domain)[-0-9A-Za-z]+(?:\.[-0-9A-Za-z]+)*(?#End of domain))?';
+ /**
+ * A singleton of this class
+ * @var Swift_Message_Encoder
+ */
+ protected static $instance = null;
+ /**
+ * Retreive an instance of the encoder as a singleton.
+ * New instances are never ever needed since it's monostatic.
+ * @return Message_Encoder
+ */
+ public static function instance()
+ {
+ if (self::$instance === null)
+ {
+ self::$instance = new Swift_Message_Encoder();
+ }
+ return self::$instance;
+ }
+ /**
+ * Break a string apart at every occurence of <add@ress> and return an array
+ * This method does NOT remove any characters like a preg_split() would do.
+ * Elements matching an address start with "a" followed by the numeric index
+ * @param string The input string to separate
+ * @return array
+ */
+ public function addressChunk($input)
+ {
+ $elements = 0;
+ while (preg_match('/^(.*?)(<' . self::CHEAP_ADDRESS_RE . '>)/s', $input, $matches))
+ {
+ if (!empty($matches[1])) $ret[($elements++)] = $matches[1];
+ $ret[('a' . ($elements++))] = $matches[2];
+ $input = substr($input, strlen($matches[0]));
+ }
+ if ($input != "") $ret[($elements++)] = $input; //Whatever is left over
+
+ return $ret;
+ }
+ /**
+ * Break a string apart at every occurence of <xxxyyy> and return an array
+ * This method does NOT remove any characters like a preg_split() would do.
+ * Elements matching a quoted string start with "a" followed by the numeric index
+ * @param string The input string to separate
+ * @return array
+ */
+ public function quoteChunk($input)
+ {
+ $elements = 0;
+ while (preg_match('/^(.*?)(<[\x20-\x3A\x3C-\x7E]*>)/s', $input, $matches))
+ {
+ if (!empty($matches[1])) $ret[($elements++)] = $matches[1];
+ $ret[('a' . ($elements++))] = $matches[2];
+ $input = substr($input, strlen($matches[0]));
+ }
+ if ($input != "") $ret[($elements++)] = $input; //Whatever is left over
+
+ return $ret;
+ }
+ /**
+ * Return the base64 encoded version of the string
+ * @param string The input string to encode
+ * @param int The maximum length of each line of output (inc CRLF)
+ * @param int The maximum length of the first line in the output (for headers)
+ * @param boolean Whether email addresses between < and > chars should be preserved or not
+ * @param string The line ending
+ * @return string
+ */
+ public function base64Encode($data, $chunk=76, $init_chunk=0, $headers=false, $le="\r\n")
+ {
+ $ret = "";
+ $chunk -= 2;
+ $chunk = $this->getHcf($chunk, 4);
+
+ if ($init_chunk >= 2)
+ {
+ $init_chunk -= 2;
+ $init_chunk = $this->getHcf($init_chunk, 4);
+ }
+
+ if ($headers) $data = $this->quoteChunk($data);
+ else $data = array($data);
+
+ foreach ($data as $key => $string)
+ {
+ $key = (string) $key;
+ if ($key{0} == 'a') //This is an address
+ {
+ if ($init_chunk && $init_chunk < (strlen($string)+2)) $ret .= $le;
+ $ret .= $le . $string;
+ }
+ else
+ {
+ $string = $this->rawBase64Encode($string);
+ if ($init_chunk > 2)
+ {
+ $ret .= substr($string, 0, $init_chunk) . $le;
+ $string = substr($string, $init_chunk);
+ }
+ elseif ($init_chunk) $ret .= $le;
+
+ $ret .= trim(chunk_split($string, $chunk, $le)) . $le;
+ }
+ $init_chunk = 0;
+ }
+
+ return trim($ret);
+ }
+ /**
+ * Return the base64 encoded version of a string with no breaks
+ * @param The input string to encode
+ * @return string
+ */
+ public function rawBase64Encode($string)
+ {
+ return $string = base64_encode($string);
+ }
+ /**
+ * Return the base64 encoded version of a file
+ * @param Swift_File The file input stream
+ * @param int Max line length
+ * @param string The line ending
+ * @return Swift_Cache_OutputStream
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function base64EncodeFile(Swift_File $file, $chunk=76, $le="\r\n")
+ {
+ Swift_ClassLoader::load("Swift_CacheFactory");
+ $cache = Swift_CacheFactory::getCache();
+ $chunk -= 2;
+ $chunk = $this->getHcf($chunk, 4);
+ $loop = false;
+ //We have to read in multiples of 3 bytes but avoid doing such small chunks that it takes too long
+ while (false !== $bytes = $file->read(8190))
+ {
+ if ($loop) $cache->write("b64", $le);
+ $loop = true;
+ $next = chunk_split($this->rawBase64Encode($bytes), $chunk, $le);
+ $next = trim($next);
+ $cache->write("b64", $next);
+ }
+ $file->reset();
+ return $cache->getOutputStream("b64");
+ }
+ /**
+ * Return the quoted printable version of the input string
+ * @param string The input string to encode
+ * @param int The maximum length of each line of output (inc CRLF)
+ * @param int The maximum length of the first line in the output (for headers)
+ * @param boolean Whether email addresses between < and > chars should be preserved or not
+ * @param string The line ending
+ * @return string
+ */
+ public function QPEncode($data, $chunk=76, $init_chunk=0, $headers=false, $le="\r\n")
+ {
+ $ret = "";
+ if ($headers) $data = $this->quoteChunk($data);
+ else $data = array($data);
+
+ $trailing_spaces = chr(9) . chr(32);
+ foreach ($data as $key => $string)
+ {
+ $key = (string) $key;
+ if ($key{0} == 'a') //An address
+ {
+ if ($init_chunk && $init_chunk < (strlen($string)+3)) $ret .= "=";
+ $ret .= $le . $string;
+ }
+ else
+ {
+ $lines = explode($le, $string);
+ foreach ($lines as $n => $line)
+ $lines[$n] = $this->rawQPEncode(rtrim($line, $trailing_spaces));
+ $string = implode($le, $lines);
+ if ($init_chunk > 3)
+ {
+ if (preg_match('/^.{1,'.($init_chunk-5).'}[^=]{2}(?!=[A-F0-9]{2})/', $string, $matches)
+ || preg_match('/^.{1,'.($init_chunk-6).'}([^=]{0,3})?/', $string, $matches))
+ {
+ $ret .= $this->fixLE($matches[0] . "=", $le); //fixLE added 24/08/07
+ $string = substr($string, strlen($matches[0]));
+ }
+ }
+ elseif ($init_chunk) $ret .= "=";
+
+ while (preg_match('/^.{1,'.($init_chunk-5).'}[^=]{2}(?!=[A-F0-9]{2})/', $string, $matches)
+ || preg_match('/^.{1,'.($chunk-6).'}([^=]{0,3})?/', $string, $matches)
+ || (strlen($string) > 0 && $matches = array($string)))
+ {
+ $ret .= $this->fixLE($le . $matches[0] . "=", $le); //fixLE added 24/08/07
+ $string = substr($string, strlen($matches[0]));
+ }
+ }
+ $init_chunk = 0;
+ }
+
+ if (substr($ret, -1) == "=") return trim(substr($ret, 0, -1));
+ else return trim($ret);
+ }
+ /**
+ * Return the QP encoded version of a string with no breaks
+ * @param string The input to encode
+ * @param boolean True if the data we're encoding is binary
+ * @return string
+ */
+ public function rawQPEncode($string, $bin=false)
+ {
+ $ret = "";
+ if (!$bin)
+ {
+ $string = str_replace(array("\r\n", "\r"), "\n", $string);
+ $string = str_replace("\n", "\r\n", $string);
+ }
+ $len = strlen($string);
+ for ($i = 0; $i < $len; $i++)
+ {
+ $val = ord($string{$i});
+ //9, 32 = HT, SP; 10, 13 = CR, LF; 33-60 & 62-126 are ok
+ // 63 = '?'; 95 = '_' and need encoding to go in the headers
+ if ((!$bin && ($val == 32 || $val == 9 || $val == 10 || $val == 13))
+ || ($val >= 33 && $val <= 60) || ($val >= 62 && $val <= 126)
+ && $val != 63)
+ {
+ $ret .= $string{$i};
+ }
+ else
+ {
+ $ret .= sprintf("=%02X", $val);
+ }
+ }
+ return $ret;
+ }
+ /**
+ * Return a file as a quoted printable encoded string
+ * @param Swift_File The file to encode
+ * @param int Max line length
+ * @param string The line ending
+ * @return Swift_Cache_OutputStream
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function QPEncodeFile(Swift_File $file, $chunk=76, $le="\r\n")
+ {
+ Swift_ClassLoader::load("Swift_CacheFactory");
+ $cache = Swift_CacheFactory::getCache();
+ while (false !== $bytes = $file->readln())
+ {
+ $next = $this->rawQPEncode($bytes, true);
+ preg_match_all('/.{1,'.($chunk-6).'}([^=]{0,3})?/', $next, $next);
+ if (count($next[0])) $cache->write("qp", $this->fixLE(implode("=" . $le, $next[0]), $le));
+ }
+ return $cache->getOutputStream("qp");
+ }
+ /**
+ * Encode a string as 7bit ascii
+ * @param string Input data to encode
+ * @param int Max line length
+ * @param string The line ending
+ * @return string
+ */
+ public function encode7Bit($data, $chunk=76, $le="\r\n")
+ {
+ return $this->fixLE(wordwrap($data, $chunk-2, $le, 1), $le);
+ }
+ /**
+ * Return a 7bit string from a file
+ * @param Swift_File The file stream to read from
+ * @param int The max line length
+ * @param string The line ending
+ * @return Swift_Cache_OutputStream
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function encode7BitFile(Swift_File $file, $chunk=76, $le="\r\n")
+ {
+ Swift_ClassLoader::load("Swift_CacheFactory");
+ $cache = Swift_CacheFactory::getCache();
+ $ret = "";
+ while (false !== $bytes = $file->read(8192)) $ret .= $bytes;
+ $cache->write("7b", $this->fixLE(wordwrap($ret, $chunk-2, $le, 1), $le));
+ return $cache->getOutputStream("7b");
+ }
+ /**
+ * Return the 8bit encoded form of a string (unchanged there-abouts)
+ * @param string Input data to encode
+ * @param int Maximum line length
+ * @param string The line ending
+ * @return string
+ */
+ public function encode8Bit($data, $chunk=76, $le="\r\n")
+ {
+ return $this->fixLE(wordwrap($data, $chunk-2, $le, 1), $le);
+ }
+ /**
+ * Return a 8bit string from a file
+ * @param Swift_File The file stream to read from
+ * @param int Max line length (including CRLF)
+ * @param string The line ending
+ * @return Swift_Cache_OutputStream
+ * @throws Swift_FileException If the file cannot be read
+ */
+ public function encode8BitFile(Swift_File $file, $chunk=76, $le="\r\n")
+ {
+ Swift_ClassLoader::load("Swift_CacheFactory");
+ $cache = Swift_CacheFactory::getCache();
+ $ret = "";
+ while (false !== $bytes = $file->read(8192)) $ret .= $bytes;
+ $cache->write("8b", $this->fixLE(wordwrap($ret, $chunk-2, $le, 1), $le));
+ return $cache->getOutputStream("8b");
+ }
+ /**
+ * Keeps lines longer than 76 characters trimmed down to size
+ * This currently does not convert other string encodings into 7bit
+ * @param string The data to make safe for headers (defaults to RFC 2822 standards)
+ * @param int maximum length of lines returned
+ * @param int The maximum length of the first line
+ * @param string The Line ending
+ * @return string
+ */
+ public function header7BitEncode($data, $chunk=76, $init_chunk=0, $le="\r\n")
+ {
+ $data = $this->encode7BitPrintable($data);
+ $ret = "";
+ if ($init_chunk > 2)
+ {
+ $data_wrapped = wordwrap($data, $init_chunk, $le);
+ $lines = explode($le, $data_wrapped);
+ $first_line = array_shift($lines);
+ $ret .= $first_line . $le;
+ $data = preg_replace("~^[ \t]~D", "", substr($data, strlen($first_line)));
+ }
+ elseif ($init_chunk) $ret .= $le;
+ $ret .= wordwrap($data, $chunk-2, $le);
+ return trim($ret);
+ }
+ /**
+ * Strip out any characters which are not in the ASCII 7bit printable range
+ * @param string The string to clean
+ * @return string
+ */
+ public function encode7BitPrintable($data)
+ {
+ return preg_replace('/[^\x20-\x7E]/', '', $data);
+ }
+ /**
+ * Detect if a string contains multi-byte non-ascii chars that fall in the UTF-8 ranges
+ * @param string Data to detect UTF-8 sequences in
+ * @return boolean
+ */
+ public function isUTF8($data)
+ {
+ return preg_match('%(?:
+ [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
+ |\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
+ |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
+ |\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
+ |\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
+ |[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
+ |\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
+ )+%xs', $data);
+ }
+ /**
+ * This function checks for 7bit *printable* characters
+ * which excludes \r \n \t etc and so, is safe for use in mail headers
+ * Actual permitted chars [\ !"#\$%&'\(\)\*\+,-\.\/0123456789:;<=>\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\\\]\^_`abcdefghijklmnopqrstuvwxyz{\|}~]
+ * Ranges \x00-\x1F are printer control sequences
+ * \x7F is the ascii delete character
+ * @param string Data to check against
+ * @return boolean
+ */
+ public function is7BitPrintable($data)
+ {
+ return (!preg_match('/[^\x20-\x7E]/', $data));
+ }
+ /**
+ * Check that a string does not contain any evil characters for headers.
+ * @param string The string to check
+ * @return boolean
+ */
+ public function isHeaderSafe($data)
+ {
+ return ($this->is7BitPrintable($data) && strpos($data, ";") === false);
+ }
+ /**
+ * If the characters fall exclusively in the 7bit ascii range, return true
+ * @param string Input to check
+ * @return boolean
+ */
+ public function is7BitAscii($data)
+ {
+ return (!preg_match('/[^\x01-\x7F]/', $data));
+ }
+ /**
+ * Encode a string for RFC 2047 compatability (url-encode)
+ * @param string The input for encoding
+ * @param string The charset used
+ * @param string The language used
+ * @param int The maximum line length
+ * @param int The maximum length of the first line
+ * @param string The line ending
+ * @return string
+ */
+ public function rfc2047Encode($str, $charset="iso-8859-1", $language="en-us", $chunk=76, $le="\r\n")
+ {
+ $lang_spec = "";
+ if (!$this->is7BitPrintable($str))
+ {
+ $lang_spec = $charset . "'" . $language . "'";
+ $str = $lang_spec . str_replace("+", "%20", urlencode($str));
+ }
+ preg_match_all('~.{1,'.($chunk-6).'}([^%]{0,3})~', $str, $matches);
+ if (count($matches[0])) return implode($le, $matches[0]);
+ }
+ /**
+ * Fixes line endings to be whatever is specified by the user
+ * SMTP requires the CRLF be used, but using sendmail in -t mode uses LF
+ * This method also escapes dots on a start of line to avoid injection
+ * @param string The data to fix
+ * @return string
+ */
+ protected function fixLE($data, $le)
+ {
+ $data = str_replace(array("\r\n", "\r"), "\n", $data);
+ if ($le != "\n") $data = str_replace("\n", $le, $data);
+ return $data = str_replace($le . ".", $le . "..", $data);
+ }
+ protected function getHcf($value, $factor)
+ {
+ return ($value - ($value % $factor));
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Encoder.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Headers.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Headers.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Headers.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,573 @@
+<?php
+
+/**
+ * Swift Mailer MIME Library Headers component
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+
+/**
+ * Contains and constructs the headers for a MIME document
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message_Headers
+{
+ /**
+ * Headers which may contain email addresses, and therefore should take notice when encoding
+ * @var array headers
+ */
+ protected $emailContainingHeaders = array(
+ "To", "From", "Reply-To", "Cc", "Bcc", "Return-Path", "Sender");
+ /**
+ * The encoding format used for the body of the document
+ * @var string format
+ */
+ protected $encoding = "B";
+ /**
+ * The charset used in the headers
+ * @var string
+ */
+ protected $charset = false;
+ /**
+ * A collection of headers
+ * @var array headers
+ */
+ protected $headers = array();
+ /**
+ * A container of references to the headers
+ * @var array
+ */
+ protected $lowerHeaders = array();
+ /**
+ * Attributes appended to headers
+ * @var array
+ */
+ protected $attributes = array();
+ /**
+ * If QP or Base64 encoding should be forced
+ * @var boolean
+ */
+ protected $forceEncoding = false;
+ /**
+ * The language used in the headers (doesn't really matter much)
+ * @var string
+ */
+ protected $language = "en-us";
+ /**
+ * Cached, pre-built headers
+ * @var string
+ */
+ protected $cached = array();
+ /**
+ * The line ending used in the headers
+ * @var string
+ */
+ protected $LE = "\r\n";
+
+ /**
+ * Set the line ending character to use
+ * @param string The line ending sequence
+ * @return boolean
+ */
+ public function setLE($le)
+ {
+ if (in_array($le, array("\r", "\n", "\r\n")))
+ {
+ foreach (array_keys($this->cached) as $k) $this->cached[$k] = null;
+ $this->LE = $le;
+ return true;
+ }
+ else return false;
+ }
+ /**
+ * Get the line ending sequence
+ * @return string
+ */
+ public function getLE()
+ {
+ return $this->LE;
+ }
+ /**
+ * Reset the cache state in these headers
+ */
+ public function uncacheAll()
+ {
+ foreach (array_keys($this->cached) as $k)
+ {
+ $this->cached[$k] = null;
+ }
+ }
+ /**
+ * Add a header or change an existing header value
+ * @param string The header name, for example "From" or "Subject"
+ * @param string The value to be inserted into the header. This is safe from header injection.
+ */
+ public function set($name, $value)
+ {
+ $lname = strtolower($name);
+ if (!isset($this->lowerHeaders[$lname]))
+ {
+ $this->headers[$name] = null;
+ $this->lowerHeaders[$lname] =& $this->headers[$name];
+ }
+ $this->cached[$lname] = null;
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if (is_array($value))
+ {
+ foreach ($value as $v)
+ {
+ if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($v))
+ {
+ $this->setCharset("utf-8");
+ break;
+ }
+ }
+ }
+ elseif ($value !== null)
+ {
+ if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($value))
+ {
+ $this->setCharset("utf-8");
+ }
+ }
+ if (!is_array($value) && $value !== null) $this->lowerHeaders[$lname] = (string) $value;
+ else $this->lowerHeaders[$lname] = $value;
+ }
+ /**
+ * Get the value at a given header
+ * @param string The name of the header, for example "From" or "Subject"
+ * @return string
+ * @throws Swift_Message_MimeException If no such header exists
+ * @see hasHeader
+ */
+ public function get($name)
+ {
+ $lname = strtolower($name);
+ if ($this->has($name))
+ {
+ return $this->lowerHeaders[$lname];
+ }
+ }
+ /**
+ * Remove a header from the list
+ * @param string The name of the header
+ */
+ public function remove($name)
+ {
+ $lname = strtolower($name);
+ if ($this->has($name))
+ {
+ unset($this->headers[$name]);
+ unset($this->lowerHeaders[$lname]);
+ unset($this->cached[$lname]);
+ if (isset($this->attributes[$lname])) unset($this->attributes[$lname]);
+ }
+ }
+ /**
+ * Just fetch the array containing the headers
+ * @return array
+ */
+ public function getList()
+ {
+ return $this->headers;
+ }
+ /**
+ * Check if a header has been set or not
+ * @param string The name of the header, for example "From" or "Subject"
+ * @return boolean
+ */
+ public function has($name)
+ {
+ $lname = strtolower($name);
+ return (array_key_exists($lname, $this->lowerHeaders) && $this->lowerHeaders[$lname] !== null);
+ }
+ /**
+ * Set the language used in the headers to $lang (e.g. en-us, en-gb, sv etc)
+ * @param string The language to use
+ */
+ public function setLanguage($lang)
+ {
+ $this->language = (string) $lang;
+ }
+ /**
+ * Get the language used in the headers to $lang (e.g. en-us, en-gb, sv etc)
+ * @return string
+ */
+ public function getLanguage()
+ {
+ return $this->language;
+ }
+ /**
+ * Set the charset used in the headers
+ * @param string The charset name
+ */
+ public function setCharset($charset)
+ {
+ $this->charset = (string) $charset;
+ }
+ /**
+ * Get the current charset used
+ * @return string
+ */
+ public function getCharset()
+ {
+ return $this->charset;
+ }
+ /**
+ * Specify the encoding to use for the headers if characters outside the 7-bit-printable ascii range are found
+ * This encoding will never be used if only 7-bit-printable characters are found in the headers.
+ * Possible values are:
+ * - QP
+ * - Q
+ * - Quoted-Printable
+ * - B
+ * - Base64
+ * NOTE: Q, QP, Quoted-Printable are all the same; as are B and Base64
+ * @param string The encoding format to use
+ * @return boolean
+ */
+ public function setEncoding($encoding)
+ {
+ switch (strtolower($encoding))
+ {
+ case "qp": case "q": case "quoted-printable":
+ $this->encoding = "Q";
+ return true;
+ case "base64": case "b":
+ $this->encoding = "B";
+ return true;
+ default: return false;
+ }
+ }
+ /**
+ * Get the encoding format used in this document
+ * @return string
+ */
+ public function getEncoding()
+ {
+ return $this->encoding;
+ }
+ /**
+ * Turn on or off forced header encoding
+ * @param boolean On/Off
+ */
+ public function forceEncoding($force=true)
+ {
+ $this->forceEncoding = (boolean) $force;
+ }
+ /**
+ * Set an attribute in a major header
+ * For example $headers->setAttribute("Content-Type", "format", "flowed")
+ * @param string The main header these values exist in
+ * @param string The name for this value
+ * @param string The value to set
+ * @throws Swift_Message_MimeException If no such header exists
+ */
+ public function setAttribute($header, $name, $value)
+ {
+ $name = strtolower($name);
+ $lheader = strtolower($header);
+ $this->cached[$lheader] = null;
+ if (!$this->has($header))
+ {
+ throw new Swift_Message_MimeException(
+ "Cannot set attribute '" . $name . "' for header '" . $header . "' as the header does not exist. " .
+ "Consider using Swift_Message_Headers->has() to check.");
+ }
+ else
+ {
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($value)) $this->setCharset("utf-8");
+ if (!isset($this->attributes[$lheader])) $this->attributes[$lheader] = array();
+ if ($value !== null) $this->attributes[$lheader][$name] = (string) $value;
+ else $this->attributes[$lheader][$name] = $value;
+ }
+ }
+ /**
+ * Check if a header has a given attribute applied to it
+ * @param string The name of the main header
+ * @param string The name of the attribute
+ * @return boolean
+ */
+ public function hasAttribute($header, $name)
+ {
+ $name = strtolower($name);
+ $lheader = strtolower($header);
+ if (!$this->has($header))
+ {
+ return false;
+ }
+ else
+ {
+ return (isset($this->attributes[$lheader]) && isset($this->attributes[$lheader][$name]) && ($this->attributes[$lheader][$name] !== null));
+ }
+ }
+ /**
+ * Get the value for a given attribute on a given header
+ * @param string The name of the main header
+ * @param string The name of the attribute
+ * @return string
+ * @throws Swift_Message_MimeException If no header is set
+ */
+ public function getAttribute($header, $name)
+ {
+ if (!$this->has($header))
+ {
+ throw new Swift_Message_MimeException(
+ "Cannot locate attribute '" . $name . "' for header '" . $header . "' as the header does not exist. " .
+ "Consider using Swift_Message_Headers->has() to check.");
+ }
+
+ $name = strtolower($name);
+ $lheader = strtolower($header);
+
+ if ($this->hasAttribute($header, $name))
+ {
+ return $this->attributes[$lheader][$name];
+ }
+ }
+ /**
+ * Remove an attribute from a header
+ * @param string The name of the header to remove the attribute from
+ * @param string The name of the attribute to remove
+ */
+ public function removeAttribute($header, $name)
+ {
+ $name = strtolower($name);
+ $lheader = strtolower($header);
+ if ($this->has($header))
+ {
+ unset($this->attributes[$lheader][$name]);
+ }
+ }
+ /**
+ * Get a list of all the attributes in the given header.
+ * @param string The name of the header
+ * @return array
+ */
+ public function listAttributes($header)
+ {
+ $header = strtolower($header);
+ if (array_key_exists($header, $this->attributes))
+ {
+ return $this->attributes[$header];
+ }
+ else return array();
+ }
+ /**
+ * Get the header in it's compliant, encoded form
+ * @param string The name of the header
+ * @return string
+ * @throws Swift_Message_MimeException If the header doesn't exist
+ */
+ public function getEncoded($name)
+ {
+ if (!$this->getCharset()) $this->setCharset("iso-8859-1");
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ //I'll try as best I can to walk through this...
+
+ $lname = strtolower($name);
+
+ if ($this->cached[$lname] !== null) return $this->cached[$lname];
+
+ $value = $this->get($name);
+
+ $is_email = in_array($name, $this->emailContainingHeaders);
+
+ $encoded_value = (array) $value; //Turn strings into arrays (just to make the following logic simpler)
+
+ //Look at each value in this header
+ // There will only be 1 value if it was a string to begin with, and usually only address lists will be multiple
+ foreach ($encoded_value as $key => $row)
+ {
+ $spec = ""; //The bit which specifies the encoding of the header (if any)
+ $end = ""; //The end delimiter for an encoded header
+
+ //If the header is 7-bit printable it's at no risk of injection
+ if (Swift_Message_Encoder::instance()->isHeaderSafe($row) && !$this->forceEncoding)
+ {
+ //Keeps the total line length at less than 76 chars, taking into account the Header name length
+ $encoded_value[$key] = Swift_Message_Encoder::instance()->header7BitEncode(
+ $row, 72, ($key > 0 ? 0 : (75-(strlen($name)+5))), $this->LE);
+ }
+ elseif ($this->encoding == "Q") //QP encode required
+ {
+ $spec = "=?" . $this->getCharset() . "?Q?"; //e.g. =?iso-8859-1?Q?
+ $end = "?=";
+ //Calculate the length of, for example: "From: =?iso-8859-1?Q??="
+ $used_length = strlen($name) + 2 + strlen($spec) + 2;
+
+ //Encode to QP, excluding the specification for now but keeping the lines short enough to be compliant
+ $encoded_value[$key] = str_replace(" ", "_", Swift_Message_Encoder::instance()->QPEncode(
+ $row, (75-(strlen($spec)+6)), ($key > 0 ? 0 : (75-$used_length)), true, $this->LE));
+
+ }
+ elseif ($this->encoding == "B") //Need to Base64 encode
+ {
+ //See the comments in the elseif() above since the logic is the same (refactor?)
+ $spec = "=?" . $this->getCharset() . "?B?";
+ $end = "?=";
+ $used_length = strlen($name) + 2 + strlen($spec) + 2;
+ $encoded_value[$key] = Swift_Message_Encoder::instance()->base64Encode(
+ $row, (75-(strlen($spec)+5)), ($key > 0 ? 0 : (76-($used_length+3))), true, $this->LE);
+ }
+
+ if (false !== $p = strpos($encoded_value[$key], $this->LE))
+ {
+ $cb = 'str_replace("' . $this->LE . '", "", "<$1>");';
+ $encoded_value[$key] = preg_replace("/<([^>]+)>/e", $cb, $encoded_value[$key]);
+ }
+
+ //Turn our header into an array of lines ready for wrapping around the encoding specification
+ $lines = explode($this->LE, $encoded_value[$key]);
+
+ for ($i = 0, $len = count($lines); $i < $len; $i++)
+ {
+ //Don't allow commas in address fields without quotes unless they're encoded
+ if (empty($spec) && $is_email && (false !== $p = strpos($lines[$i], ",")))
+ {
+ $s = strpos($lines[$i], " <");
+ $e = strpos($lines[$i], ">");
+ if ($s < $e)
+ {
+ $addr = substr($lines[$i], $s);
+ $lines[$i] = "\"" . substr($lines[$i], 0, $s) . "\"" . $addr;
+ }
+ else
+ {
+ $lines[$i] = "\"" . $lines[$i] . "\"";
+ }
+ }
+
+ if ($this->encoding == "Q") $lines[$i] = rtrim($lines[$i], "=");
+
+ if ($lines[$i] == "" && $i > 0)
+ {
+ unset($lines[$i]); //Empty line, we'd rather not have these in the headers thank you!
+ continue;
+ }
+ if ($i > 0)
+ {
+ //Don't stick the specification part around the line if it's an address
+ if (substr($lines[$i], 0, 1) == '<' && substr($lines[$i], -1) == '>') $lines[$i] = " " . $lines[$i];
+ else $lines[$i] = " " . $spec . $lines[$i] . $end;
+ }
+ else
+ {
+ if (substr($lines[$i], 0, 1) != '<' || substr($lines[$i], -1) != '>') $lines[$i] = $spec . $lines[$i] . $end;
+ }
+ }
+ //Build back into a string, now includes the specification
+ $encoded_value[$key] = implode($this->LE, $lines);
+ $lines = null;
+ }
+
+ //If there are multiple values in this header, put them on separate lines, cleared by commas
+ $this->cached[$lname] = implode("," . $this->LE . " ", $encoded_value);
+
+ //Append attributes if there are any
+ if (!empty($this->attributes[$lname])) $this->cached[$lname] .= $this->buildAttributes($this->cached[$lname], $lname);
+
+ return $this->cached[$lname];
+ }
+ /**
+ * Build the list of attributes for appending to the given header
+ * This is RFC 2231 & 2047 compliant.
+ * A HUGE thanks to Joaquim Homrighausen for heaps of help, advice
+ * and testing to get this working rock solid.
+ * @param string The header built without attributes
+ * @param string The lowercase name of the header
+ * @return string
+ * @throws Swift_Message_MimeException If no such header exists or there are no attributes
+ */
+ protected function buildAttributes($header_line, $header_name)
+ {
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ $lines = explode($this->LE, $header_line);
+ $used_len = strlen($lines[count($lines)-1]);
+ $lines= null;
+ $ret = "";
+ foreach ($this->attributes[$header_name] as $attribute => $att_value)
+ {
+ if ($att_value === null) continue;
+ // 70 to account for LWSP, CRLF, quotes and a semi-colon
+ // + length of attribute
+ // + 4 for a 2 digit number and 2 asterisks
+ $avail_len = 70 - (strlen($attribute) + 4);
+ $encoded = Swift_Message_Encoder::instance()->rfc2047Encode($att_value, $this->charset, $this->language, $avail_len, $this->LE);
+ $lines = explode($this->LE, $encoded);
+ foreach ($lines as $i => $line)
+ {
+ //Add quotes if needed (RFC 2045)
+ if (preg_match("~[\\s\";,<>\\(\\)@:\\\\/\\[\\]\\?=]~", $line)) $lines[$i] = '"' . $line . '"';
+ }
+ $encoded = implode($this->LE, $lines);
+
+ //If we can fit this entire attribute onto the same line as the header then do it!
+ if ((strlen($encoded) + $used_len + strlen($attribute) + 4) < 74)
+ {
+ if (strpos($encoded, "'") !== false) $attribute .= "*";
+ $append = "; " . $attribute . "=" . $encoded;
+ $ret .= $append;
+ $used_len += strlen($append);
+ }
+ else //... otherwise list of underneath
+ {
+ $ret .= ";";
+ if (count($lines) > 1)
+ {
+ $loop = false;
+ $add_asterisk = false;
+ foreach ($lines as $i => $line)
+ {
+ $att_copy = $attribute; //Because it's multi-line it needs asterisks with decimal indices
+ $att_copy .= "*" . $i;
+ if ($add_asterisk || strpos($encoded, "'") !== false)
+ {
+ $att_copy .= "*"; //And if it's got a ' then it needs another asterisk
+ $add_asterisk = true;
+ }
+ $append = "";
+ if ($loop) $append .= ";";
+ $append .= $this->LE . " " . $att_copy . "=" . $line;
+ $ret .= $append;
+ $used_len = strlen($append)+1;
+ $loop = true;
+ }
+ }
+ else
+ {
+ if (strpos($encoded, "'") !== false) $attribute .= "*";
+ $append = $this->LE . " " . $attribute . "=" . $encoded;
+ $used_len = strlen($append)+1;
+ $ret .= $append;
+ }
+ }
+ $lines= null;
+ }
+ return $ret;
+ }
+ /**
+ * Compile the list of headers which have been set and return an ascii string
+ * The return value should always be 7-bit ascii and will have been cleaned for header injection
+ * If this looks complicated it's probably because it is!! Keeping everything compliant is not easy.
+ * This is RFC 2822 compliant
+ * @return string
+ */
+ public function build()
+ {
+ $ret = "";
+ foreach ($this->headers as $name => $value) //Look at each header
+ {
+ if ($value === null) continue;
+ $ret .= ltrim($name, ".") . ": " . $this->getEncoded($name) . $this->LE;
+ }
+ return trim($ret);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Headers.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Image.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Image.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Image.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Swift Mailer Image Component
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Message_EmbeddedFile");
+
+/**
+ * Embedded Image component for Swift Mailer
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message_Image extends Swift_Message_EmbeddedFile
+{
+ /**
+ * Constructor
+ * @param Swift_File The input source file
+ * @param string The filename to use, optional
+ * @param string The MIME type to use, optional
+ * @param string The Content-ID to use, optional
+ * @param string The encoding format to use, optional
+ */
+ public function __construct(Swift_File $data=null, $name=null, $type="application/octet-stream", $cid=null, $encoding="base64")
+ {
+ parent::__construct($data, $name, $type, $cid, $encoding);
+ }
+ /**
+ * Set data for the image
+ * This overrides setData() in Swift_Message_Attachment
+ * @param Swift_File The data to set, as a file
+ * @throws Swift_Message_MimeException If the image cannot be used, or the file is not
+ */
+ public function setData($data, $read_filename=true)
+ {
+ if (!($data instanceof Swift_File)) throw new Exception("Parameter 1 of " . __METHOD__ . " must be instance of Swift_File");
+ parent::setData($data, $read_filename);
+ $img_data = @getimagesize($data->getPath());
+ if (!$img_data)
+ {
+ throw new Swift_Message_MimeException(
+ "Cannot use file '" . $data->getPath() . "' as image since getimagesize() was unable to detect a file format. " .
+ "Try using Swift_Message_EmbeddedFile instead");
+ }
+ $type = image_type_to_mime_type($img_data[2]);
+ $this->setContentType($type);
+ if (!$this->getFileName()) $this->setFileName($data->getFileName());
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Image.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Mime.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Mime.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Mime.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,500 @@
+<?php
+
+/**
+ * Swift Mailer MIME Library central component
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_File");
+Swift_ClassLoader::load("Swift_Message_MimeException");
+
+/**
+ * Mime is the underbelly for Messages, Attachments, Parts, Embedded Images, Forwarded Mail, etc
+ * In fact, every single component of the composed email is simply a new Mime document nested inside another
+ * When you piece an email together in this way you see just how straight-forward it really is
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+abstract class Swift_Message_Mime
+{
+ /**
+ * Constant for plain-text emails
+ */
+ const PLAIN = "text/plain";
+ /**
+ * Constant for HTML emails
+ */
+ const HTML = "text/html";
+ /**
+ * Constant for miscellaneous mime type
+ */
+ const MISC = "application/octet-stream";
+ /**
+ * Constant for MIME sections which must appear in the multipart/alternative section.
+ */
+ const LEVEL_ALTERNATIVE = "alternative";
+ /**
+ * Constant for MIME sections which must appear in the multipart/related section.
+ */
+ const LEVEL_RELATED = "related";
+ /**
+ * Constant for MIME sections which must appear in the multipart/mixed section.
+ */
+ const LEVEL_MIXED = "mixed";
+ /**
+ * Constant for MIME sections which must appear in the multipart/mixed section.
+ */
+ const LEVEL_TOP = "top";
+ /**
+ * Constant for safe line length in almost all places
+ */
+ const SAFE_LENGTH = 1000; //RFC 2822
+ /**
+ * Constant for really safe line length
+ */
+ const VERY_SAFE_LENGTH = 76; //For command line mail clients such as pine
+ /**
+ * The header part of this MIME document
+ * @var Swift_Message_Headers
+ */
+ public $headers = null;
+ /**
+ * The body of the documented (unencoded)
+ * @var string data
+ */
+ protected $data = "";
+ /**
+ * Maximum line length
+ * @var int
+ */
+ protected $wrap = 1000; //RFC 2822
+ /**
+ * Nested mime parts
+ * @var array
+ */
+ protected $children = array();
+ /**
+ * The boundary used to separate mime parts
+ * @var string
+ */
+ protected $boundary = null;
+ /**
+ * The line ending characters needed
+ * @var string
+ */
+ protected $LE = "\r\n";
+ /**
+ * An instance of Swift_Cache
+ * @var Swift_Cache
+ */
+ protected $cache;
+ /**
+ * A list of used MIME boundaries after they're generated.
+ * @var array
+ */
+ protected static $usedBoundaries = array();
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ Swift_ClassLoader::load("Swift_Message_Headers");
+ $this->setHeaders(new Swift_Message_Headers());
+ Swift_ClassLoader::load("Swift_CacheFactory");
+ $this->cache = Swift_CacheFactory::getCache();
+ }
+ /**
+ * Compute a unique boundary
+ * @return string
+ */
+ public static function generateBoundary()
+ {
+ do
+ {
+ $boundary = uniqid(rand(), true);
+ } while (in_array($boundary, self::$usedBoundaries));
+ self::$usedBoundaries[] = $boundary;
+ return "_=_swift-" . $boundary . "_=_";
+ }
+ /**
+ * Replace the current headers with new ones
+ * DO NOT DO THIS UNLESS YOU KNOW WHAT YOU'RE DOING!
+ * @param Swift_Message_Headers The headers to use
+ */
+ public function setHeaders($headers)
+ {
+ $this->headers = $headers;
+ }
+ /**
+ * Set the line ending character to use
+ * @param string The line ending sequence
+ * @return boolean
+ */
+ public function setLE($le)
+ {
+ if (in_array($le, array("\r", "\n", "\r\n")))
+ {
+ $this->cache->clear("body");
+ $this->LE = $le;
+ //This change should be recursive
+ $this->headers->setLE($le);
+ foreach ($this->children as $id => $child)
+ {
+ $this->children[$id]->setLE($le);
+ }
+
+ return true;
+ }
+ else return false;
+ }
+ /**
+ * Get the line ending sequence
+ * @return string
+ */
+ public function getLE()
+ {
+ return $this->LE;
+ }
+ /**
+ * Reset the entire cache state from this branch of the tree and traversing down through the children
+ */
+ public function uncacheAll()
+ {
+ $this->cache->clear("body");
+ $this->cache->clear("append");
+ $this->cache->clear("headers");
+ $this->cache->clear("dbl_le");
+ $this->headers->uncacheAll();
+ foreach ($this->children as $id => $child)
+ {
+ $this->children[$id]->uncacheAll();
+ }
+ }
+ /**
+ * Set the content type of this MIME document
+ * @param string The content type to use in the same format as MIME 1.0 expects
+ */
+ public function setContentType($type)
+ {
+ $this->headers->set("Content-Type", $type);
+ }
+ /**
+ * Get the content type which has been set
+ * The MIME 1.0 Content-Type is provided as a string
+ * @return string
+ */
+ public function getContentType()
+ {
+ try {
+ return $this->headers->get("Content-Type");
+ } catch (Swift_Message_MimeException $e) {
+ return false;
+ }
+ }
+ /**
+ * Set the encoding format to be used on the body of the document
+ * @param string The encoding type used
+ * @param boolean If this encoding format should be used recursively. Note, this only takes effect if no encoding is set in the children.
+ * @param boolean If the encoding should only be applied when the string is not ascii.
+ */
+ public function setEncoding($encoding, $recursive=false, $non_ascii=false)
+ {
+ $this->cache->clear("body");
+ switch (strtolower($encoding))
+ {
+ case "q": case "qp": case "quoted-printable":
+ $encoding = "quoted-printable";
+ break;
+ case "b": case "base64":
+ $encoding = "base64";
+ break;
+ case "7bit": case "8bit": case "binary":
+ $encoding = strtolower($encoding);
+ break;
+ }
+
+ $data = $this->getData();
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if ($non_ascii && is_string($data) && strlen($data) > 0 && !Swift_Message_Encoder::instance()->is7BitAscii($data))
+ {
+ $this->headers->set("Content-Transfer-Encoding", $encoding);
+ }
+ elseif (!$non_ascii || !is_string($data))
+ {
+ $this->headers->set("Content-Transfer-Encoding", $encoding);
+ }
+
+ if ($recursive)
+ {
+ foreach ($this->children as $id => $child)
+ {
+ if (!$child->getEncoding()) $this->children[$id]->setEncoding($encoding, $recursive, $non_ascii);
+ }
+ }
+ }
+ /**
+ * Get the encoding format used in this document
+ * @return string
+ */
+ public function getEncoding()
+ {
+ try {
+ return $this->headers->get("Content-Transfer-Encoding");
+ } catch (Swift_Message_MimeException $e) {
+ return false;
+ }
+ }
+ /**
+ * Specify the string which makes up the body of this message
+ * HINT: You can always nest another MIME document here if you call it's build() method.
+ * $data can be an object of Swift_File or a string
+ * @param mixed The body of the document
+ */
+ public function setData($data)
+ {
+ $this->cache->clear("body");
+ if ($data instanceof Swift_File) $this->data = $data;
+ else $this->data = (string) $data;
+ }
+ /**
+ * Return the string which makes up the body of this MIME document
+ * @return string,Swift_File
+ */
+ public function getData()
+ {
+ return $this->data;
+ }
+ /**
+ * Get the data in the format suitable for sending
+ * @return Swift_Cache_OutputStream
+ * @throws Swift_FileException If the file stream given cannot be read
+ * @throws Swift_Message_MimeException If some required headers have been forcefully removed
+ */
+ public function buildData()
+ {
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ Swift_ClassLoader::load("Swift_Cache_JointOutputStream");
+ if (!empty($this->children)) //If we've got some mime parts we need to stick them onto the end of the message
+ {
+ if ($this->boundary === null) $this->boundary = self::generateBoundary();
+ $this->headers->setAttribute("Content-Type", "boundary", $this->boundary);
+
+ $this->cache->clear("append");
+ foreach ($this->children as $part)
+ {
+ $this->cache->write("append", $this->LE . "--" . $this->boundary . $this->LE);
+ $part_stream = $part->build();
+ while (false !== $bytes = $part_stream->read()) $this->cache->write("append", $bytes);
+ }
+ $this->cache->write("append", $this->LE . "--" . $this->boundary . "--" . $this->LE);
+ }
+
+ $joint_os = new Swift_Cache_JointOutputStream();
+
+ //Try using a cached version to save some cycles (at the expense of memory)
+ //if ($this->cache !== null) return $this->cache . $append;
+ if ($this->cache->has("body"))
+ {
+ $joint_os->addStream($this->cache->getOutputStream("body"));
+ $joint_os->addStream($this->cache->getOutputStream("append"));
+ return $joint_os;
+ }
+
+ $is_file = ($this->getData() instanceof Swift_File);
+ switch ($this->getEncoding())
+ {
+ case "quoted-printable":
+ if ($is_file)
+ {
+ $qp_os = Swift_Message_Encoder::instance()->QPEncodeFile($this->getData(), 76, $this->LE);
+ while (false !== $bytes = $qp_os->read())
+ $this->cache->write("body", $bytes);
+ }
+ else
+ {
+ $this->cache->write("body", Swift_Message_Encoder::instance()->QPEncode($this->getData(), 76, 0, false, $this->LE));
+ }
+ break;
+ case "base64":
+ if ($is_file)
+ {
+ $b64_os = Swift_Message_Encoder::instance()->base64EncodeFile($this->getData(), 76, $this->LE);
+ while (false !== $bytes = $b64_os->read())
+ $this->cache->write("body", $bytes);
+ }
+ else
+ {
+ $this->cache->write("body", Swift_Message_Encoder::instance()->base64Encode($this->getData(), 76, 0, false, $this->LE));
+ }
+ break;
+ case "binary":
+ if ($is_file)
+ {
+ $data = $this->getData();
+ while (false !== $bytes = $data->read(8192))
+ $this->cache->write("body", $bytes);
+ }
+ else
+ {
+ $this->cache->write("body", $this->getData());
+ }
+ break;
+ case "7bit":
+ if ($is_file)
+ {
+ $os = Swift_Message_Encoder::instance()->encode7BitFile($this->getData(), $this->wrap, $this->LE);
+ while (false !== $bytes = $os->read())
+ $this->cache->write("body", $bytes);
+ }
+ else
+ {
+ $this->cache->write("body", Swift_Message_Encoder::instance()->encode7Bit($this->getData(), $this->wrap, $this->LE));
+ }
+ break;
+ case "8bit": default:
+ if ($is_file)
+ {
+ $os = Swift_Message_Encoder::instance()->encode8BitFile($this->getData(), $this->wrap, $this->LE);
+ while (false !== $bytes = $os->read())
+ $this->cache->write("body", $bytes);
+ }
+ else
+ {
+ $this->cache->write("body", Swift_Message_Encoder::instance()->encode8Bit($this->getData(), $this->wrap, $this->LE));
+ }
+ break;
+ }
+ $joint_os->addStream($this->cache->getOutputStream("body"));
+ $joint_os->addStream($this->cache->getOutputStream("append"));
+ return $joint_os;
+ }
+ /**
+ * Set the size at which lines wrap around (includes the CRLF)
+ * @param int The length of a line
+ */
+ public function setLineWrap($len)
+ {
+ $this->cache->clear("body");
+ $this->wrap = (int) $len;
+ }
+ /**
+ * Nest a child mime part in this document
+ * @param Swift_Message_Mime
+ * @param string The identifier to use, optional
+ * @param int Add the part before (-1) or after (+1) the other parts
+ * @return string The identifier for this part
+ */
+ public function addChild(Swift_Message_Mime $mime, $id=null, $after=1)
+ {
+ if (empty($id))
+ {
+ do
+ {
+ $id = uniqid();
+ } while (array_key_exists($id, $this->children));
+ }
+ $id = (string) $id;
+ if ($after == -1) $this->children = array_merge(array($id => $mime), $this->children);
+ else $this->children[$id] = $mime;
+
+ return $id;
+ }
+ /**
+ * Check if a child exists identified by $id
+ * @param string Identifier to look for
+ * @return boolean
+ */
+ public function hasChild($id)
+ {
+ return array_key_exists($id, $this->children);
+ }
+ /**
+ * Get a child document, identified by $id
+ * @param string The identifier for this child
+ * @return Swift_Message_Mime The child document
+ * @throws Swift_Message_MimeException If no such child exists
+ */
+ public function getChild($id)
+ {
+ if ($this->hasChild($id))
+ {
+ return $this->children[$id];
+ }
+ else
+ {
+ throw new Swift_Message_MimeException(
+ "Cannot retrieve child part identified by '" . $id . "' as it does not exist. Consider using hasChild() to check.");
+ }
+ }
+ /**
+ * Remove a part from the document
+ * @param string The identifier of the child
+ * @throws Swift_Message_MimeException If no such part exists
+ */
+ public function removeChild($id)
+ {
+ $id = (string) $id;
+ if (!$this->hasChild($id))
+ {
+ throw new Swift_Message_MimeException(
+ "Cannot remove child part identified by '" . $id . "' as it does not exist. Consider using hasChild() to check.");
+ }
+ else
+ {
+ $this->children[$id] = null;
+ unset($this->children[$id]);
+ }
+ }
+ /**
+ * List the IDs of all children in this document
+ * @return array
+ */
+ public function listChildren()
+ {
+ return array_keys($this->children);
+ }
+ /**
+ * Get the total number of children present in this document
+ * @return int
+ */
+ public function numChildren()
+ {
+ return count($this->children);
+ }
+ /**
+ * Get the level at which this mime part would appear in a document
+ * One of "mixed", "alternative" or "related"
+ * @return string
+ */
+ abstract public function getLevel();
+ /**
+ * Compile the entire MIME document into a string
+ * The returned string may be used in other documents if needed.
+ * @return Swift_Cache_OutputStream
+ */
+ public function build()
+ {
+ $this->preBuild();
+ $data = $this->buildData();
+ $joint_os = new Swift_Cache_JointOutputStream();
+ $this->cache->clear("headers");
+ $this->cache->write("headers", $this->headers->build());
+ $joint_os->addStream($this->cache->getOutputStream("headers"));
+ $this->cache->clear("dbl_le");
+ $this->cache->write("dbl_le", str_repeat($this->LE, 2));
+ $joint_os->addStream($this->cache->getOutputStream("dbl_le"));
+ $joint_os->addStream($data);
+ return $joint_os;
+ //return $this->headers->build() . str_repeat($this->LE, 2) . $data;
+ }
+ /**
+ * Execute any logic needed prior to building
+ */
+ abstract public function preBuild();
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Mime.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/MimeException.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/MimeException.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/MimeException.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * Swift MIME Exception
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Exception");
+
+/**
+ * Swift MIME Exception
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message_MimeException extends Swift_Exception
+{
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/MimeException.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Part.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Part.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Part.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,134 @@
+<?php
+
+/**
+ * Swift Mailer Message MIME Part
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Message_Mime");
+
+/**
+ * MIME Part body component for Swift Mailer
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message_Part extends Swift_Message_Mime
+{
+ /**
+ * Constructor
+ * @param mixed The data to use in the body
+ * @param string Mime type
+ * @param string The encoding format used
+ * @param string The charset used
+ */
+ public function __construct($data=null, $type="text/plain", $encoding=null, $charset=null)
+ {
+ parent::__construct();
+
+ $this->setContentType($type);
+ $this->setEncoding($encoding);
+ $this->setCharset($charset);
+ $this->setFlowed(false);
+
+ if ($data !== null)
+ {
+ $this->setData($data);
+ if ($charset === null)
+ {
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data)) $this->setCharset("utf-8");
+ else $this->setCharset("iso-8859-1"); //The likely encoding
+ }
+ }
+ }
+ /**
+ * Get the level in the MIME hierarchy at which this section should appear.
+ * @return string
+ */
+ public function getLevel()
+ {
+ return Swift_Message_Mime::LEVEL_ALTERNATIVE;
+ }
+ /**
+ * Alias for setData()
+ * @param mixed Body
+ */
+ public function setBody($body)
+ {
+ $this->setData($body);
+ }
+ /**
+ * Alias for getData()
+ * @return mixed The document body
+ */
+ public function getBody()
+ {
+ return $this->getData();
+ }
+ /**
+ * Set the charset of the document
+ * @param string The charset used
+ */
+ public function setCharset($charset)
+ {
+ $this->headers->setAttribute("Content-Type", "charset", $charset);
+ if (($this->getEncoding() == "7bit") && (strtolower($charset) == "utf-8" || strtolower($charset) == "utf8")) $this->setEncoding("8bit");
+ }
+ /**
+ * Get the charset used in the document
+ * Returns null if none is set
+ * @return string
+ */
+ public function getCharset()
+ {
+ if ($this->headers->hasAttribute("Content-Type", "charset"))
+ {
+ return $this->headers->getAttribute("Content-Type", "charset");
+ }
+ else
+ {
+ return null;
+ }
+ }
+ /**
+ * Set the "format" attribute to flowed
+ * @param boolean On or Off
+ */
+ public function setFlowed($flowed=true)
+ {
+ $value = null;
+ if ($flowed) $value = "flowed";
+ $this->headers->setAttribute("Content-Type", "format", $value);
+ }
+ /**
+ * Pre-compilation logic
+ */
+ public function preBuild()
+ {
+ if (!($enc = $this->getEncoding())) $this->setEncoding("8bit");
+ $data = $this->getData();
+ if ($this->getCharset() === null && !$this->numChildren())
+ {
+ if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data))
+ {
+ $this->setCharset("utf-8");
+ }
+ elseif (is_string($data) && Swift_Message_Encoder::instance()->is7BitAscii($data))
+ {
+ $this->setCharset("us-ascii");
+ if (!$enc) $this->setEncoding("7bit");
+ }
+ else $this->setCharset("iso-8859-1");
+ }
+ elseif ($this->numChildren())
+ {
+ $this->setCharset(null);
+ $this->setEncoding("7bit");
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message/Part.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,797 @@
+<?php
+
+/**
+ * Swift Mailer Message Component
+ * Composes MIME 1.0 messages meeting various RFC standards
+ * Deals with attachments, embedded images, multipart bodies, forwarded messages...
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Message
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_Address");
+Swift_ClassLoader::load("Swift_Message_Mime");
+Swift_ClassLoader::load("Swift_Message_Image");
+Swift_ClassLoader::load("Swift_Message_Part");
+
+
+/**
+ * Swift Message class
+ * @package Swift_Message
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Message extends Swift_Message_Mime
+{
+ /**
+ * Constant from a high priority message (pretty meaningless)
+ */
+ const PRIORITY_HIGH = 1;
+ /**
+ * Constant for a low priority message
+ */
+ const PRIORITY_LOW = 5;
+ /**
+ * Constant for a normal priority message
+ */
+ const PRIORITY_NORMAL = 3;
+ /**
+ * The MIME warning for client not supporting multipart content
+ * @var string
+ */
+ protected $mimeWarning = null;
+ /**
+ * The version of the library (Swift) if known.
+ * @var string
+ */
+ protected $libVersion = "";
+ /**
+ * A container for references to other objects.
+ * This is used in some very complex logic when sub-parts get shifted around.
+ * @var array
+ */
+ protected $references = array(
+ "parent" => array("alternative" => null, "mixed" => null, "related" => null),
+ "alternative" => array(),
+ "mixed" => array(),
+ "related" => array()
+ );
+
+ /**
+ * Ctor.
+ * @param string Message subject
+ * @param string Body
+ * @param string Content-type
+ * @param string Encoding
+ * @param string Charset
+ */
+ public function __construct($subject="", $body=null, $type="text/plain", $encoding=null, $charset=null)
+ {
+ parent::__construct();
+ if (function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get"))
+ {
+ date_default_timezone_set(@date_default_timezone_get());
+ }
+ $this->setReturnPath(null);
+ $this->setTo("");
+ $this->setFrom("");
+ $this->setCc(null);
+ $this->setBcc(null);
+ $this->setReplyTo(null);
+ $this->setSubject($subject);
+ $this->setDate(time());
+ if (defined("Swift::VERSION"))
+ {
+ $this->libVersion = Swift::VERSION;
+ $this->headers->set("X-LibVersion", $this->libVersion);
+ }
+ $this->headers->set("MIME-Version", "1.0");
+ $this->setContentType($type);
+ $this->setCharset($charset);
+ $this->setFlowed(true);
+ $this->setEncoding($encoding);
+
+ foreach (array_keys($this->references["parent"]) as $key)
+ {
+ $this->setReference("parent", $key, $this);
+ }
+
+ $this->setMimeWarning(
+ "This is a message in multipart MIME format. Your mail client should not be displaying this. " .
+ "Consider upgrading your mail client to view this message correctly."
+ );
+
+ if ($body !== null)
+ {
+ $this->setData($body);
+ if ($charset === null)
+ {
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if (Swift_Message_Encoder::instance()->isUTF8($body)) $this->setCharset("utf-8");
+ else $this->setCharset("iso-8859-1");
+ }
+ }
+ }
+ /**
+ * Sets a reference so when nodes are nested, operations can be redirected.
+ * This really should be refactored to use just one array rather than dynamic variables.
+ * @param string Key 1
+ * @param string Key 2
+ * @param Object Reference
+ */
+ protected function setReference($where, $key, $ref)
+ {
+ if ($ref === $this) $this->references[$where][$key] = false;
+ else $this->references[$where][$key] = $ref;
+ }
+ /**
+ * Get a reference to an object (for complex reasons).
+ * @param string Key 1
+ * @param string Key 2
+ * @return Object
+ */
+ protected function getReference($where, $key)
+ {
+ if (!$this->references[$where][$key]) return $this;
+ else return $this->references[$where][$key];
+ }
+ /**
+ * Get the level in the MIME hierarchy at which this section should appear.
+ * @return string
+ */
+ public function getLevel()
+ {
+ return Swift_Message_Mime::LEVEL_TOP;
+ }
+ /**
+ * Set the message id literally.
+ * Unless you know what you are doing you should be using generateId() rather than this method,
+ * otherwise you may break compliancy with RFC 2822.
+ * @param string The message ID string.
+ */
+ public function setId($id)
+ {
+ $this->headers->set("Message-ID", $id);
+ }
+ /**
+ * Create a RFC 2822 compliant message id, optionally based upon $idstring.
+ * The message ID includes information about the current time, the server and some random characters.
+ * @param string An optional string the base the ID on
+ * @return string The generated message ID, including the <> quotes.
+ * @author Cristian Rodriguez <judas.iscariote(a)flyspray.org>
+ */
+ public function generateId($idstring=null)
+ {
+ $midparams = array(
+ "utctime" => gmstrftime("%Y%m%d%H%M%S"),
+ "pid" => getmypid(),
+ "randint" => mt_rand(),
+ "customstr" => (preg_match("/^(?<!\\.)[a-z0-9\\.]+(?!\\.)\$/iD", $idstring) ? $idstring : "swift") ,
+ "hostname" => (isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : php_uname("n")),
+ );
+ $this->setId(vsprintf("<%s.%d.%d.%s@%s>", $midparams));
+ return $this->getId();
+ }
+ /**
+ * Get the generated message ID for this message, including the <> quotes.
+ * If generated automatically, or using generateId() this method returns a RFC2822 compliant Message-ID.
+ * @return string
+ * @author Cristian Rodriguez <judas.iscariote(a)flyspray.org>
+ */
+ public function getId()
+ {
+ return $this->headers->has("Message-ID") ? $this->headers->get("Message-ID") : null;
+ }
+ /**
+ * Set the address in the Return-Path: header
+ * @param string The bounce-detect address
+ */
+ public function setReturnPath($address)
+ {
+ if ($address instanceof Swift_Address) $address = $address->build(true);
+ $this->headers->set("Return-Path", $address);
+ }
+ /**
+ * Return the address used in the Return-Path: header
+ * @return string
+ * @param boolean Return the address for SMTP command
+ */
+ public function getReturnPath($smtp=false)
+ {
+ if ($this->headers->has("Return-Path"))
+ {
+ if (!$smtp) return $this->headers->get("Return-Path");
+ else
+ {
+ $path = $this->headers->get("Return-Path");
+ if (strpos($path, ">") > strpos($path, "<")) return substr($path, ($start = strpos($path, "<")), ($start + strrpos($path, ">") + 1));
+ else return "<" . $path . ">";
+ }
+ }
+ }
+ /**
+ * Set the address in the From: header
+ * @param string The address to set as From
+ */
+ public function setFrom($from)
+ {
+ if ($from instanceof Swift_Address) $from = $from->build();
+ $this->headers->set("From", $from);
+ }
+ /**
+ * Get the address used in the From: header
+ * @return string
+ */
+ public function getFrom()
+ {
+ if ($this->headers->has("From")) return $this->headers->get("From");
+ }
+ /**
+ * Set the list of recipients in the To: header
+ * @param mixed An array or a string
+ */
+ public function setTo($to)
+ {
+ if ($to)
+ {
+ if (!is_array($to)) $to = array($to);
+ foreach ($to as $key => $value)
+ {
+ if ($value instanceof Swift_Address) $to[$key] = $value->build();
+ }
+ }
+ $this->headers->set("To", $to);
+ }
+ /**
+ * Return the list of recipients in the To: header
+ * @return array
+ */
+ public function getTo()
+ {
+ if ($this->headers->has("To"))
+ {
+ $to = $this->headers->get("To");
+ if ($to == "") return array();
+ else return (array) $to;
+ }
+ }
+ /**
+ * Set the list of recipients in the Reply-To: header
+ * @param mixed An array or a string
+ */
+ public function setReplyTo($replyto)
+ {
+ if ($replyto)
+ {
+ if (!is_array($replyto)) $replyto = array($replyto);
+ foreach ($replyto as $key => $value)
+ {
+ if ($value instanceof Swift_Address) $replyto[$key] = $value->build();
+ }
+ }
+ $this->headers->set("Reply-To", $replyto);
+ }
+ /**
+ * Return the list of recipients in the Reply-To: header
+ * @return array
+ */
+ public function getReplyTo()
+ {
+ if ($this->headers->has("Reply-To"))
+ {
+ $reply_to = $this->headers->get("Reply-To");
+ if ($reply_to == "") return array();
+ else return (array) $reply_to;
+ }
+ }
+ /**
+ * Set the list of recipients in the Cc: header
+ * @param mixed An array or a string
+ */
+ public function setCc($cc)
+ {
+ if ($cc)
+ {
+ if (!is_array($cc)) $cc = array($cc);
+ foreach ($cc as $key => $value)
+ {
+ if ($value instanceof Swift_Address) $cc[$key] = $value->build();
+ }
+ }
+ $this->headers->set("Cc", $cc);
+ }
+ /**
+ * Return the list of recipients in the Cc: header
+ * @return array
+ */
+ public function getCc()
+ {
+ if ($this->headers->has("Cc"))
+ {
+ $cc = $this->headers->get("Cc");
+ if ($cc == "") return array();
+ else return (array) $cc;
+ }
+ }
+ /**
+ * Set the list of recipients in the Bcc: header
+ * @param mixed An array or a string
+ */
+ public function setBcc($bcc)
+ {
+ if ($bcc)
+ {
+ if (!is_array($bcc)) $bcc = array($bcc);
+ foreach ($bcc as $key => $value)
+ {
+ if ($value instanceof Swift_Address) $bcc[$key] = $value->build();
+ }
+ }
+ $this->headers->set("Bcc", $bcc);
+ }
+ /**
+ * Return the list of recipients in the Bcc: header
+ * @return array
+ */
+ public function getBcc()
+ {
+ if ($this->headers->has("Bcc"))
+ {
+ $bcc = $this->headers->get("Bcc");
+ if ($bcc == "") return array();
+ else return (array) $bcc;
+ }
+ }
+ /**
+ * Set the subject in the headers
+ * @param string The subject of the email
+ */
+ public function setSubject($subject)
+ {
+ $this->headers->set("Subject", $subject);
+ }
+ /**
+ * Get the current subject used in the headers
+ * @return string
+ */
+ public function getSubject()
+ {
+ return $this->headers->get("Subject");
+ }
+ /**
+ * Set the date in the headers in RFC 2822 format
+ * @param int The time as a UNIX timestamp
+ */
+ public function setDate($date)
+ {
+ $this->headers->set("Date", date("r", $date));
+ }
+ /**
+ * Get the date as it looks in the headers
+ * @return string
+ */
+ public function getDate()
+ {
+ return strtotime($this->headers->get("Date"));
+ }
+ /**
+ * Set the charset of the document
+ * @param string The charset used
+ */
+ public function setCharset($charset)
+ {
+ $this->headers->setAttribute("Content-Type", "charset", $charset);
+ if (($this->getEncoding() == "7bit") && (strtolower($charset) == "utf-8" || strtolower($charset) == "utf8")) $this->setEncoding("8bit");
+ }
+ /**
+ * Get the charset used in the document
+ * Returns null if none is set
+ * @return string
+ */
+ public function getCharset()
+ {
+ if ($this->headers->hasAttribute("Content-Type", "charset"))
+ {
+ return $this->headers->getAttribute("Content-Type", "charset");
+ }
+ else
+ {
+ return null;
+ }
+ }
+ /**
+ * Set the "format" attribute to flowed
+ * @param boolean On or Off
+ */
+ public function setFlowed($flowed=true)
+ {
+ $value = null;
+ if ($flowed) $value = "flowed";
+ $this->headers->setAttribute("Content-Type", "format", $value);
+ }
+ /**
+ * Check if the message format is set as flowed
+ * @return boolean
+ */
+ public function isFlowed()
+ {
+ if ($this->headers->hasAttribute("Content-Type", "format")
+ && $this->headers->getAttribute("Content-Type", "format") == "flowed")
+ {
+ return true;
+ }
+ else return false;
+ }
+ /**
+ * Set the message prioirty in the mail client (don't rely on this)
+ * @param int The priority as a value between 1 (high) and 5 (low)
+ */
+ public function setPriority($priority)
+ {
+ $priority = (int) $priority;
+ if ($priority > self::PRIORITY_LOW) $priority = self::PRIORITY_LOW;
+ if ($priority < self::PRIORITY_HIGH) $priority = self::PRIORITY_HIGH;
+ $label = array(1 => "High", 2 => "High", 3 => "Normal", 4 => "Low", 5 => "Low");
+ $this->headers->set("X-Priority", $priority);
+ $this->headers->set("X-MSMail-Priority", $label[$priority]);
+ $this->headers->set("X-MimeOLE", "Produced by SwiftMailer " . $this->libVersion);
+ }
+ /**
+ * Request that the client send back a read-receipt (don't rely on this!)
+ * @param string Request address
+ */
+ public function requestReadReceipt($request)
+ {
+ if ($request instanceof Swift_Address) $request = $request->build();
+ if (!$request)
+ {
+ $this->headers->set("Disposition-Notification-To", null);
+ $this->headers->set("X-Confirm-Reading-To", null);
+ $this->headers->set("Return-Receipt-To", null);
+ }
+ else
+ {
+ $this->headers->set("Disposition-Notification-To", $request);
+ $this->headers->set("X-Confirm-Reading-To", $request);
+ $this->headers->set("Return-Receipt-To", $request);
+ }
+ }
+ /**
+ * Check if a read receipt has been requested for this message
+ * @return boolean
+ */
+ public function wantsReadReceipt()
+ {
+ return $this->headers->has("Disposition-Notification-To");
+ }
+ /**
+ * Get the current message priority
+ * Returns NULL if none set
+ * @return int
+ */
+ public function getPriority()
+ {
+ if ($this->headers->has("X-Priority")) return $this->headers->get("X-Priority");
+ else return null;
+ }
+ /**
+ * Alias for setData()
+ * @param mixed Body
+ */
+ public function setBody($body)
+ {
+ $this->setData($body);
+ }
+ /**
+ * Alias for getData()
+ * @return mixed The document body
+ */
+ public function getBody()
+ {
+ return $this->getData();
+ }
+ /**
+ * Set the MIME warning message which is displayed to old clients
+ * @var string The full warning message (in 7bit ascii)
+ */
+ public function setMimeWarning($text)
+ {
+ $this->mimeWarning = (string) $text;
+ }
+ /**
+ * Get the MIME warning which is displayed to old clients
+ * @return string
+ */
+ public function getMimeWarning()
+ {
+ return $this->mimeWarning;
+ }
+ /**
+ * Attach a mime part or an attachment of some sort
+ * Any descendant of Swift_Message_Mime can be added safely (including other Swift_Message objects for mail forwarding!!)
+ * @param Swift_Message_Mime The document to attach
+ * @param string An identifier to use (one is returned otherwise)
+ * @return string The identifier for the part
+ */
+ public function attach(Swift_Message_Mime $child, $id=null)
+ {
+ try {
+ switch ($child->getLevel())
+ {
+ case Swift_Message_Mime::LEVEL_ALTERNATIVE:
+ $sign = (strtolower($child->getContentType()) == "text/plain") ? -1 : 1;
+ $id = $this->getReference("parent", "alternative")->addChild($child, $id, $sign);
+ $this->setReference("alternative", $id, $child);
+ break;
+ case Swift_Message_Mime::LEVEL_RELATED:
+ $id = "cid:" . $child->getContentId();
+ $id = $this->getReference("parent", "related")->addChild($child, $id, 1);
+ $this->setReference("related", $id, $child);
+ break;
+ case Swift_Message_Mime::LEVEL_MIXED: default:
+ $id = $this->getReference("parent", "mixed")->addChild($child, $id, 1);
+ $this->setReference("mixed", $id, $child);
+ break;
+ }
+ $this->postAttachFixStructure();
+ $this->fixContentType();
+ return $id;
+ } catch (Swift_Message_MimeException $e) {
+ throw new Swift_Message_MimeException("Something went wrong whilst trying to move some MIME parts during an attach(). " .
+ "The MIME component threw an exception:<br />" . $e->getMessage());
+ }
+ }
+ /**
+ * Remove a nested MIME part
+ * @param string The ID of the attached part
+ * @throws Swift_Message_MimeException If no such part exists
+ */
+ public function detach($id)
+ {
+ try {
+ switch (true)
+ {
+ case array_key_exists($id, $this->references["alternative"]):
+ $this->getReference("parent", "alternative")->removeChild($id);
+ unset($this->references["alternative"][$id]);
+ break;
+ case array_key_exists($id, $this->references["related"]):
+ $this->getReference("parent", "related")->removeChild($id);
+ unset($this->references["related"][$id]);
+ break;
+ case array_key_exists($id, $this->references["mixed"]):
+ $this->getReference("parent", "mixed")->removeChild($id);
+ unset($this->references["mixed"][$id]);
+ break;
+ default:
+ throw new Swift_Message_MimeException("Unable to detach part identified by ID '" . $id . "' since it's not registered.");
+ break;
+ }
+ $this->postDetachFixStructure();
+ $this->fixContentType();
+ } catch (Swift_Message_MimeException $e) {
+ throw new Swift_Message_MimeException("Something went wrong whilst trying to move some MIME parts during a detach(). " .
+ "The MIME component threw an exception:<br />" . $e->getMessage());
+ }
+ }
+ /**
+ * Sets the correct content type header by looking at what types of data we have set
+ */
+ protected function fixContentType()
+ {
+ if (!empty($this->references["mixed"])) $this->setContentType("multipart/mixed");
+ elseif (!empty($this->references["related"])) $this->setContentType("multipart/related");
+ elseif (!empty($this->references["alternative"])) $this->setContentType("multipart/alternative");
+ }
+ /**
+ * Move a branch of the tree, containing all it's MIME parts onto another branch
+ * @param string The content type on the branch itself
+ * @param string The content type which may exist in the branch's parent
+ * @param array The array containing all the nodes presently
+ * @param string The location of the branch now
+ * @param string The location of the branch after moving
+ * @param string The key to identify the branch by in it's new location
+ */
+ protected function moveBranchIn($type, $nested_type, $from, $old_branch, $new_branch, $tag)
+ {
+ $new = new Swift_Message_Part();
+ $new->setContentType($type);
+ $this->getReference("parent", $new_branch)->addChild($new, $tag, -1);
+
+ switch ($new_branch)
+ {
+ case "related": $this->setReference("related", $tag, $new);//relatedRefs[$tag] = $new;
+ break;
+ case "mixed": $this->setReference("mixed", $tag, $new);//mixedRefs[$tag] = $new;
+ break;
+ }
+
+ foreach ($from as $id => $ref)
+ {
+ if (!$ref) $ref = $this;
+ $sign = (strtolower($ref->getContentType()) == "text/plain"
+ || strtolower($ref->getContentType()) == $nested_type) ? -1 : 1;
+ switch ($new_branch)
+ {
+ case "related": $this->getReference("related", $tag)->addChild($ref, $id, $sign);
+ break;
+ case "mixed": $this->getReference("mixed", $tag)->addChild($ref, $id, $sign);
+ break;
+ }
+ $this->getReference("parent", $old_branch)->removeChild($id);
+ }
+ $this->setReference("parent", $old_branch, $new); //parentRefs[$old_branch] = $new;
+ }
+ /**
+ * Analyzes the mixing of MIME types in a mulitpart message an re-arranges if needed
+ * It looks complicated and long winded but the concept is pretty simple, even if putting it
+ * in code does me make want to cry!
+ */
+ protected function postAttachFixStructure()
+ {
+ switch (true)
+ {
+ case (!empty($this->references["mixed"]) && !empty($this->references["related"]) && !empty($this->references["alternative"])):
+ if (!isset($this->references["related"]["_alternative"]))
+ {
+ $this->moveBranchIn(
+ "multipart/alternative", "multipart/alternative", $this->references["alternative"], "alternative", "related", "_alternative");
+ }
+ if (!isset($this->references["mixed"]["_related"]))
+ {
+ $this->moveBranchIn(
+ "multipart/related", "multipart/alternative", $this->references["related"], "related", "mixed", "_related");
+ }
+ break;
+ case (!empty($this->references["mixed"]) && !empty($this->references["related"])):
+ if (!isset($this->references["mixed"]["_related"]))
+ {
+ $this->moveBranchIn(
+ "multipart/related", "multipart/related", $this->references["related"], "related", "mixed", "_related");
+ }
+ break;
+ case (!empty($this->references["mixed"]) && !empty($this->references["alternative"])):
+ if (!isset($this->references["mixed"]["_alternative"]))
+ {
+ $this->moveBranchIn(
+ "multipart/alternative", null, $this->references["alternative"], "alternative", "mixed", "_alternative");
+ }
+ break;
+ case (!empty($this->references["related"]) && !empty($this->references["alternative"])):
+ if (!isset($this->references["related"]["_alternative"]))
+ {
+ $this->moveBranchIn(
+ "multipart/alternative", "multipart/alternative", $this->references["alternative"], "alternative", "related", "_alternative");
+ }
+ break;
+ }
+ }
+ /**
+ * Move a branch further toward the top of the tree
+ * @param array The array containing MIME parts from the old branch
+ * @param string The name of the old branch
+ * @param string The name of the new branch
+ * @param string The key of the branch being moved
+ */
+ protected function moveBranchOut($from, $old_branch, $new_branch, $tag)
+ {
+ foreach ($from as $id => $ref)
+ {
+ if (!$ref) $ref = $this;
+ $sign = (strtolower($ref->getContentType()) == "text/html"
+ || strtolower($ref->getContentType()) == "multipart/alternative") ? -1 : 1;
+ $this->getReference("parent", $new_branch)->addChild($ref, $id, $sign);
+ switch ($new_branch)
+ {
+ case "related": $this->getReference("related", $tag)->removeChild($id);
+ break;
+ case "mixed": $this->getReference("parent", $old_branch)->removeChild($id);
+ break;
+ }
+ }
+ $this->getReference("parent", $new_branch)->removeChild($tag);
+ $mixed = $this->getReference("parent", $new_branch);//parentRefs[$new_branch];
+ $this->setReference("parent", $old_branch, $mixed);//parentRefs[$old_branch] = $mixed;
+ switch ($new_branch)
+ {
+ case "related": unset($this->references["related"][$tag]);
+ break;
+ case "mixed": unset($this->references["mixed"][$tag]);
+ break;
+ }
+ }
+ /**
+ * Analyzes the mixing of MIME types in a mulitpart message an re-arranges if needed
+ * It looks complicated and long winded but the concept is pretty simple, even if putting it
+ * in code does me make want to cry!
+ */
+ protected function postDetachFixStructure()
+ {
+ switch (true)
+ {
+ case (!empty($this->references["mixed"]) && !empty($this->references["related"]) && !empty($this->references["alternative"])):
+ if (array_keys($this->references["related"]) == array("_alternative"))
+ {
+ $alt = $this->getReference("parent", "related")->getChild("_alternative");
+ $this->getReference("parent", "mixed")->addChild($alt, "_alternative", -1);
+ $this->setReference("mixed", "_alternative", $alt);//mixedRefs["_alternative"] = $alt;
+ $this->getReference("parent", "related")->removeChild("_alternative");
+ unset($this->references["related"]["_alternative"]);
+ $this->getReference("parent", "mixed")->removeChild("_related");
+ unset($this->references["mixed"]["_related"]);
+ }
+ if (array_keys($this->references["mixed"]) == array("_related"))
+ {
+ $this->moveBranchOut($this->references["related"], "related", "mixed", "_related");
+ }
+ break;
+ case (!empty($this->references["mixed"]) && !empty($this->references["related"])):
+ if (array_keys($this->references["mixed"]) == array("_related"))
+ {
+ $this->moveBranchOut($this->references["related"], "related", "mixed", "_related");
+ }
+ if (isset($this->references["related"]["_alternative"]))
+ {
+ $this->detach("_alternative");
+ }
+ break;
+ case (!empty($this->references["mixed"]) && !empty($this->references["alternative"])):
+ if (array_keys($this->references["mixed"]) == array("_alternative"))
+ {
+ $this->moveBranchOut($this->references["alternative"], "alternative", "mixed", "_alternative");
+ }
+ break;
+ case (!empty($this->references["related"]) && !empty($this->references["alternative"])):
+ if (array_keys($this->references["related"]) == array("_alternative"))
+ {
+ $this->moveBranchOut($this->references["alternative"], "alternative", "related", "_alternative");
+ }
+ break;
+ case (!empty($this->references["mixed"])):
+ if (isset($this->references["mixed"]["_related"])) $this->detach("_related");
+ case (!empty($this->references["related"])):
+ if (isset($this->references["related"]["_alternative"]) || isset($this->references["mixed"]["_alternative"]))
+ $this->detach("_alternative");
+ break;
+ }
+ }
+ /**
+ * Execute needed logic prior to compilation
+ */
+ public function preBuild()
+ {
+ $data = $this->getData();
+ if (!($enc = $this->getEncoding()))
+ {
+ $this->setEncoding("8bit");
+ }
+ if ($this->getCharset() === null && !$this->numChildren())
+ {
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if (is_string($data) && Swift_Message_Encoder::instance()->isUTF8($data))
+ {
+ $this->setCharset("utf-8");
+ }
+ elseif(is_string($data) && Swift_Message_Encoder::instance()->is7BitAscii($data))
+ {
+ $this->setCharset("us-ascii");
+ if (!$enc) $this->setEncoding("7bit");
+ }
+ else $this->setCharset("iso-8859-1");
+ }
+ elseif ($this->numChildren())
+ {
+ if (!$this->getData())
+ {
+ $this->setData($this->getMimeWarning());
+ $this->setLineWrap(76);
+ }
+
+ if ($this->getCharset() !== null) $this->setCharset(null);
+ if ($this->isFlowed()) $this->setFlowed(false);
+ $this->setEncoding("7bit");
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Message.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/AntiFlood.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/AntiFlood.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/AntiFlood.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,105 @@
+<?php
+
+/**
+ * Swift Mailer AntiFlood Plugin
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_SendListener");
+
+/**
+ * Swift AntiFlood controller.
+ * Closes a connection and pauses for X seconds after a number of emails have been sent.
+ * @package Swift_Plugin
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_AntiFlood implements Swift_Events_SendListener
+{
+ /**
+ * The number of emails to send between connections
+ * @var int
+ */
+ protected $threshold = null;
+ /**
+ * The number of seconds to pause for between connections
+ * @var int
+ */
+ protected $waitFor = null;
+ /**
+ * Number of emails sent so far
+ * @var int
+ */
+ protected $count = 0;
+
+ /**
+ * Constructor
+ * @param int Number of emails to send before re-connecting
+ * @param int The timeout in seconds between connections
+ */
+ public function __construct($threshold, $wait=0)
+ {
+ $this->setThreshold($threshold);
+ $this->setWait($wait);
+ }
+ /**
+ * Set the number of emails which must be sent for a reconnection to occur
+ * @param int Number of emails
+ */
+ public function setThreshold($threshold)
+ {
+ $this->threshold = (int) $threshold;
+ }
+ /**
+ * Get the number of emails which need to be sent for reconnection to occur
+ * @return int
+ */
+ public function getThreshold()
+ {
+ return $this->threshold;
+ }
+ /**
+ * Set the number of seconds the plugin should wait for before reconnecting
+ * @param int Time in seconds
+ */
+ public function setWait($time)
+ {
+ $this->waitFor = (int) $time;
+ }
+ /**
+ * Get the number of seconds the plugin should wait for before re-connecting
+ * @return int
+ */
+ public function getWait()
+ {
+ return $this->waitFor;
+ }
+ /**
+ * Sleep for a given number of seconds
+ * @param int Number of seconds to wait for
+ */
+ public function wait($seconds)
+ {
+ if ($seconds) sleep($seconds);
+ }
+ /**
+ * Swift's SendEvent listener.
+ * Invoked when Swift sends a message
+ * @param Swift_Events_SendEvent The event information
+ * @throws Swift_ConnectionException If the connection cannot be closed/re-opened
+ */
+ public function sendPerformed(Swift_Events_SendEvent $e)
+ {
+ $this->count++;
+ if ($this->count >= $this->getThreshold())
+ {
+ $e->getSwift()->disconnect();
+ $this->wait($this->getWait());
+ $e->getSwift()->connect();
+ $this->count = 0;
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/AntiFlood.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/BandwidthMonitor.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/BandwidthMonitor.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/BandwidthMonitor.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * Swift Mailer Bandwidth Monitoring Plugin
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_CommandListener");
+Swift_ClassLoader::load("Swift_Events_ResponseListener");
+
+/**
+ * Swift Bandwidth Monitor.
+ * Tracks bytes in and out of the connection.
+ * @package Swift_Plugin
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_BandwidthMonitor implements Swift_Events_CommandListener, Swift_Events_ResponseListener
+{
+ /**
+ * The number of bytes received
+ * @var int
+ */
+ protected $in = 0;
+ /**
+ * The number of bytes sent
+ * @var int
+ */
+ protected $out = 0;
+
+ /**
+ * Part of the interface which is notified after a command is sent.
+ * @param Swift_Events_CommandEvent
+ */
+ public function commandSent(Swift_Events_CommandEvent $e)
+ {
+ $code = $e->getCode();
+ $add = 0;
+ if ($code != -1) $add = 2;
+ $bytes = strlen($e->getString()) + $add;
+ $this->addBytesOut($bytes);
+ }
+ /**
+ * Part of the interface which is notified when a response is received
+ * @param Swift_Events_ResponseEvent
+ */
+ public function responseReceived(Swift_Events_ResponseEvent $e)
+ {
+ $bytes = strlen($e->getString()) + 2;
+ $this->addBytesIn($bytes);
+ }
+ /**
+ * Add some bytes to the running totals for incoming bandwidth
+ * @param int Bytes in
+ */
+ public function addBytesIn($num)
+ {
+ $num = abs((int)$num);
+ $this->setBytesIn($this->getBytesIn() + $num);
+ }
+ /**
+ * Add some bytes to the running totals for outgoing bandwidth
+ * @param int Bytes out
+ */
+ public function addBytesOut($num)
+ {
+ $num = abs((int)$num);
+ $this->setBytesOut($this->getBytesOut() + $num);
+ }
+ /**
+ * Get the total number of bytes received
+ * @return int
+ */
+ public function getBytesIn()
+ {
+ return $this->in;
+ }
+ /**
+ * Get the total number of bytes sent
+ * @return int
+ */
+ public function getBytesOut()
+ {
+ return $this->out;
+ }
+ /**
+ * Set the total number of bytes received.
+ * Can be used to reset the counters at runtime.
+ * @param int The bytes in
+ */
+ public function setBytesIn($num)
+ {
+ $this->in = abs((int)$num);
+ }
+ /**
+ * Set the total number of bytes sent.
+ * Can be used to reset the counters at runtime.
+ * @param int The bytes out
+ */
+ public function setBytesOut($num)
+ {
+ $this->out = abs((int)$num);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/BandwidthMonitor.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/ConnectionRotator.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/ConnectionRotator.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/ConnectionRotator.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * Swift Mailer Rotating Connection Controller
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_SendListener");
+Swift_ClassLoader::load("Swift_Events_DisconnectListener");
+
+/**
+ * Swift Rotating Connection Controller
+ * Invokes the nextConnection() method of Swift_Connection_Rotator upon sending a given number of messages
+ * @package Swift_Plugin
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_ConnectionRotator implements Swift_Events_SendListener, Swift_Events_DisconnectListener
+{
+ /**
+ * The number of emails which must be sent before the connection is rotated
+ * @var int Threshold number of emails
+ */
+ protected $threshold = 1;
+ /**
+ * The total number of emails sent on this connection
+ * @var int
+ */
+ protected $count = 0;
+ /**
+ * The connections we have used thus far
+ * @var array
+ */
+ protected $used = array();
+ /**
+ * Internal check to see if this plugin has yet been invoked
+ * @var boolean
+ */
+ protected $called = false;
+
+ /**
+ * Constructor
+ * @param int The number of emails to send before rotating
+ */
+ public function __construct($threshold=1)
+ {
+ $this->setThreshold($threshold);
+ }
+ /**
+ * Set the number of emails to send before a connection rotation is tried
+ * @param int Number of emails
+ */
+ public function setThreshold($threshold)
+ {
+ $this->threshold = (int) $threshold;
+ }
+ /**
+ * Get the number of emails which must be sent before a rotation occurs
+ * @return int
+ */
+ public function getThreshold()
+ {
+ return $this->threshold;
+ }
+ /**
+ * Swift's SendEvent listener.
+ * Invoked when Swift sends a message
+ * @param Swift_Events_SendEvent The event information
+ * @throws Swift_ConnectionException If the connection cannot be rotated
+ */
+ public function sendPerformed(Swift_Events_SendEvent $e)
+ {
+ if (!method_exists($e->getSwift()->connection, "nextConnection"))
+ {
+ throw new Swift_ConnectionException("The ConnectionRotator plugin cannot be used with connections other than Swift_Connection_Rotator.");
+ }
+ if (!$this->called)
+ {
+ $this->used[] = $e->getSwift()->connection->getActive();
+ }
+ $this->count++;
+ if ($this->count >= $this->getThreshold())
+ {
+ $e->getSwift()->connection->nextConnection();
+ if (!in_array(($id = $e->getSwift()->connection->getActive()), $this->used))
+ {
+ $e->getSwift()->connect();
+ $this->used[] = $id;
+ }
+ $this->count = 0;
+ }
+ $this->called = true;
+ }
+ /**
+ * Disconnect all the other connections
+ * @param Swift_Events_DisconnectEvent The event info
+ */
+ public function disconnectPerformed(Swift_Events_DisconnectEvent $e)
+ {
+ $active = $e->getConnection()->getActive();
+ $e->getConnection()->nextConnection();
+ while ($e->getConnection()->getActive() != $active)
+ {
+ $e->getSwift()->command("QUIT", 221);
+ $e->getConnection()->stop();
+ $e->getConnection()->nextConnection();
+ }
+ $this->used = array();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/ConnectionRotator.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator/Replacements.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator/Replacements.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator/Replacements.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * Swift Mailer Decorator Replacements Container
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @subpackage Decorator
+ * @license GNU Lesser General Public License
+ */
+
+
+/**
+ * Swift Decorator Plugin Replacements.
+ * Provides and manages the list of replacements for the decorator plugin.
+ * @package Swift_Plugin
+ * @subpackage Decorator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_Decorator_Replacements
+{
+ /**
+ * The list of replacements as a 2-d array
+ * @var array,array
+ */
+ protected $replacements;
+
+ /**
+ * Ctor.
+ * @param array The replacements as a 2-d array, optional
+ */
+ public function __construct($replacements = array())
+ {
+ $this->setReplacements($replacements);
+ }
+ /**
+ * Add a list of replacements for a given address.
+ * @param string The e-mail address
+ * @param array The replacements as (search => replacement) form.
+ */
+ public function addReplacements($address, $replacements)
+ {
+ $this->replacements[strtolower($address)] = (array)$replacements;
+ }
+ /**
+ * Set the complete list of replacements as a 2-d array.
+ * The array is formed thus (address => (search => replace), address => (search => replace))
+ * @param array,array The replacements.
+ */
+ public function setReplacements($replacements)
+ {
+ $this->replacements = array_change_key_case((array) $replacements, CASE_LOWER);
+ }
+ /**
+ * Get the entire list of replacements as a 2-d array
+ * @return array,array
+ */
+ public function getReplacements()
+ {
+ return $this->replacements;
+ }
+ /**
+ * Get the list of replacements for the address given.
+ * Returns an array where (search => replacement).
+ * @param string The address to get replacements for
+ * @return array
+ */
+ public function getReplacementsFor($address)
+ {
+ $address = strtolower($address);
+ if (array_key_exists($address, $this->replacements))
+ {
+ return (array)$this->replacements[$address];
+ }
+ else return array();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator/Replacements.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,259 @@
+<?php
+
+/**
+ * Swift Mailer Message Decorating Plugin.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @subpackage Decorator
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_BeforeSendListener");
+Swift_ClassLoader::load("Swift_Plugin_Decorator_Replacements");
+
+/**
+ * Swift Decorator Plugin.
+ * Allows messages to be slightly different for each recipient.
+ * @package Swift_Plugin
+ * @subpackage Decorator
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_Decorator implements Swift_Events_BeforeSendListener
+{
+ /**
+ * The replacements object.
+ * @var Swift_Plugin_Decorator_Replacements
+ */
+ protected $replacements;
+ /**
+ * Temporary storage so we can restore changes we make.
+ * @var array
+ */
+ protected $store;
+ /**
+ * A list of allowed mime types to replace bodies for.
+ * @var array
+ */
+ protected $permittedTypes = array("text/plain" => 1, "text/html" => 1);
+ /**
+ * True if values in the headers can be replaced
+ * @var boolean
+ */
+ protected $permittedInHeaders = true;
+
+ /**
+ * Ctor.
+ * @param mixed Replacements as a 2-d array or Swift_Plugin_Decorator_Replacements instance.
+ */
+ public function __construct($replacements=null)
+ {
+ $this->setReplacements($replacements);
+ }
+ /**
+ * Enable of disable the ability to replace values in the headers
+ * @param boolean
+ */
+ public function setPermittedInHeaders($bool)
+ {
+ $this->permittedInHeaders = (bool) $bool;
+ }
+ /**
+ * Check if replacements in headers are allowed.
+ * @return boolean
+ */
+ public function getPermittedInHeaders()
+ {
+ return $this->permittedInHeaders;
+ }
+ /**
+ * Add a mime type to the list of permitted type to replace values in the body.
+ * @param string The mime type (e.g. text/plain)
+ */
+ public function addPermittedType($type)
+ {
+ $type = strtolower($type);
+ $this->permittedTypes[$type] = 1;
+ }
+ /**
+ * Remove the ability to replace values in the body of the given mime type
+ * @param string The mime type
+ */
+ public function removePermittedType($type)
+ {
+ unset($this->permittedTypes[$type]);
+ }
+ /**
+ * Get the list of mime types for which the body can be changed.
+ * @return array
+ */
+ public function getPermittedTypes()
+ {
+ return array_keys($this->permittedTypes);
+ }
+ /**
+ * Check if the body can be replaced in the given mime type.
+ * @param string The mime type
+ * @return boolean
+ */
+ public function isPermittedType($type)
+ {
+ return array_key_exists(strtolower($type), $this->permittedTypes);
+ }
+ /**
+ * Called just before Swift sends a message.
+ * We perform operations on the message here.
+ * @param Swift_Events_SendEvent The event object for sending a message
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $e)
+ {
+ $message = $e->getMessage();
+ $this->recursiveRestore($message, $this->store); //3.3.3 bugfix
+
+ $recipients = $e->getRecipients();
+ $to = array_keys($recipients->getTo());
+ if (count($to) > 0) $to = $to[0];
+ else return;
+
+ $replacements = (array)$this->replacements->getReplacementsFor($to);
+
+ $this->store = array(
+ "headers" => array(),
+ "body" => false,
+ "children" => array()
+ );
+ $this->recursiveReplace($message, $replacements, $this->store);
+ }
+ /**
+ * Replace strings in the message searching through all the allowed sub-parts.
+ * @param Swift_Message_Mime The message (or part)
+ * @param array The list of replacements
+ * @param array The array to cache original values into where needed
+ */
+ protected function recursiveReplace(Swift_Message_Mime $mime, $replacements, &$store)
+ {
+ //Check headers
+ if ($this->getPermittedInHeaders())
+ {
+ foreach ($mime->headers->getList() as $name => $value)
+ {
+ if (is_string($value) && ($replaced = $this->replace($replacements, $value)) != $value)
+ {
+ $mime->headers->set($name, $replaced);
+ $store["headers"][$name] = array();
+ $store["headers"][$name]["value"] = $value;
+ $store["headers"][$name]["attributes"] = array();
+ }
+ foreach ($mime->headers->listAttributes($name) as $att_name => $att_value)
+ {
+ if (is_string($att_value)
+ && ($att_replaced = $this->replace($replacements, $att_value)) != $att_value)
+ {
+ if (!isset($store["headers"][$name]))
+ {
+ $store["headers"][$name] = array("value" => false, "attributes" => array());
+ }
+ $mime->headers->setAttribute($name, $att_name, $att_replaced);
+ $store["headers"][$name]["attributes"][$att_name] = $att_value;
+ }
+ }
+ }
+ }
+ //Check body
+ $body = $mime->getData();
+ if ($this->isPermittedType($mime->getContentType())
+ && is_string($body) && ($replaced = $this->replace($replacements, $body)) != $body)
+ {
+ $mime->setData($replaced);
+ $store["body"] = $body;
+ }
+ //Check sub-parts
+ foreach ($mime->listChildren() as $id)
+ {
+ $store["children"][$id] = array(
+ "headers" => array(),
+ "body" => false,
+ "children" => array()
+ );
+ $child = $mime->getChild($id);
+ $this->recursiveReplace($child, $replacements, $store["children"][$id]);
+ }
+ }
+ /**
+ * Perform a str_replace() over the given value.
+ * @param array The list of replacements as (search => replacement)
+ * @param string The string to replace
+ * @return string
+ */
+ protected function replace($replacements, $value)
+ {
+ return str_replace(array_keys($replacements), array_values($replacements), $value);
+ }
+ /**
+ * Put the original values back in the message after it was modified before sending.
+ * @param Swift_Message_Mime The message (or part)
+ * @param array The location of the stored values
+ */
+ protected function recursiveRestore(Swift_Message_Mime $mime, &$store)
+ {
+ if (empty($store)) //3.3.3 bugfix
+ {
+ return;
+ }
+
+ //Restore headers
+ foreach ($store["headers"] as $name => $array)
+ {
+ if ($array["value"] !== false) $mime->headers->set($name, $array["value"]);
+ foreach ($array["attributes"] as $att_name => $att_value)
+ {
+ $mime->headers->setAttribute($name, $att_name, $att_value);
+ }
+ }
+ //Restore body
+ if ($store["body"] !== false)
+ {
+ $mime->setData($store["body"]);
+ }
+ //Restore children
+ foreach ($store["children"] as $id => $child_store)
+ {
+ $child = $mime->getChild($id);
+ $this->recursiveRestore($child, $child_store);
+ }
+ }
+ /**
+ * Set the replacements as a 2-d array or an instance of Swift_Plugin_Decorator_Replacements.
+ * @param mixed Array or Swift_Plugin_Decorator_Replacements
+ */
+ public function setReplacements($replacements)
+ {
+ if ($replacements === null)
+ {
+ $r = array();
+ $this->replacements = new Swift_Plugin_Decorator_Replacements($r);
+ }
+ elseif (is_array($replacements))
+ {
+ $this->replacements = new Swift_Plugin_Decorator_Replacements($replacements);
+ }
+ elseif ($replacements instanceof Swift_Plugin_Decorator_Replacements)
+ {
+ $this->replacements = $replacements;
+ }
+ else
+ {
+ throw new Exception(
+ "Decorator replacements must be array or instance of Swift_Plugin_Decorator_Replacements.");
+ }
+ }
+ /**
+ * Get the replacements object.
+ * @return Swift_Plugin_Decorator_Replacements
+ */
+ public function getReplacements()
+ {
+ return $this->replacements;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Decorator.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/EasySwiftResponseTracker.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/EasySwiftResponseTracker.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/EasySwiftResponseTracker.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * EasySwift Response Tracker
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package EasySwift
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_ResponseListener");
+
+/**
+ * EasySwift, Swift Response Tracker.
+ * Updates properties in EasySwift when a response is received by Swift.
+ * @package EasySwift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_EasySwiftResponseTracker implements Swift_Events_ResponseListener
+{
+ /**
+ * The target object to update
+ * @var EasySwift
+ */
+ protected $target = null;
+
+ /**
+ * Constructor
+ * @param EasySwift The instance of EasySwift to run against
+ */
+ public function __construct($obj)
+ {
+ $this->target = $obj;
+ }
+ /**
+ * Response listener method
+ * @param Swift_Events_ResponseEvent The event occured in Swift
+ */
+ public function responseReceived(Swift_Events_ResponseEvent $e)
+ {
+ $this->target->lastResponse = $e->getString();
+ $this->target->responseCode = $e->getCode();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/EasySwiftResponseTracker.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/FileEmbedder.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/FileEmbedder.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/FileEmbedder.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,431 @@
+<?php
+
+/**
+ * A Swift Mailer plugin to download remote images and stylesheets then embed them.
+ * This also embeds local files from disk.
+ * Please read the LICENSE file
+ * @package Swift_Plugin
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_BeforeSendListener");
+
+/**
+ * Swift FileEmbedder Plugin to embed remote files.
+ * Scans a Swift_Message instance for remote files and then embeds them before sending.
+ * This also embeds local files from disk.
+ * @package Swift_Plugin
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_FileEmbedder implements Swift_Events_BeforeSendListener
+{
+ /**
+ * True if remote files will be embedded.
+ * @var boolean
+ */
+ protected $embedRemoteFiles = true;
+ /**
+ * True if local files will be embedded.
+ * @var boolean
+ */
+ protected $embedLocalFiles = true;
+ /**
+ * (X)HTML tag defintions listing allowed attributes and extensions.
+ * @var array
+ */
+ protected $definitions = array(
+ "img" => array(
+ "attributes" => array("src"),
+ "extensions" => array("gif", "png", "jpg", "jpeg", "pjpeg")
+ ),
+ "link" => array(
+ "attributes" => array("href"),
+ "extensions" => array("css")
+ ),
+ "script" => array(
+ "attributes" => array("src"),
+ "extensions" => array("js")
+ ));
+ /**
+ * Protocols which may be used to download a remote file.
+ * @var array
+ */
+ protected $protocols = array(
+ "http" => "http",
+ "https" => "https",
+ "ftp" => "ftp"
+ );
+ /**
+ * A PCRE regexp which will be passed via sprintf() to produce a complete pattern.
+ * @var string
+ */
+ protected $remoteFilePatternFormat = "~
+ (<(?:%s)\\s+[^>]*? #Opening tag followed by (possible) attributes
+ (?:%s)=((?:\"|')?)) #Permitted attributes followed by (possible) quotation marks
+ ((?:%s)://[\\x01-\\x7F]*?(?:%s)?) #Remote URL (matching a permitted protocol)
+ (\\2[^>]*>) #Remaining attributes followed by end of tag
+ ~isx";
+ /**
+ * A PCRE regexp which will be passed via sprintf() to produce a complete pattern.
+ * @var string
+ */
+ protected $localFilePatternFormat = "~
+ (<(?:%s)\\s+[^>]*? #Opening tag followed by (possible) attributes
+ (?:%s)=((?:\"|')?)) #Permitted attributes followed by (possible) quotation marks
+ ((?:/|[a-z]:\\\\|[a-z]:/)[\\x01-\\x7F]*?(?:%s)?) #Local, absolute path
+ (\\2[^>]*>) #Remaining attributes followed by end of tag
+ ~isx";
+ /**
+ * A list of extensions mapping to their usual MIME types.
+ * @var array
+ */
+ protected $mimeTypes = array(
+ "gif" => "image/gif",
+ "png" => "image/png",
+ "jpeg" => "image/jpeg",
+ "jpg" => "image/jpeg",
+ "pjpeg" => "image/pjpeg",
+ "js" => "text/javascript",
+ "css" => "text/css");
+ /**
+ * Child IDs of files already embedded.
+ * @var array
+ */
+ protected $registeredFiles = array();
+
+ /**
+ * Get the MIME type based upon the extension.
+ * @param string The extension (sans the dot).
+ * @return string
+ */
+ public function getType($ext)
+ {
+ $ext = strtolower($ext);
+ if (isset($this->mimeTypes[$ext]))
+ {
+ return $this->mimeTypes[$ext];
+ }
+ else return null;
+ }
+ /**
+ * Add a new MIME type defintion (or overwrite an existing one).
+ * @param string The extension (sans the dot)
+ * @param string The MIME type (e.g. image/jpeg)
+ */
+ public function addType($ext, $type)
+ {
+ $this->mimeTypes[strtolower($ext)] = strtolower($type);
+ }
+ /**
+ * Set the PCRE pattern which finds -full- HTML tags and copies the path for a local file into a backreference.
+ * The pattern contains three %s replacements for sprintf().
+ * First replacement is the tag name (e.g. img)
+ * Second replacement is the attribute name (e.g. src)
+ * Third replacement is the file extension (e.g. jpg)
+ * This pattern should contain the full URL in backreference index 3.
+ * @param string sprintf() format string containing a PCRE regexp.
+ */
+ public function setLocalFilePatternFormat($format)
+ {
+ $this->localFilePatternFormat = $format;
+ }
+ /**
+ * Gets the sprintf() format string for the PCRE pattern to scan for remote files.
+ * @return string
+ */
+ public function getLocalFilePatternFormat()
+ {
+ return $this->localFilePatternFormat;
+ }
+ /**
+ * Set the PCRE pattern which finds -full- HTML tags and copies the URL for the remote file into a backreference.
+ * The pattern contains four %s replacements for sprintf().
+ * First replacement is the tag name (e.g. img)
+ * Second replacement is the attribute name (e.g. src)
+ * Third replacement is the protocol (e.g. http)
+ * Fourth replacement is the file extension (e.g. jpg)
+ * This pattern should contain the full URL in backreference index 3.
+ * @param string sprintf() format string containing a PCRE regexp.
+ */
+ public function setRemoteFilePatternFormat($format)
+ {
+ $this->remoteFilePatternFormat = $format;
+ }
+ /**
+ * Gets the sprintf() format string for the PCRE pattern to scan for remote files.
+ * @return string
+ */
+ public function getRemoteFilePatternFormat()
+ {
+ return $this->remoteFilePatternFormat;
+ }
+ /**
+ * Add a new protocol which can be used to download files.
+ * Protocols should not include the "://" portion. This method expects alphanumeric characters only.
+ * @param string The protocol name (e.g. http or ftp)
+ */
+ public function addProtocol($prot)
+ {
+ $prot = strtolower($prot);
+ $this->protocols[$prot] = $prot;
+ }
+ /**
+ * Remove a protocol from the list of allowed protocols once added.
+ * @param string The name of the protocol (e.g. http)
+ */
+ public function removeProtocol($prot)
+ {
+ unset($this->protocols[strtolower($prot)]);
+ }
+ /**
+ * Get a list of all registered protocols.
+ * @return array
+ */
+ public function getProtocols()
+ {
+ return array_values($this->protocols);
+ }
+ /**
+ * Add, or modify a tag definition.
+ * This affects how the plugins scans for files to download.
+ * @param string The name of a tag to search for (e.g. img)
+ * @param string The name of attributes to look for (e.g. src). You can pass an array if there are multiple possibilities.
+ * @param array A list of extensions to allow (sans dot). If there's only one you can just pass a string.
+ */
+ public function setTagDefinition($tag, $attributes, $extensions)
+ {
+ $tag = strtolower($tag);
+ $attributes = (array)$attributes;
+ $extensions = (array)$extensions;
+
+ if (empty($tag) || empty($attributes) || empty($extensions))
+ {
+ return null;
+ }
+
+ $this->definitions[$tag] = array("attributes" => $attributes, "extensions" => $extensions);
+ return true;
+ }
+ /**
+ * Remove a tag definition for remote files.
+ * @param string The name of the tag
+ */
+ public function removeTagDefinition($tag)
+ {
+ unset($this->definitions[strtolower($tag)]);
+ }
+ /**
+ * Get a tag definition.
+ * Returns an array with indexes "attributes" and "extensions".
+ * Each element is an array listing the values within it.
+ * @param string The name of the tag
+ * @return array
+ */
+ public function getTagDefinition($tag)
+ {
+ $tag = strtolower($tag);
+ if (isset($this->definitions[$tag])) return $this->definitions[$tag];
+ else return null;
+ }
+ /**
+ * Get the PCRE pattern for a remote file based on the tag name.
+ * @param string The name of the tag
+ * @return string
+ */
+ public function getRemoteFilePattern($tag_name)
+ {
+ $tag_name = strtolower($tag_name);
+ $pattern_format = $this->getRemoteFilePatternFormat();
+ if ($def = $this->getTagDefinition($tag_name))
+ {
+ $pattern = sprintf($pattern_format, $tag_name, implode("|", $def["attributes"]),
+ implode("|", $this->getProtocols()), implode("|", $def["extensions"]));
+ return $pattern;
+ }
+ else return null;
+ }
+ /**
+ * Get the PCRE pattern for a local file based on the tag name.
+ * @param string The name of the tag
+ * @return string
+ */
+ public function getLocalFilePattern($tag_name)
+ {
+ $tag_name = strtolower($tag_name);
+ $pattern_format = $this->getLocalFilePatternFormat();
+ if ($def = $this->getTagDefinition($tag_name))
+ {
+ $pattern = sprintf($pattern_format, $tag_name, implode("|", $def["attributes"]),
+ implode("|", $def["extensions"]));
+ return $pattern;
+ }
+ else return null;
+ }
+ /**
+ * Register a file which has been downloaded so it doesn't need to be downloaded twice.
+ * @param string The remote URL
+ * @param string The ID as attached in the message
+ * @param Swift_Message_EmbeddedFile The file object itself
+ */
+ public function registerFile($url, $cid, $file)
+ {
+ $url = strtolower($url);
+ if (!isset($this->registeredFiles[$url])) $this->registeredFiles[$url] = array("cids" => array(), "obj" => null);
+ $this->registeredFiles[$url]["cids"][] = $cid;
+ if (empty($this->registeredFiles[$url]["obj"])) $this->registeredFiles[$url]["obj"] = $file;
+ }
+ /**
+ * Turn on or off remote file embedding.
+ * @param boolean
+ */
+ public function setEmbedRemoteFiles($set)
+ {
+ $this->embedRemoteFiles = (bool)$set;
+ }
+ /**
+ * Returns true if remote files can be embedded, or false if not.
+ * @return boolean
+ */
+ public function getEmbedRemoteFiles()
+ {
+ return $this->embedRemoteFiles;
+ }
+ /**
+ * Turn on or off local file embedding.
+ * @param boolean
+ */
+ public function setEmbedLocalFiles($set)
+ {
+ $this->embedLocalFiles = (bool)$set;
+ }
+ /**
+ * Returns true if local files can be embedded, or false if not.
+ * @return boolean
+ */
+ public function getEmbedLocalFiles()
+ {
+ return $this->embedLocalFiles;
+ }
+ /**
+ * Callback method for preg_replace().
+ * Embeds files which have been found during scanning.
+ * @param array Backreferences from preg_replace()
+ * @return string The tag with it's URL replaced with a CID
+ */
+ protected function embedRemoteFile($matches)
+ {
+ $url = preg_replace("~^([^#]+)#.*\$~s", "\$1", $matches[3]);
+ $bits = parse_url($url);
+ $ext = preg_replace("~^.*?\\.([^\\.]+)\$~s", "\$1", $bits["path"]);
+
+ $lower_url = strtolower($url);
+ if (array_key_exists($lower_url, $this->registeredFiles))
+ {
+ $registered = $this->registeredFiles[$lower_url];
+ foreach ($registered["cids"] as $cid)
+ {
+ if ($this->message->hasChild($cid))
+ {
+ return $matches[1] . $cid . $matches[4];
+ }
+ }
+ //If we get here the file is downloaded, but not embedded
+ $cid = $this->message->attach($registered["obj"]);
+ $this->registerFile($url, $cid, $registered["obj"]);
+ return $matches[1] . $cid . $matches[4];
+ }
+ $magic_quotes = get_magic_quotes_runtime();
+ set_magic_quotes_runtime(0);
+ $filedata = @file_get_contents($url);
+ set_magic_quotes_runtime($magic_quotes);
+ if (!$filedata)
+ {
+ return $matches[1] . $matches[3] . $matches[4];
+ }
+ $filename = preg_replace("~^.*/([^/]+)\$~s", "\$1", $url);
+ $att = new Swift_Message_EmbeddedFile($filedata, $filename, $this->getType($ext));
+ $id = $this->message->attach($att);
+ $this->registerFile($url, $id, $att);
+ return $matches[1] . $id . $matches[4];
+ }
+ /**
+ * Callback method for preg_replace().
+ * Embeds files which have been found during scanning.
+ * @param array Backreferences from preg_replace()
+ * @return string The tag with it's path replaced with a CID
+ */
+ protected function embedLocalFile($matches)
+ {
+ $path = realpath($matches[3]);
+ if (!$path)
+ {
+ return $matches[1] . $matches[3] . $matches[4];
+ }
+ $ext = preg_replace("~^.*?\\.([^\\.]+)\$~s", "\$1", $path);
+
+ $lower_path = strtolower($path);
+ if (array_key_exists($lower_path, $this->registeredFiles))
+ {
+ $registered = $this->registeredFiles[$lower_path];
+ foreach ($registered["cids"] as $cid)
+ {
+ if ($this->message->hasChild($cid))
+ {
+ return $matches[1] . $cid . $matches[4];
+ }
+ }
+ //If we get here the file is downloaded, but not embedded
+ $cid = $this->message->attach($registered["obj"]);
+ $this->registerFile($path, $cid, $registered["obj"]);
+ return $matches[1] . $cid . $matches[4];
+ }
+ $filename = basename($path);
+ $att = new Swift_Message_EmbeddedFile(new Swift_File($path), $filename, $this->getType($ext));
+ $id = $this->message->attach($att);
+ $this->registerFile($path, $id, $att);
+ return $matches[1] . $id . $matches[4];
+ }
+ /**
+ * Empty out the cache of registered files.
+ */
+ public function clearCache()
+ {
+ $this->registeredFiles = null;
+ $this->registeredFiles = array();
+ }
+ /**
+ * Swift's BeforeSendListener required method.
+ * Runs just before Swift sends a message. Here is where we do all the replacements.
+ * @param Swift_Events_SendEvent
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $e)
+ {
+ $this->message = $e->getMessage();
+
+ foreach ($this->message->listChildren() as $id)
+ {
+ $part = $this->message->getChild($id);
+ $body = $part->getData();
+ if (!is_string($body) || substr(strtolower($part->getContentType()), 0, 5) != "text/") continue;
+
+ foreach ($this->definitions as $tag_name => $def)
+ {
+ if ($this->getEmbedRemoteFiles())
+ {
+ $re = $this->getRemoteFilePattern($tag_name);
+ $body = preg_replace_callback($re, array($this, "embedRemoteFile"), $body);
+ }
+
+ if ($this->getEmbedLocalFiles())
+ {
+ $re = $this->getLocalFilePattern($tag_name);
+ $body = preg_replace_callback($re, array($this, "embedLocalFile"), $body);
+ }
+ }
+
+ $part->setData($body);
+ }
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/FileEmbedder.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/MailSend.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/MailSend.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/MailSend.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,170 @@
+<?php
+
+/**
+ * Swift Mailer mail() sending plugin
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Connection
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_SendListener");
+Swift_ClassLoader::load("Swift_Events_BeforeSendListener");
+
+/**
+ * Swift mail() send plugin
+ * Sends the message using mail() when a SendEvent is fired. Using the NativeMail connection provides stub responses to allow this to happen cleanly.
+ * @package Swift_Connection
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_MailSend implements Swift_Events_SendListener, Swift_Events_BeforeSendListener
+{
+ /**
+ * The operating system of the server
+ * @var string
+ */
+ protected $OS = null;
+ /**
+ * The return path in use here
+ * @var string
+ */
+ protected $returnPath = null;
+ /**
+ * The line ending before we intrusively change it
+ * @var string
+ */
+ protected $oldLE = "\r\n";
+ /**
+ * 5th parameter in mail().
+ * @var string
+ */
+ protected $additionalParams;
+
+ /**
+ * Constructor.
+ * @param string 5th mail() function parameter as a sprintf() formatted string where %s is the sender.
+ */
+ public function __construct($params="-oi -f %s")
+ {
+ $this->setAdditionalParams($params);
+ $this->setOS(PHP_OS);
+ }
+ /**
+ * Set the 5th mail() function parameter as a sprintf() formatted string where %s is the sender.
+ * @param string
+ */
+ public function setAdditionalParams($params)
+ {
+ $this->additionalParams = $params;
+ }
+ /**
+ * Get the 5th mail() function parameter as a sprintf() string.
+ * @return string
+ */
+ public function getAdditionalParams()
+ {
+ return $this->additionalParams;
+ }
+ /**
+ * Set the operating system string (changes behaviour with LE)
+ * @param string The operating system
+ */
+ public function setOS($os)
+ {
+ $this->OS = $os;
+ }
+ /**
+ * Get the operating system string
+ * @return string
+ */
+ public function getOS()
+ {
+ return $this->OS;
+ }
+ /**
+ * Check if this is windows or not
+ * @return boolean
+ */
+ public function isWindows()
+ {
+ return (substr($this->getOS(), 0, 3) == "WIN");
+ }
+ /**
+ * Swift's BeforeSendEvent listener.
+ * Invoked just before Swift sends a message
+ * @param Swift_Events_SendEvent The event information
+ */
+ public function beforeSendPerformed(Swift_Events_SendEvent $e)
+ {
+ $message = $e->getMessage();
+ $message->uncacheAll();
+ $this->oldLE = $message->getLE();
+ if (!$this->isWindows() && $this->oldLE != "\n") $message->setLE("\n");
+ }
+ /**
+ * Swift's SendEvent listener.
+ * Invoked when Swift sends a message
+ * @param Swift_Events_SendEvent The event information
+ * @throws Swift_ConnectionException If mail() returns false
+ */
+ public function sendPerformed(Swift_Events_SendEvent $e)
+ {
+ $message = $e->getMessage();
+ $recipients = $e->getRecipients();
+
+ $to = array();
+ foreach ($recipients->getTo() as $addr)
+ {
+ if ($this->isWindows()) $to[] = substr($addr->build(true), 1, -1);
+ else $to[] = $addr->build();
+ }
+ $to = implode(", ", $to);
+
+ $bcc_orig = $message->headers->has("Bcc") ? $message->headers->get("Bcc") : null;
+ $subject_orig = $message->headers->has("Subject") ? $message->headers->get("Subject") : null;
+ $to_orig = $message->headers->has("To") ? $message->headers->get("To") : null;
+
+ $bcc = array();
+ foreach ($recipients->getBcc() as $addr) $bcc[] = $addr->build();
+ if (!empty($bcc)) $message->headers->set("Bcc", $bcc);
+ $bcc = null;
+
+ $body_data = $message->buildData();
+ $message_body = $body_data->readFull();
+
+ $subject_enc = $message->headers->has("Subject") ? $message->headers->getEncoded("Subject") : "";
+
+ $message->headers->set("To", null);
+ $message->headers->set("Subject", null);
+
+ $sender = $e->getSender();
+ $this->returnPath = $sender->build();
+ if ($message->headers->has("Return-Path")) $this->returnPath = $message->headers->get("Return-Path");
+ if (preg_match("~<([^>]+)>[^>]*\$~", $this->returnPath, $matches)) $this->returnPath = $matches[1];
+
+ $this->doMail($to, $subject_enc, $message_body, $message->headers, sprintf($this->getAdditionalParams(), $this->returnPath));
+ $message->setLE($this->oldLE);
+ $message->headers->set("To", $to_orig);
+ $message->headers->set("Subject", $subject_orig);
+ $message->headers->set("Bcc", $bcc_orig);
+ }
+
+ public function doMail($to, $subject, $message, $headers, $params)
+ {
+ $original_from = @ini_get("sendmail_from");
+ @ini_set("sendmail_from", $this->returnPath);
+
+ $headers = $headers->build();
+
+ if (!ini_get("safe_mode")) $success = mail($to, $subject, $message, $headers, $params);
+ else $success = mail($to, $subject, $message, $headers);
+
+ if (!$success)
+ {
+ @ini_set("sendmail_from", $original_from);
+ throw new Swift_ConnectionException("Sending failed using mail() as PHP's default mail() function returned boolean FALSE.");
+ }
+ @ini_set("sendmail_from", $original_from);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/MailSend.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Throttler.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Throttler.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Throttler.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,168 @@
+<?php
+
+/**
+ * Swift Mailer Throttling Plugin.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Plugin_BandwidthMonitor");
+Swift_ClassLoader::load("Swift_Events_SendListener");
+
+/**
+ * Throttler plugin for Swift Mailer.
+ * Restricts the speed at which Swift will operate.
+ * @package Swift_Plugin
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_Throttler extends Swift_Plugin_BandwidthMonitor implements Swift_Events_SendListener
+{
+ /**
+ * The rate in byte-per-minute
+ * @var int
+ */
+ protected $bpm = null;
+ /**
+ * The rate as emails-per-minute
+ * @var int
+ */
+ protected $epm = null;
+ /**
+ * The number of emails sent so far
+ * @var int
+ */
+ protected $sent = 0;
+ /**
+ * The time at the start of overall execution
+ * @var int
+ */
+ protected $time = null;
+
+ /**
+ * Part of the interface which is notified after a command is sent.
+ * @param Swift_Events_CommandEvent
+ */
+ public function commandSent(Swift_Events_CommandEvent $e)
+ {
+ parent::commandSent($e);
+ if (null === $rate = $this->getBytesPerMinute()) return;
+
+ $duration = $this->getTimeLapse();
+ $bytes_sent = $this->getBytesOut();
+ $bytes_per_sec = $rate / 60;
+ $seconds_allowed_so_far = ceil($bytes_sent / $bytes_per_sec);
+ $overrun = $seconds_allowed_so_far - $duration;
+ if ($overrun > 0)
+ {
+ $this->wait($overrun);
+ }
+ }
+ /**
+ * Part of the interface which is notified when a message has been sent.
+ * @param Swift_Events_SendEvent
+ */
+ public function sendPerformed(Swift_Events_SendEvent $e)
+ {
+ $this->setSent($this->getSent() + 1);
+ if (null === $rate = $this->getEmailsPerMinute()) return;
+
+ $duration = $this->getTimeLapse();
+ $emails_sent = $this->getSent();
+ $emails_per_sec = $rate / 60;
+ $seconds_allowed_so_far = ceil($emails_sent / $emails_per_sec);
+ $overrun = $seconds_allowed_so_far - $duration;
+ if ($overrun > 0)
+ {
+ $this->wait($overrun);
+ }
+ }
+ /**
+ * Wait for $seconds before continuing
+ * @param int The number of seconds to wait
+ */
+ public function wait($secs)
+ {
+ sleep($secs);
+ }
+ /**
+ * Set the time if it's not already set
+ */
+ protected function setTime()
+ {
+ if ($this->time === null) $this->time = time();
+ }
+ /**
+ * Get the time taken thus far (full seconds).
+ * @return int
+ */
+ public function getTimeLapse()
+ {
+ $this->setTime();
+ return time() - $this->time;
+ }
+ /**
+ * Set the number of emails sent
+ * @param int Emails sent so far
+ */
+ public function setSent($num)
+ {
+ $this->sent = (int)$num;
+ }
+ /**
+ * Get the number of emails sent
+ * @return int
+ */
+ public function getSent()
+ {
+ return $this->sent;
+ }
+ /**
+ * Set the throttling rate as bytes per minute
+ * @param int The maximum number of outgoing bytes in 60 seconds.
+ */
+ public function setBytesPerMinute($bpm)
+ {
+ if ($bpm === null)
+ {
+ $this->bpm = null;
+ return;
+ }
+ $this->setEmailsPerMinute(null);
+ $this->bpm = abs((int)$bpm);
+ }
+ /**
+ * Get the number of bytes allowed per minute.
+ * Reurns NULL if not used.
+ * @return int
+ */
+ public function getBytesPerMinute()
+ {
+ return $this->bpm;
+ }
+ /**
+ * Set the rate as emails-per-minute.
+ * @param int The max number of emails to send in a minute.
+ */
+ public function setEmailsPerMinute($epm)
+ {
+ if ($epm === null)
+ {
+ $this->epm = null;
+ return;
+ }
+ $this->setBytesPerMinute(null);
+ $this->epm = abs((int)$epm);
+ }
+ /**
+ * Get the rate as number of emails per minute.
+ * Returns null if not used.
+ * @return int
+ */
+ public function getEmailsPerMinute()
+ {
+ return $this->epm;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/Throttler.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/AbstractView.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/AbstractView.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/AbstractView.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * Swift Mailer Verbose-sending Plugin View Layer.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @subpackage VerboseSending
+ * @license GNU Lesser General Public License
+ */
+
+/**
+ * The View layer for the Verbose Sending Plugin
+ * @package Swift_Plugin
+ * @subpackage VerboseSending
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+abstract class Swift_Plugin_VerboseSending_AbstractView
+{
+ /**
+ * Paint the result of a send operation
+ * @param string The email address that was tried
+ * @param boolean True if the message was successfully sent
+ */
+ abstract public function paintResult($address, $result);
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/AbstractView.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/DefaultView.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/DefaultView.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/DefaultView.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Swift Mailer Verbose-sending Plugin Default View File.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @subpackage VerboseSending
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Plugin_VerboseSending_AbstractView");
+
+/**
+ * The Default View for the Verbose Sending Plugin
+ * @package Swift_Plugin
+ * @subpackage VerboseSending
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_VerboseSending_DefaultView extends Swift_Plugin_VerboseSending_AbstractView
+{
+ /**
+ * Number of recipients painted
+ * @var int
+ */
+ protected $count = 0;
+
+ /**
+ * Paint the result of a send operation
+ * @param string The email address that was tried
+ * @param boolean True if the message was successfully sent
+ */
+ public function paintResult($address, $result)
+ {
+ $this->count++;
+ $color = $result ? "#51c45f" : "#d67d71";
+ $result_text = $result ? "PASS" : "FAIL";
+ ?>
+ <div style="color: #ffffff; margin: 2px; padding: 3px;
+ font-weight: bold; background: <?php echo $color; ?>;">
+ <span style="float: right; text-decoration: underline;">
+ <?php echo $result_text; ?></span>
+ Recipient (<?php echo $this->count; ?>):
+ <?php echo $address; ?>
+ </div>
+ <?php
+ flush();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending/DefaultView.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * Swift Mailer Verbose Sending Plugin.
+ * Please read the LICENSE file
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift_Plugin
+ * @subpackage VerboseSending
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/../ClassLoader.php";
+Swift_ClassLoader::load("Swift_Events_SendListener");
+Swift_ClassLoader::load("Swift_Plugin_VerboseSending_DefaultView");
+
+/**
+ * Verbose Sending plugin for Swift Mailer.
+ * Displays "pass" or "fail" messages in realtime as the messages are sent.
+ * @package Swift_Plugin
+ * @subpackage VerboseSending
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_Plugin_VerboseSending implements Swift_Events_SendListener
+{
+ /**
+ * The view layer which displays the results.
+ * @var Swift_Plugin_VerboseSending_AbstractView
+ */
+ protected $view;
+
+ /**
+ * Ctor.
+ * @param Swift_Plugin_VerboseSending_AbstractView The view object to display the result
+ */
+ public function __construct(Swift_Plugin_VerboseSending_AbstractView $view)
+ {
+ $this->setView($view);
+ }
+ /**
+ * Part of the interface which is notified when a message has been sent.
+ * @param Swift_Events_SendEvent
+ */
+ public function sendPerformed(Swift_Events_SendEvent $e)
+ {
+ $recipients = $e->getRecipients();
+ $failed = $e->getFailedRecipients();
+ $it = $recipients->getIterator("to");
+ while ($it->hasNext())
+ {
+ $it->next();
+ $address = $it->getValue();
+ $pass = !in_array($address->getAddress(), $failed);
+ $this->getView()->paintResult($address->getAddress(), $pass);
+ }
+ $it = $recipients->getIterator("cc");
+ while ($it->hasNext())
+ {
+ $it->next();
+ $address = $it->getValue();
+ $pass = !in_array($address->getAddress(), $failed);
+ $this->getView()->paintResult($address->getAddress(), $pass);
+ }
+ $it = $recipients->getIterator("bcc");
+ while ($it->hasNext())
+ {
+ $it->next();
+ $address = $it->getValue();
+ $pass = !in_array($address->getAddress(), $failed);
+ $this->getView()->paintResult($address->getAddress(), $pass);
+ }
+ }
+ /**
+ * Set the View component to display results.
+ * @param Swift_Plugin_VerboseSending_AbstractView The view object to display the result
+ */
+ public function setView(Swift_Plugin_VerboseSending_AbstractView $view)
+ {
+ $this->view = $view;
+ }
+ /**
+ * Get the View component.
+ * @return Swift_Plugin_VerboseSending_AbstractView
+ */
+ public function getView()
+ {
+ return $this->view;
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/Plugin/VerboseSending.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/RecipientList.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/RecipientList.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/RecipientList.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,234 @@
+<?php
+
+/**
+ * Swift Mailer Recipient List Container
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/ClassLoader.php";
+Swift_ClassLoader::load("Swift_Address");
+Swift_ClassLoader::load("Swift_Iterator_Array");
+
+/**
+ * Swift's Recipient List container. Contains To, Cc, Bcc
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ */
+class Swift_RecipientList extends Swift_AddressContainer
+{
+ /**
+ * The recipients in the To: header
+ * @var array
+ */
+ protected $to = array();
+ /**
+ * The recipients in the Cc: header
+ * @var array
+ */
+ protected $cc = array();
+ /**
+ * The recipients in the Bcc: header
+ * @var array
+ */
+ protected $bcc = array();
+ /**
+ * Iterators to use when getting lists back out.
+ * If any iterators are present here, their relevant "addXX()" methods will be useless.
+ * As per the last note, any iterators need to be pre-configured before Swift::send() is called.
+ * @var array,Swift_Iterator
+ */
+ protected $iterators = array("to" => null, "cc" => null, "bcc" => null);
+
+ /**
+ * Add a recipient.
+ * @param string The address
+ * @param string The name
+ * @param string The field (to, cc or bcc)
+ */
+ public function add($address, $name="", $where="to")
+ {
+ if ($address instanceof Swift_Address)
+ {
+ $address_str = trim(strtolower($address->getAddress()));
+ }
+
+ elseif (is_array($address))
+ {
+ foreach ($address as $a) $this->add($a, $name, $where);
+ return;
+ }
+ else
+ {
+ $address_str = (string) $address;
+ $address_str = trim(strtolower($address_str));
+ $address = new Swift_Address($address_str, $name);
+ }
+
+ if (in_array($where, array("to", "cc", "bcc")))
+ {
+ $container =& $this->$where;
+ $container[$address_str] = $address;
+ }
+ }
+ /**
+ * Remove a recipient.
+ * @param string The address
+ * @param string The field (to, cc or bcc)
+ */
+ public function remove($address, $where="to")
+ {
+ if ($address instanceof Swift_Address)
+ {
+ $key = trim(strtolower($address->getAddress()));
+ }
+ else $key = trim(strtolower((string) $address));
+
+ if (in_array($where, array("to", "cc", "bcc")))
+ {
+ if (array_key_exists($key, $this->$where)) unset($this->{$where}[$key]);
+ }
+ }
+ /**
+ * Get an iterator object for all the recipients in the given field.
+ * @param string The field name (to, cc or bcc)
+ * @return Swift_Iterator
+ */
+ public function getIterator($where)
+ {
+ if (!empty($this->iterators[$where]))
+ {
+ return $this->iterators[$where];
+ }
+ elseif (in_array($where, array("to", "cc", "bcc")))
+ {
+ $it = new Swift_Iterator_Array($this->$where);
+ return $it;
+ }
+ }
+ /**
+ * Override the loading of the default iterator (Swift_ArrayIterator) and use the one given here.
+ * @param Swift_Iterator The iterator to use. It must be populated already.
+ */
+ public function setIterator(Swift_Iterator $it, $where)
+ {
+ if (in_array($where, array("to", "cc", "bcc")))
+ {
+ $this->iterators[$where] = $it;
+ }
+ }
+ /**
+ * Add a To: recipient
+ * @param mixed The address to add. Can be a string or Swift_Address
+ * @param string The personal name, optional
+ */
+ public function addTo($address, $name=null)
+ {
+ $this->add($address, $name, "to");
+ }
+ /**
+ * Get an array of addresses in the To: field
+ * The array contains Swift_Address objects
+ * @return array
+ */
+ public function getTo()
+ {
+ return $this->to;
+ }
+ /**
+ * Remove a To: recipient from the list
+ * @param mixed The address to remove. Can be Swift_Address or a string
+ */
+ public function removeTo($address)
+ {
+ $this->remove($address, "to");
+ }
+ /**
+ * Empty all To: addresses
+ */
+ public function flushTo()
+ {
+ $this->to = null;
+ $this->to = array();
+ }
+ /**
+ * Add a Cc: recipient
+ * @param mixed The address to add. Can be a string or Swift_Address
+ * @param string The personal name, optional
+ */
+ public function addCc($address, $name=null)
+ {
+ $this->add($address, $name, "cc");
+ }
+ /**
+ * Get an array of addresses in the Cc: field
+ * The array contains Swift_Address objects
+ * @return array
+ */
+ public function getCc()
+ {
+ return $this->cc;
+ }
+ /**
+ * Remove a Cc: recipient from the list
+ * @param mixed The address to remove. Can be Swift_Address or a string
+ */
+ public function removeCc($address)
+ {
+ $this->remove($address, "cc");
+ }
+ /**
+ * Empty all Cc: addresses
+ */
+ public function flushCc()
+ {
+ $this->cc = null;
+ $this->cc = array();
+ }
+ /**
+ * Add a Bcc: recipient
+ * @param mixed The address to add. Can be a string or Swift_Address
+ * @param string The personal name, optional
+ */
+ public function addBcc($address, $name=null)
+ {
+ $this->add($address, $name, "bcc");
+ }
+ /**
+ * Get an array of addresses in the Bcc: field
+ * The array contains Swift_Address objects
+ * @return array
+ */
+ public function getBcc()
+ {
+ return $this->bcc;
+ }
+ /**
+ * Remove a Bcc: recipient from the list
+ * @param mixed The address to remove. Can be Swift_Address or a string
+ */
+ public function removeBcc($address)
+ {
+ $this->remove($address, "bcc");
+ }
+ /**
+ * Empty all Bcc: addresses
+ */
+ public function flushBcc()
+ {
+ $this->bcc = null;
+ $this->bcc = array();
+ }
+ /**
+ * Empty the entire list
+ */
+ public function flush()
+ {
+ $this->flushTo();
+ $this->flushCc();
+ $this->flushBcc();
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift/RecipientList.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/swift_lib/Swift.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/swift_lib/Swift.php 2008-11-18 13:54:25 UTC (rev 11209)
@@ -0,0 +1,489 @@
+<?php
+
+/**
+ * Swift Mailer Core Component.
+ * Please read the LICENSE file
+ * @copyright Chris Corbyn <chris(a)w3style.co.uk>
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @package Swift
+ * @version 3.3.2
+ * @license GNU Lesser General Public License
+ */
+
+require_once dirname(__FILE__) . "/Swift/ClassLoader.php";
+Swift_ClassLoader::load("Swift_LogContainer");
+Swift_ClassLoader::load("Swift_ConnectionBase");
+Swift_ClassLoader::load("Swift_BadResponseException");
+Swift_ClassLoader::load("Swift_Cache");
+Swift_ClassLoader::load("Swift_CacheFactory");
+Swift_ClassLoader::load("Swift_Message");
+Swift_ClassLoader::load("Swift_RecipientList");
+Swift_ClassLoader::load("Swift_BatchMailer");
+Swift_ClassLoader::load("Swift_Events");
+Swift_ClassLoader::load("Swift_Events_Listener");
+
+/**
+ * Swift is the central component in the Swift library.
+ * @package Swift
+ * @author Chris Corbyn <chris(a)w3style.co.uk>
+ * @version 3.3.2
+ */
+class Swift
+{
+ /**
+ * The version number.
+ */
+ const VERSION = "3.3.2";
+ /**
+ * Constant to flag Swift not to try and connect upon instantiation
+ */
+ const NO_START = 2;
+ /**
+ * Constant to tell Swift not to perform the standard SMTP handshake upon connect
+ */
+ const NO_HANDSHAKE = 4;
+ /**
+ * Constant to ask Swift to start logging
+ */
+ const ENABLE_LOGGING = 8;
+ /**
+ * Constant to prevent postConnect() being run in the connection
+ */
+ const NO_POST_CONNECT = 16;
+ /**
+ * The connection object currently active
+ * @var Swift_Connection
+ */
+ public $connection = null;
+ /**
+ * The domain name of this server (should technically be a FQDN)
+ * @var string
+ */
+ protected $domain = null;
+ /**
+ * Flags to change the behaviour of Swift
+ * @var int
+ */
+ protected $options;
+ /**
+ * Loaded plugins, separated into containers according to roles
+ * @var array
+ */
+ protected $listeners = array();
+
+ /**
+ * Constructor
+ * @param Swift_Connection The connection object to deal with I/O
+ * @param string The domain name of this server (the client) as a FQDN
+ * @param int Optional flags
+ * @throws Swift_ConnectionException If a connection cannot be established or the connection is behaving incorrectly
+ */
+ public function __construct(Swift_Connection $conn, $domain=false, $options=null)
+ {
+ $this->initializeEventListenerContainer();
+ $this->setOptions($options);
+
+ $log = Swift_LogContainer::getLog();
+
+ if ($this->hasOption(self::ENABLE_LOGGING) && !$log->isEnabled())
+ {
+ $log->setLogLevel(Swift_Log::LOG_NETWORK);
+ }
+
+ if (!$domain) $domain = !empty($_SERVER["SERVER_ADDR"]) ? "[" . $_SERVER["SERVER_ADDR"] . "]" : "localhost.localdomain";
+
+ $this->setDomain($domain);
+ $this->connection = $conn;
+
+ if ($conn && !$this->hasOption(self::NO_START))
+ {
+ if ($log->hasLevel(Swift_Log::LOG_EVERYTHING)) $log->add("Trying to connect...", Swift_Log::NORMAL);
+ $this->connect();
+ }
+ }
+ /**
+ * Populate the listeners array with the defined listeners ready for plugins
+ */
+ protected function initializeEventListenerContainer()
+ {
+ Swift_ClassLoader::load("Swift_Events_ListenerMapper");
+ foreach (Swift_Events_ListenerMapper::getMap() as $interface => $method)
+ {
+ if (!isset($this->listeners[$interface]))
+ $this->listeners[$interface] = array();
+ }
+ }
+ /**
+ * Add a new plugin to Swift
+ * Plugins must implement one or more event listeners
+ * @param Swift_Events_Listener The plugin to load
+ */
+ public function attachPlugin(Swift_Events_Listener $plugin, $id)
+ {
+ foreach (array_keys($this->listeners) as $key)
+ {
+ $listener = "Swift_Events_" . $key;
+ Swift_ClassLoader::load($listener);
+ if ($plugin instanceof $listener) $this->listeners[$key][$id] = $plugin;
+ }
+ }
+ /**
+ * Get an attached plugin if it exists
+ * @param string The id of the plugin
+ * @return Swift_Event_Listener
+ */
+ public function getPlugin($id)
+ {
+ foreach ($this->listeners as $type => $arr)
+ {
+ if (isset($arr[$id])) return $this->listeners[$type][$id];
+ }
+ return null; //If none found
+ }
+ /**
+ * Remove a plugin attached under the ID of $id
+ * @param string The ID of the plugin
+ */
+ public function removePlugin($id)
+ {
+ foreach ($this->listeners as $type => $arr)
+ {
+ if (isset($arr[$id]))
+ {
+ $this->listeners[$type][$id] = null;
+ unset($this->listeners[$type][$id]);
+ }
+ }
+ }
+ /**
+ * Send a new type of event to all objects which are listening for it
+ * @param Swift_Events The event to send
+ * @param string The type of event
+ */
+ public function notifyListeners($e, $type)
+ {
+ Swift_ClassLoader::load("Swift_Events_ListenerMapper");
+ if (!empty($this->listeners[$type]) && $notifyMethod = Swift_Events_ListenerMapper::getNotifyMethod($type))
+ {
+ $e->setSwift($this);
+ foreach ($this->listeners[$type] as $k => $listener)
+ {
+ $listener->$notifyMethod($e);
+ }
+ }
+ else $e = null;
+ }
+ /**
+ * Check if an option flag has been set
+ * @param string Option name
+ * @return boolean
+ */
+ public function hasOption($option)
+ {
+ return ($this->options & $option);
+ }
+ /**
+ * Adjust the options flags
+ * E.g. $obj->setOptions(Swift::NO_START | Swift::NO_HANDSHAKE)
+ * @param int The bits to set
+ */
+ public function setOptions($options)
+ {
+ $this->options = (int) $options;
+ }
+ /**
+ * Get the current options set (as bits)
+ * @return int
+ */
+ public function getOptions()
+ {
+ return (int) $this->options;
+ }
+ /**
+ * Set the FQDN of this server as it will identify itself
+ * @param string The FQDN of the server
+ */
+ public function setDomain($name)
+ {
+ $this->domain = (string) $name;
+ }
+ /**
+ * Attempt to establish a connection with the service
+ * @throws Swift_ConnectionException If the connection cannot be established or behaves oddly
+ */
+ public function connect()
+ {
+ $this->connection->start();
+ $greeting = $this->command("", 220);
+ if (!$this->hasOption(self::NO_HANDSHAKE))
+ {
+ $this->handshake($greeting);
+ }
+ Swift_ClassLoader::load("Swift_Events_ConnectEvent");
+ $this->notifyListeners(new Swift_Events_ConnectEvent($this->connection), "ConnectListener");
+ }
+ /**
+ * Disconnect from the MTA
+ * @throws Swift_ConnectionException If the connection will not stop
+ */
+ public function disconnect()
+ {
+ $this->command("QUIT");
+ $this->connection->stop();
+ Swift_ClassLoader::load("Swift_Events_DisconnectEvent");
+ $this->notifyListeners(new Swift_Events_DisconnectEvent($this->connection), "DisconnectListener");
+ }
+ /**
+ * Throws an exception if the response code wanted does not match the one returned
+ * @param Swift_Event_ResponseEvent The full response from the service
+ * @param int The 3 digit response code wanted
+ * @throws Swift_BadResponseException If the code does not match
+ */
+ protected function assertCorrectResponse(Swift_Events_ResponseEvent $response, $codes)
+ {
+ $codes = (array)$codes;
+ if (!in_array($response->getCode(), $codes))
+ {
+ $log = Swift_LogContainer::getLog();
+ $error = "Expected response code(s) [" . implode(", ", $codes) . "] but got response [" . $response->getString() . "]";
+ if ($log->hasLevel(Swift_Log::LOG_ERRORS)) $log->add($error, Swift_Log::ERROR);
+ throw new Swift_BadResponseException($error);
+ }
+ }
+ /**
+ * Have a polite greeting with the server and work out what it's capable of
+ * @param Swift_Events_ResponseEvent The initial service line respoonse
+ * @throws Swift_ConnectionException If conversation is not going very well
+ */
+ protected function handshake(Swift_Events_ResponseEvent $greeting)
+ {
+ if ($this->connection->getRequiresEHLO() || strpos($greeting->getString(), "ESMTP"))
+ $this->setConnectionExtensions($this->command("EHLO " . $this->domain, 250));
+ else $this->command("HELO " . $this->domain, 250);
+ //Connection might want to do something like authenticate now
+ if (!$this->hasOption(self::NO_POST_CONNECT)) $this->connection->postConnect($this);
+ }
+ /**
+ * Set the extensions which the service reports in the connection object
+ * @param Swift_Events_ResponseEvent The list of extensions as reported by the service
+ */
+ protected function setConnectionExtensions(Swift_Events_ResponseEvent $list)
+ {
+ $le = (strpos($list->getString(), "\r\n") !== false) ? "\r\n" : "\n";
+ $list = explode($le, $list->getString());
+ for ($i = 1, $len = count($list); $i < $len; $i++)
+ {
+ $extension = substr($list[$i], 4);
+ $attributes = split("[ =]", $extension);
+ $this->connection->setExtension($attributes[0], (isset($attributes[1]) ? array_slice($attributes, 1) : array()));
+ }
+ }
+ /**
+ * Execute a command against the service and get the response
+ * @param string The command to execute (leave off any CRLF!!!)
+ * @param int The code to check for in the response, if any. -1 indicates that no response is wanted.
+ * @return Swift_Events_ResponseEvent The server's response (could be multiple lines)
+ * @throws Swift_ConnectionException If a code was expected but does not match the one returned
+ */
+ public function command($command, $code=null)
+ {
+ $log = Swift_LogContainer::getLog();
+ Swift_ClassLoader::load("Swift_Events_CommandEvent");
+ if ($command !== "")
+ {
+ $command_event = new Swift_Events_CommandEvent($command, $code);
+ $command = null; //For memory reasons
+ $this->notifyListeners($command_event, "BeforeCommandListener");
+ if ($log->hasLevel(Swift_Log::LOG_NETWORK) && $code != -1) $log->add($command_event->getString(), Swift_Log::COMMAND);
+ $end = ($code != -1) ? "\r\n" : null;
+ $this->connection->write($command_event->getString(), $end);
+ $this->notifyListeners($command_event, "CommandListener");
+ }
+
+ if ($code == -1) return null;
+
+ Swift_ClassLoader::load("Swift_Events_ResponseEvent");
+ $response_event = new Swift_Events_ResponseEvent($this->connection->read());
+ $this->notifyListeners($response_event, "ResponseListener");
+ if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add($response_event->getString(), Swift_Log::RESPONSE);
+ if ($command !== "" && $command_event->getCode() !== null)
+ $this->assertCorrectResponse($response_event, $command_event->getCode());
+ return $response_event;
+ }
+ /**
+ * Reset a conversation which has gone badly
+ * @throws Swift_ConnectionException If the service refuses to reset
+ */
+ public function reset()
+ {
+ $this->command("RSET", 250);
+ }
+ /**
+ * Send a message to any number of recipients
+ * @param Swift_Message The message to send. This does not need to (and shouldn't really) have any of the recipient headers set.
+ * @param mixed The recipients to send to. Can be a string, Swift_Address or Swift_RecipientList. Note that all addresses apart from Bcc recipients will appear in the message headers
+ * @param mixed The address to send the message from. Can either be a string or an instance of Swift_Address.
+ * @return int The number of successful recipients
+ * @throws Swift_ConnectionException If sending fails for any reason.
+ */
+ public function send(Swift_Message $message, $recipients, $from)
+ {
+ Swift_ClassLoader::load("Swift_Message_Encoder");
+ if (is_string($recipients) && preg_match("/^" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . "\$/", $recipients))
+ {
+ $recipients = new Swift_Address($recipients);
+ }
+ elseif (!($recipients instanceof Swift_AddressContainer))
+ throw new Exception("The recipients parameter must either be a valid string email address, ".
+ "an instance of Swift_RecipientList or an instance of Swift_Address.");
+
+ if (is_string($from) && preg_match("/^" . Swift_Message_Encoder::CHEAP_ADDRESS_RE . "\$/", $from))
+ {
+ $from = new Swift_Address($from);
+ }
+ elseif (!($from instanceof Swift_Address))
+ throw new Exception("The sender parameter must either be a valid string email address or ".
+ "an instance of Swift_Address.");
+
+ $log = Swift_LogContainer::getLog();
+
+ if (!$message->getEncoding() && !$this->connection->hasExtension("8BITMIME"))
+ {
+ $message->setEncoding("QP", true, true);
+ }
+
+ $list = $recipients;
+ if ($recipients instanceof Swift_Address)
+ {
+ $list = new Swift_RecipientList();
+ $list->addTo($recipients);
+ }
+
+ Swift_ClassLoader::load("Swift_Events_SendEvent");
+ $send_event = new Swift_Events_SendEvent($message, $list, $from, 0);
+
+ $this->notifyListeners($send_event, "BeforeSendListener");
+
+ $to = $cc = array();
+ if (!($has_from = $message->getFrom())) $message->setFrom($from);
+ if (!($has_return_path = $message->getReturnPath())) $message->setReturnPath($from->build(true));
+ if (!($has_reply_to = $message->getReplyTo())) $message->setReplyTo($from);
+ if (!($has_message_id = $message->getId())) $message->generateId();
+
+ $this->command("MAIL FROM: " . $message->getReturnPath(true), 250);
+
+ $failed = 0;
+ $sent = 0;
+ $tmp_sent = 0;
+
+ $it = $list->getIterator("to");
+ while ($it->hasNext())
+ {
+ $it->next();
+ $address = $it->getValue();
+ $to[] = $address->build();
+ try {
+ $this->command("RCPT TO: " . $address->build(true), 250);
+ $tmp_sent++;
+ } catch (Swift_BadResponseException $e) {
+ $failed++;
+ $send_event->addFailedRecipient($address->getAddress());
+ if ($log->hasLevel(Swift_Log::LOG_FAILURES)) $log->addfailedRecipient($address->getAddress());
+ }
+ }
+ $it = $list->getIterator("cc");
+ while ($it->hasNext())
+ {
+ $it->next();
+ $address = $it->getValue();
+ $cc[] = $address->build();
+ try {
+ $this->command("RCPT TO: " . $address->build(true), 250);
+ $tmp_sent++;
+ } catch (Swift_BadResponseException $e) {
+ $failed++;
+ $send_event->addFailedRecipient($address->getAddress());
+ if ($log->hasLevel(Swift_Log::LOG_FAILURES)) $log->addfailedRecipient($address->getAddress());
+ }
+ }
+
+ if ($failed == (count($to) + count($cc)))
+ {
+ $this->reset();
+ $this->notifyListeners($send_event, "SendListener");
+ return 0;
+ }
+
+ if (!($has_to = $message->getTo()) && !empty($to)) $message->setTo($to);
+ if (!($has_cc = $message->getCc()) && !empty($cc)) $message->setCc($cc);
+
+ $this->command("DATA", 354);
+ $data = $message->build();
+
+ while (false !== $bytes = $data->read())
+ $this->command($bytes, -1);
+ if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add("<MESSAGE DATA>", Swift_Log::COMMAND);
+ try {
+ $this->command("\r\n.", 250);
+ $sent += $tmp_sent;
+ } catch (Swift_BadResponseException $e) {
+ $failed += $tmp_sent;
+ }
+
+ $tmp_sent = 0;
+ $has_bcc = $message->getBcc();
+ $it = $list->getIterator("bcc");
+ while ($it->hasNext())
+ {
+ $it->next();
+ $address = $it->getValue();
+ if (!$has_bcc) $message->setBcc($address->build());
+ try {
+ $this->command("MAIL FROM: " . $message->getReturnPath(true), 250);
+ $this->command("RCPT TO: " . $address->build(true), 250);
+ $this->command("DATA", 354);
+ $data = $message->build();
+ while (false !== $bytes = $data->read())
+ $this->command($bytes, -1);
+ if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add("<MESSAGE DATA>", Swift_Log::COMMAND);
+ $this->command("\r\n.", 250);
+ $sent++;
+ } catch (Swift_BadResponseException $e) {
+ $failed++;
+ $send_event->addFailedRecipient($address->getAddress());
+ if ($log->hasLevel(Swift_Log::LOG_FAILURES)) $log->addfailedRecipient($address->getAddress());
+ $this->reset();
+ }
+ }
+
+ $total = count($to) + count($cc) + count($list->getBcc());
+
+ $send_event->setNumSent($sent);
+ $this->notifyListeners($send_event, "SendListener");
+
+ if (!$has_return_path) $message->setReturnPath("");
+ if (!$has_from) $message->setFrom("");
+ if (!$has_to) $message->setTo("");
+ if (!$has_reply_to) $message->setReplyTo(null);
+ if (!$has_cc) $message->setCc(null);
+ if (!$has_bcc) $message->setBcc(null);
+ if (!$has_message_id) $message->setId(null);
+
+ if ($log->hasLevel(Swift_Log::LOG_NETWORK)) $log->add("Message sent to " . $sent . "/" . $total . " recipients", Swift_Log::NORMAL);
+
+ return $sent;
+ }
+ /**
+ * Send a message to a batch of recipients.
+ * Unlike send() this method ignores Cc and Bcc recipients and does not reveal every recipients' address in the headers
+ * @param Swift_Message The message to send (leave out the recipient headers unless you are deliberately overriding them)
+ * @param Swift_RecipientList The addresses to send to
+ * @param Swift_Address The address the mail is from (sender)
+ * @return int The number of successful recipients
+ */
+ public function batchSend(Swift_Message $message, Swift_RecipientList $to, $from)
+ {
+ $batch = new Swift_BatchMailer($this);
+ return $batch->send($message, $to, $from);
+ }
+}
Property changes on: trunk/docs/common-resources/en/src/main/script/swift_lib/Swift.php
___________________________________________________________________
Name: svn:executable
+ *
Modified: trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl 2008-11-18 13:47:17 UTC (rev 11208)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl 2008-11-18 13:54:25 UTC (rev 11209)
@@ -69,13 +69,6 @@
</xsl:template>
<xsl:template match="abstract" mode="titlepage.mode">
- <div id="timestamp">
- <xsl:text>Last published: </xsl:text>
- <xsl:call-template name="datetime.format">
- <xsl:with-param name="date" select="date:date-time()"/>
- <xsl:with-param name="format" select="'B d, Y'"/>
- </xsl:call-template>
- </div>
<div>
<xsl:apply-templates select="." mode="class.attribute"/>
<xsl:apply-templates mode="titlepage.mode"/>
Modified: trunk/docs/faq/pom.xml
===================================================================
--- trunk/docs/faq/pom.xml 2008-11-18 13:47:17 UTC (rev 11208)
+++ trunk/docs/faq/pom.xml 2008-11-18 13:54:25 UTC (rev 11209)
@@ -29,7 +29,45 @@
<build>
<pluginManagement>
<plugins>
-
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>
+ org.richfaces.docs.common-resources
+ </groupId>
+ <artifactId>
+ ${project.translation}
+ </artifactId>
+ <version>
+ ${project.version}
+ </version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>
+ ${project.build.directory}
+ </outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ <overWriteReleases>
+ false
+ </overWriteReleases>
+ <overWriteSnapshots>
+ true
+ </overWriteSnapshots>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-jdocbook-plugin</artifactId>
@@ -69,6 +107,12 @@
<version>1.1.0-SNAPSHOT</version>
<type>jdocbook-style</type>
</dependency>
+ <dependency>
+ <groupId>org.richfaces.docs.common-resources</groupId>
+ <artifactId>${translation}</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ </dependency>
</dependencies>
<configuration>
<sourceDirectory>
@@ -81,7 +125,7 @@
</imageResource>
<cssResource>
<directory>
- ${basedir}/src/main/resources
+ ${project.build.directory}/common-resources
</directory>
</cssResource>
<sourceDocumentName>
@@ -118,7 +162,7 @@
<format>
<formatName>html_single</formatName>
<stylesheetResource>
- file:${pom.basedir}/src/main/resources/xslt/org/jboss/richfaces/xhtml-single.xsl
+ ${xsl_html_single}
</stylesheetResource>
<imageCopyingRequired>
true
17 years, 6 months
JBoss Rich Faces SVN: r11208 - in trunk/docs/userguide: en/src/main/resources and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2008-11-18 08:47:17 -0500 (Tue, 18 Nov 2008)
New Revision: 11208
Removed:
trunk/docs/userguide/en/src/main/resources/css/
trunk/docs/userguide/en/src/main/resources/images/bg_table.gif
trunk/docs/userguide/en/src/main/resources/images/favicon.ico
trunk/docs/userguide/en/src/main/resources/images/new.png
trunk/docs/userguide/en/src/main/resources/images/richfaces_label2.png
trunk/docs/userguide/en/src/main/resources/images/updated.png
trunk/docs/userguide/en/src/main/resources/script/
trunk/docs/userguide/en/src/main/resources/xslt/
Modified:
trunk/docs/userguide/pom.xml
Log:
https://jira.jboss.org/jira/browse/RF-4107 - one resources folder was added
Deleted: trunk/docs/userguide/en/src/main/resources/images/bg_table.gif
===================================================================
(Binary files differ)
Deleted: trunk/docs/userguide/en/src/main/resources/images/favicon.ico
===================================================================
(Binary files differ)
Deleted: trunk/docs/userguide/en/src/main/resources/images/new.png
===================================================================
(Binary files differ)
Deleted: trunk/docs/userguide/en/src/main/resources/images/richfaces_label2.png
===================================================================
(Binary files differ)
Deleted: trunk/docs/userguide/en/src/main/resources/images/updated.png
===================================================================
(Binary files differ)
Modified: trunk/docs/userguide/pom.xml
===================================================================
--- trunk/docs/userguide/pom.xml 2008-11-18 13:44:22 UTC (rev 11207)
+++ trunk/docs/userguide/pom.xml 2008-11-18 13:47:17 UTC (rev 11208)
@@ -576,10 +576,10 @@
<artifactItem>
<groupId>
- org.richfaces.docs.xslt
+ org.richfaces.docs.common-resources
</groupId>
<artifactId>
- ${translation}
+ ${project.translation}
</artifactId>
<version>
${project.version}
@@ -587,7 +587,7 @@
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>
- ${project.build.directory}/xslt
+ ${project.build.directory}
</outputDirectory>
</artifactItem>
<artifactItem>
@@ -654,7 +654,7 @@
${project.build.directory}/generated/
</outputDir>
<stylesheet>
- ${project.build.directory}/xslt/xslt/f.xsl
+ ${project.build.directory}/common-resources/xslt/f.xsl
</stylesheet>
<fileMappers>
<fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
@@ -698,7 +698,7 @@
${project.build.directory}/generated/
</outputDir>
<stylesheet>
- ${project.build.directory}/xslt/xslt/f.xsl
+ ${project.build.directory}/common-resources/xslt/f.xsl
</stylesheet>
<fileMappers>
<fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
@@ -771,6 +771,12 @@
<version>1.1.0</version>
<type>jdocbook-style</type>
</dependency>
+ <dependency>
+ <groupId>org.richfaces.docs.common-resources</groupId>
+ <artifactId>${translation}</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ </dependency>
<!--dependency>
<groupId>org.richfaces.docs.xslt</groupId>
<artifactId>${translation}</artifactId>
@@ -794,7 +800,7 @@
</imageResource>
<cssResource>
<directory>
- ${basedir}/src/main/resources
+ ${project.build.directory}/common-resources
</directory>
</cssResource>
<sourceDocumentName>
@@ -802,7 +808,7 @@
</sourceDocumentName>
<formats>
- <format>
+ <!--format>
<formatName>pdf</formatName>
<stylesheetResource>
classpath:/xslt/org/jboss/pdf.xsl
@@ -813,11 +819,11 @@
<imagePathSettingRequired>
true
</imagePathSettingRequired>
- </format>
+ </format-->
<format>
<formatName>html</formatName>
<stylesheetResource>
- file:${pom.basedir}/src/main/resources/xslt/org/jboss/richfaces/xhtml.xsl
+ ${xsl_html}
</stylesheetResource>
<finalName>index.html</finalName>
<imageCopyingRequired>
@@ -828,10 +834,10 @@
</imagePathSettingRequired>
</format>
- <format>
+ <!--format>
<formatName>html_single</formatName>
<stylesheetResource>
- file:${pom.basedir}/src/main/resources/xslt/org/jboss/richfaces/xhtml-single.xsl
+ ${xsl_html_single}
</stylesheetResource>
<imageCopyingRequired>
true
@@ -842,8 +848,7 @@
<finalName>
index.html
</finalName>
-
- </format>
+ </format-->
</formats>
<xincludeSupported>true</xincludeSupported>
<options>
17 years, 6 months
JBoss Rich Faces SVN: r11207 - in trunk/docs/migrationguide: en/src/main and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2008-11-18 08:44:22 -0500 (Tue, 18 Nov 2008)
New Revision: 11207
Removed:
trunk/docs/migrationguide/en/src/main/resources/
Modified:
trunk/docs/migrationguide/pom.xml
Log:
https://jira.jboss.org/jira/browse/RF-4107 - one resources folder was added
Modified: trunk/docs/migrationguide/pom.xml
===================================================================
--- trunk/docs/migrationguide/pom.xml 2008-11-18 13:07:37 UTC (rev 11206)
+++ trunk/docs/migrationguide/pom.xml 2008-11-18 13:44:22 UTC (rev 11207)
@@ -30,6 +30,45 @@
<pluginManagement>
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>
+ org.richfaces.docs.common-resources
+ </groupId>
+ <artifactId>
+ ${project.translation}
+ </artifactId>
+ <version>
+ ${project.version}
+ </version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>
+ ${project.build.directory}
+ </outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ <overWriteReleases>
+ false
+ </overWriteReleases>
+ <overWriteSnapshots>
+ true
+ </overWriteSnapshots>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-jdocbook-plugin</artifactId>
<version>2.1.0-200803311251UTC-MPJDOCBOOK-8</version>
@@ -68,14 +107,26 @@
<version>1.1.0-SNAPSHOT</version>
<type>jdocbook-style</type>
</dependency>
+ <dependency>
+ <groupId>org.richfaces.docs.common-resources</groupId>
+ <artifactId>${translation}</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ </dependency>
</dependencies>
<configuration>
- <sourceDirectory> ${basedir}/src/main/docbook </sourceDirectory>
+ <sourceDirectory>
+ ${basedir}/src/main/docbook
+ </sourceDirectory>
<imageResource>
- <directory> ${basedir}/src/main/resources </directory>
+ <directory>
+ ${project.build.directory}/common-resources
+ </directory>
</imageResource>
<cssResource>
- <directory> ${basedir}/src/main/resources </directory>
+ <directory>
+ ${project.build.directory}/common-resources
+ </directory>
</cssResource>
<sourceDocumentName>master.xml</sourceDocumentName>
<formats>
@@ -88,7 +139,7 @@
<format>
<formatName>html</formatName>
<stylesheetResource>
- file:${pom.basedir}/src/main/resources/xslt/org/jboss/richfaces/xhtml.xsl
+ ${xsl_html}
</stylesheetResource>
<finalName>index.html</finalName>
<imageCopyingRequired>
@@ -100,7 +151,9 @@
</format>
<format>
<formatName>html_single</formatName>
- <stylesheetResource>file:${pom.basedir}/src/main/resources/xslt/org/jboss/richfaces/xhtml-single.xsl</stylesheetResource>
+ <stylesheetResource>
+ ${xsl_html_single}
+ </stylesheetResource>
<imageCopyingRequired>true</imageCopyingRequired>
<imagePathSettingRequired>false</imagePathSettingRequired>
<finalName>index.html </finalName>
17 years, 6 months
JBoss Rich Faces SVN: r11206 - in trunk/docs: common-resources and 7 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2008-11-18 08:07:37 -0500 (Tue, 18 Nov 2008)
New Revision: 11206
Added:
trunk/docs/common-resources/
trunk/docs/common-resources/en/
trunk/docs/common-resources/en/src/
trunk/docs/common-resources/en/src/main/
trunk/docs/common-resources/en/src/main/css/
trunk/docs/common-resources/en/src/main/css/html-release.css
trunk/docs/common-resources/en/src/main/css/html.css
trunk/docs/common-resources/en/src/main/images/
trunk/docs/common-resources/en/src/main/images/close.png
trunk/docs/common-resources/en/src/main/images/favicon.ico
trunk/docs/common-resources/en/src/main/images/feedback_logo.png
trunk/docs/common-resources/en/src/main/images/ico_important.gif
trunk/docs/common-resources/en/src/main/images/ico_note.gif
trunk/docs/common-resources/en/src/main/images/ico_tip.gif
trunk/docs/common-resources/en/src/main/images/new.png
trunk/docs/common-resources/en/src/main/images/richfaces_label2.png
trunk/docs/common-resources/en/src/main/images/updated.png
trunk/docs/common-resources/en/src/main/script/
trunk/docs/common-resources/en/src/main/script/effects.js
trunk/docs/common-resources/en/src/main/script/prototype-1.6.0.2.js
trunk/docs/common-resources/en/src/main/script/scriptaculous.js
trunk/docs/common-resources/en/src/main/script/send_mail.php
trunk/docs/common-resources/en/src/main/script/toggle.js
trunk/docs/common-resources/en/src/main/xslt/
trunk/docs/common-resources/en/src/main/xslt/collapsing-navigation.xsl
trunk/docs/common-resources/en/src/main/xslt/f.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml-common.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml-diffmk.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml-release.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml-single-diffmk.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml-single-release.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml-single.xsl
trunk/docs/common-resources/en/src/main/xslt/xhtml.xsl
trunk/docs/common-resources/pom.xml
Log:
https://jira.jboss.org/jira/browse/RF-4107 - one resources folder was added
Added: trunk/docs/common-resources/en/src/main/css/html-release.css
===================================================================
--- trunk/docs/common-resources/en/src/main/css/html-release.css (rev 0)
+++ trunk/docs/common-resources/en/src/main/css/html-release.css 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,265 @@
+@import url("jbossorg.css");
+
+.expand_collapse_toc {
+ float:left;
+ width:20px;
+ color:#6699CC;
+ cursor:pointer;
+}
+
+.toc dl dt span.chapter{
+ margin: 0px 0px 0px 20px;
+ padding: 0px;
+}
+
+body {
+background-image:url(../images/community/bkg_gradient.gif);
+background-repeat:repeat-x;
+z-index:1;
+color:#333333;
+font-family:'Lucida Grande',Geneva,Verdana,Arial,sans-serif;
+font-size:12px;
+line-height:150%;
+max-width:1000px;
+padding:0em 2em;
+text-align:center;
+}
+
+div.book, div.chapter, div.section{
+ width:1000px;
+ margin:0 auto;
+ text-align:justify;
+ font-weight: 100;
+}
+
+div.abstract {
+font-size:10px;
+}
+
+.docnav li.previous strong, .docnav li.next strong {
+ width: 200px;
+ height:22px;
+}
+
+.docnav a:hover {
+ cursor:pointer;
+}
+th, td {
+ border: 1px solid #AAAAAA;
+}
+#title, ul.docnav{
+ margin:0 auto;
+ width:1000px;
+ margin-left:0px;
+}
+
+/* Center all images and Figure/Table titles */
+div.mediaobject img {margin:left;}
+
+p.title {
+ text-align:left;
+ font-size: 11px;
+}
+
+.css_normal {
+line-height:0px;
+color:#000000;
+}
+.css_colon {
+color:#000000;
+}
+.css_semi_colon {
+color:#000000;
+}
+.css_curly_brace {
+color:#000000;
+}
+.css_comment {
+color:#3F5FBF;
+background-color:rgb(247,247,247);
+}
+.css_error {
+color:#BF3F3F;
+}
+.css_selector {
+color:#3F7F7F;
+}
+.css_null {
+color:rgb(0,0,0);
+}
+.css_property_name {
+font-weight:bold;
+color:#7F007F;
+}
+.css_property_value {
+color:#2A00FF;
+}
+.css_uri {
+color:#2A00FF;
+}
+.css_atmark_rule {
+color:#3F7F7F;
+}
+.css_media {
+color:#2A00FF;
+}
+.css_string {
+color:#2A00FF;
+}
+code.code{
+color:#000000;
+font-size:14px;
+font-family:monospace;
+}
+a.new {
+background:transparent url(../images/new.png) no-repeat scroll right top;
+padding-right:70px;
+}
+a.updated {
+background:transparent url(../images/updated.png) no-repeat scroll right top;
+padding-right:70px;
+}
+.tbi {color: #aaaaaa;}
+.tbi p {color: #333333;}
+
+div.note, div.tip, div.important{
+ height:100%;
+}
+
+pre.JAVA {
+line-height:10px;
+!line-height:15px;
+}
+pre.CSS {
+line-height:10px;
+!line-height:15px;
+}
+div.table-contents table{
+ font-size:12px;
+}
+
+/* Feedback styles */
+
+* html div#feedback-wrapper {position: absolute;
+top:expression(eval(document.compatMode &&
+document.compatMode=='CSS1Compat') ?
+documentElement.scrollTop
++(documentElement.clientHeight-this.clientHeight)
+: document.body.scrollTop
++(document.body.clientHeight-this.clientHeight));}
+
+* html #feedback-maincontainer {position: absolute;
+top:expression(eval(document.compatMode &&
+document.compatMode=='CSS1Compat') ?
+documentElement.scrollTop
++(documentElement.clientHeight-this.clientHeight)
+: document.body.scrollTop
++(document.body.clientHeight-this.clientHeight));}
+
+#feedback-wrapper{
+ margin: 0px;
+ padding: 0px;
+ position:fixed;
+ bottom:0px;
+ right:0px;
+ height:322px;
+ width: 100px;
+ overflow: hidden;
+}
+
+#feedback-link{
+ float: left;
+ display: block;
+}
+
+
+#feedback-header{
+ background-color: #AAB3BD;
+ text-align: center;
+ color: white;
+ width: 100%;
+ font-weight: bold;
+ position: relative;
+ height: 20px;
+ padding: 0px;
+ margin:0px;
+}
+
+#feedback-close{
+ display:block;
+ position:absolute;
+ right:2px;
+ top:2px;
+ width:12px;
+ border: 0px;
+}
+
+#feedback-state{
+ font-weight: bold;
+ height: 20px;
+ width: 508px;
+ line-height: 20px;
+ overflow: hidden;
+}
+
+#feedback-maincontainer{
+ z-index:2000;
+ text-align: center;
+ background: #F5F5F5;
+ border: 1px solid #CCC;
+ position: fixed;
+ bottom: 0px;
+ right: 120px;
+}
+*html #feedback-maincontainer{
+ width: 520px;
+}
+
+#feedback-mailform{
+ margin: 0px 20px 0px 20px;
+ padding-bottom:5px;
+}
+
+*html #feedback-mailform{
+ margin: 0px 20px 0px 0px;
+ padding-bottom:5px;
+}
+
+.feedback-textbox-div{
+ font-weight: bold;
+ margin-bottom:5px;
+ text-align: right;
+ color: #415973;
+}
+
+#message{
+ width: 200px;
+ height: 150px;
+ padding: 2px;
+}
+
+.feedback-formbutton{
+ font-size: 12px;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #415973;
+}
+
+.feedback-textbox, #message{
+ background-color:#FFFFFF;
+ border:1px solid #A5ACB2;
+ padding:2px 1px 3px 5px;
+ width: 400px;
+ font-size: 12px;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #000;
+}
+
+.feedback-button-container{
+ margin: 0px 5px 0px 0px;
+}
+
+.feedback-images{
+ border:0;
+ margin:0;
+ display: inline;
+}
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/css/html-release.css
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/css/html.css
===================================================================
--- trunk/docs/common-resources/en/src/main/css/html.css (rev 0)
+++ trunk/docs/common-resources/en/src/main/css/html.css 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,277 @@
+@import url("jbossorg.css");
+
+.expand_collapse_toc {
+ float:left;
+ width:20px;
+ color:#6699CC;
+ cursor:pointer;
+}
+
+.toc dl dt span.chapter{
+ margin: 0px 0px 0px 20px;
+ padding: 0px;
+}
+
+body {
+background-image:url(../images/richfaces_label2.png);
+background-repeat:no-repeat;
+background-attachment:fixed;
+background-position:top left;
+z-index:1;
+color:#333333;
+font-family:'Lucida Grande',Geneva,Verdana,Arial,sans-serif;
+font-size:12px;
+line-height:150%;
+max-width:1000px;
+padding:0em 2em;
+text-align:center;
+}
+
+div#overlay{
+background-image:url(../images/community/bkg_gradient.gif);
+background-repeat:repeat-x;
+width:100%;
+height:100%;
+position:absolute;
+top:0px;
+left:0px;
+z-index:-1;
+}
+div.book, div.chapter, div.section{
+ width:1000px;
+ margin:0 auto;
+ text-align:justify;
+ font-weight: 100;
+}
+
+div.abstract {
+font-size:10px;
+}
+
+.docnav li.previous strong, .docnav li.next strong {
+ width: 200px;
+ height:22px;
+}
+
+.docnav a:hover {
+ cursor:pointer;
+}
+th, td {
+ border: 1px solid #AAAAAA;
+}
+#title, ul.docnav{
+ margin:0 auto;
+ width:1000px;
+ margin-left:0px;
+}
+
+/* Center all images and Figure/Table titles */
+div.mediaobject img {margin:left;}
+
+p.title {
+ text-align:left;
+ font-size: 11px;
+}
+
+.css_normal {
+line-height:0px;
+color:#000000;
+}
+.css_colon {
+color:#000000;
+}
+.css_semi_colon {
+color:#000000;
+}
+.css_curly_brace {
+color:#000000;
+}
+.css_comment {
+color:#3F5FBF;
+background-color:rgb(247,247,247);
+}
+.css_error {
+color:#BF3F3F;
+}
+.css_selector {
+color:#3F7F7F;
+}
+.css_null {
+color:rgb(0,0,0);
+}
+.css_property_name {
+font-weight:bold;
+color:#7F007F;
+}
+.css_property_value {
+color:#2A00FF;
+}
+.css_uri {
+color:#2A00FF;
+}
+.css_atmark_rule {
+color:#3F7F7F;
+}
+.css_media {
+color:#2A00FF;
+}
+.css_string {
+color:#2A00FF;
+}
+code.code{
+color:#000000;
+font-size:14px;
+font-family:monospace;
+}
+a.new {
+background:transparent url(../images/new.png) no-repeat scroll right top;
+padding-right:70px;
+}
+a.updated {
+background:transparent url(../images/updated.png) no-repeat scroll right top;
+padding-right:70px;
+}
+.tbi {color: #aaaaaa;}
+.tbi p {color: #333333;}
+
+div.note, div.tip, div.important{
+ height:100%;
+}
+
+pre.JAVA {
+line-height:10px;
+!line-height:15px;
+}
+pre.CSS {
+line-height:10px;
+!line-height:15px;
+}
+div.table-contents table{
+ font-size:12px;
+}
+
+/* Feedback styles */
+
+* html div#feedback-wrapper {position: absolute;
+top:expression(eval(document.compatMode &&
+document.compatMode=='CSS1Compat') ?
+documentElement.scrollTop
++(documentElement.clientHeight-this.clientHeight)
+: document.body.scrollTop
++(document.body.clientHeight-this.clientHeight));}
+
+* html #feedback-maincontainer {position: absolute;
+top:expression(eval(document.compatMode &&
+document.compatMode=='CSS1Compat') ?
+documentElement.scrollTop
++(documentElement.clientHeight-this.clientHeight)
+: document.body.scrollTop
++(document.body.clientHeight-this.clientHeight));}
+
+#feedback-wrapper{
+ margin: 0px;
+ padding: 0px;
+ position:fixed;
+ bottom:0px;
+ right:0px;
+ height:322px;
+ width: 100px;
+ overflow: hidden;
+}
+
+#feedback-link{
+ float: left;
+ display: block;
+}
+
+
+#feedback-header{
+ background-color: #AAB3BD;
+ text-align: center;
+ color: white;
+ width: 100%;
+ font-weight: bold;
+ position: relative;
+ height: 20px;
+ padding: 0px;
+ margin:0px;
+}
+
+#feedback-close{
+ display:block;
+ position:absolute;
+ right:2px;
+ top:2px;
+ width:12px;
+ border: 0px;
+}
+
+#feedback-state{
+ font-weight: bold;
+ height: 20px;
+ width: 508px;
+ line-height: 20px;
+ overflow: hidden;
+}
+
+#feedback-maincontainer{
+ z-index:2000;
+ text-align: center;
+ background: #F5F5F5;
+ border: 1px solid #CCC;
+ position: fixed;
+ bottom: 0px;
+ right: 120px;
+}
+*html #feedback-maincontainer{
+ width: 520px;
+}
+
+#feedback-mailform{
+ margin: 0px 20px 0px 20px;
+ padding-bottom:5px;
+}
+
+*html #feedback-mailform{
+ margin: 0px 20px 0px 0px;
+ padding-bottom:5px;
+}
+
+.feedback-textbox-div{
+ font-weight: bold;
+ margin-bottom:5px;
+ text-align: right;
+ color: #415973;
+}
+
+#message{
+ width: 200px;
+ height: 150px;
+ padding: 2px;
+}
+
+.feedback-formbutton{
+ font-size: 12px;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #415973;
+}
+
+.feedback-textbox, #message{
+ background-color:#FFFFFF;
+ border:1px solid #A5ACB2;
+ padding:2px 1px 3px 5px;
+ width: 400px;
+ font-size: 12px;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #000;
+}
+
+.feedback-button-container{
+ margin: 0px 5px 0px 0px;
+}
+
+.feedback-images{
+ border:0;
+ margin:0;
+ display: inline;
+}
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/css/html.css
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/images/close.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/close.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/favicon.ico
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/favicon.ico
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/feedback_logo.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/feedback_logo.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/ico_important.gif
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/ico_important.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/ico_note.gif
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/ico_note.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/ico_tip.gif
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/ico_tip.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/new.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/new.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/richfaces_label2.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/richfaces_label2.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/images/updated.png
===================================================================
(Binary files differ)
Property changes on: trunk/docs/common-resources/en/src/main/images/updated.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/common-resources/en/src/main/script/effects.js
===================================================================
--- trunk/docs/common-resources/en/src/main/script/effects.js (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/effects.js 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,1122 @@
+// script.aculo.us effects.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+// Justin Palmer (http://encytemedia.com/)
+// Mark Pilgrim (http://diveintomark.org/)
+// Martin Bialasinki
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
+ var color = '#';
+ if (this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if (this.slice(0,1) == '#') {
+ if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if (this.length==7) color = this.toLowerCase();
+ }
+ }
+ return (color.length==7 ? color : (arguments[0] || this));
+};
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+ }).flatten().join('');
+};
+
+Element.collectTextNodesIgnoreClass = function(element, className) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+ Element.collectTextNodesIgnoreClass(node, className) : ''));
+ }).flatten().join('');
+};
+
+Element.setContentZoom = function(element, percent) {
+ element = $(element);
+ element.setStyle({fontSize: (percent/100) + 'em'});
+ if (Prototype.Browser.WebKit) window.scrollBy(0,0);
+ return element;
+};
+
+Element.getInlineOpacity = function(element){
+ return $(element).style.opacity || '';
+};
+
+Element.forceRerendering = function(element) {
+ try {
+ element = $(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+ _elementDoesNotExistError: {
+ name: 'ElementDoesNotExistError',
+ message: 'The specified DOM element does not exist, but is required for this effect to operate'
+ },
+ Transitions: {
+ linear: Prototype.K,
+ sinoidal: function(pos) {
+ return (-Math.cos(pos*Math.PI)/2) + 0.5;
+ },
+ reverse: function(pos) {
+ return 1-pos;
+ },
+ flicker: function(pos) {
+ var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ return pos > 1 ? 1 : pos;
+ },
+ wobble: function(pos) {
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+ },
+ pulse: function(pos, pulses) {
+ pulses = pulses || 5;
+ return (
+ ((pos % (1/pulses)) * pulses).round() == 0 ?
+ ((pos * pulses * 2) - (pos * pulses * 2).floor()) :
+ 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
+ );
+ },
+ spring: function(pos) {
+ return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
+ },
+ none: function(pos) {
+ return 0;
+ },
+ full: function(pos) {
+ return 1;
+ }
+ },
+ DefaultOptions: {
+ duration: 1.0, // seconds
+ fps: 100, // 100= assume 66fps max.
+ sync: false, // true for combining
+ from: 0.0,
+ to: 1.0,
+ delay: 0.0,
+ queue: 'parallel'
+ },
+ tagifyText: function(element) {
+ var tagifyStyle = 'position:relative';
+ if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
+
+ element = $(element);
+ $A(element.childNodes).each( function(child) {
+ if (child.nodeType==3) {
+ child.nodeValue.toArray().each( function(character) {
+ element.insertBefore(
+ new Element('span', {style: tagifyStyle}).update(
+ character == ' ' ? String.fromCharCode(160) : character),
+ child);
+ });
+ Element.remove(child);
+ }
+ });
+ },
+ multiple: function(element, effect) {
+ var elements;
+ if (((typeof element == 'object') ||
+ Object.isFunction(element)) &&
+ (element.length))
+ elements = element;
+ else
+ elements = $(element).childNodes;
+
+ var options = Object.extend({
+ speed: 0.1,
+ delay: 0.0
+ }, arguments[2] || { });
+ var masterDelay = options.delay;
+
+ $A(elements).each( function(element, index) {
+ new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+ });
+ },
+ PAIRS: {
+ 'slide': ['SlideDown','SlideUp'],
+ 'blind': ['BlindDown','BlindUp'],
+ 'appear': ['Appear','Fade']
+ },
+ toggle: function(element, effect) {
+ element = $(element);
+ effect = (effect || 'appear').toLowerCase();
+ var options = Object.extend({
+ queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+ }, arguments[2] || { });
+ Effect[element.visible() ?
+ Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }
+};
+
+Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create(Enumerable, {
+ initialize: function() {
+ this.effects = [];
+ this.interval = null;
+ },
+ _each: function(iterator) {
+ this.effects._each(iterator);
+ },
+ add: function(effect) {
+ var timestamp = new Date().getTime();
+
+ var position = Object.isString(effect.options.queue) ?
+ effect.options.queue : effect.options.queue.position;
+
+ switch(position) {
+ case 'front':
+ // move unstarted effects after this effect
+ this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
+ e.startOn += effect.finishOn;
+ e.finishOn += effect.finishOn;
+ });
+ break;
+ case 'with-last':
+ timestamp = this.effects.pluck('startOn').max() || timestamp;
+ break;
+ case 'end':
+ // start effect after last queued effect has finished
+ timestamp = this.effects.pluck('finishOn').max() || timestamp;
+ break;
+ }
+
+ effect.startOn += timestamp;
+ effect.finishOn += timestamp;
+
+ if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+ this.effects.push(effect);
+
+ if (!this.interval)
+ this.interval = setInterval(this.loop.bind(this), 15);
+ },
+ remove: function(effect) {
+ this.effects = this.effects.reject(function(e) { return e==effect });
+ if (this.effects.length == 0) {
+ clearInterval(this.interval);
+ this.interval = null;
+ }
+ },
+ loop: function() {
+ var timePos = new Date().getTime();
+ for(var i=0, len=this.effects.length;i<len;i++)
+ this.effects[i] && this.effects[i].loop(timePos);
+ }
+});
+
+Effect.Queues = {
+ instances: $H(),
+ get: function(queueName) {
+ if (!Object.isString(queueName)) return queueName;
+
+ return this.instances.get(queueName) ||
+ this.instances.set(queueName, new Effect.ScopedQueue());
+ }
+};
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.Base = Class.create({
+ position: null,
+ start: function(options) {
+ function codeForEvent(options,eventName){
+ return (
+ (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
+ (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
+ );
+ }
+ if (options && options.transition === false) options.transition = Effect.Transitions.linear;
+ this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
+ this.currentFrame = 0;
+ this.state = 'idle';
+ this.startOn = this.options.delay*1000;
+ this.finishOn = this.startOn+(this.options.duration*1000);
+ this.fromToDelta = this.options.to-this.options.from;
+ this.totalTime = this.finishOn-this.startOn;
+ this.totalFrames = this.options.fps*this.options.duration;
+
+ eval('this.render = function(pos){ '+
+ 'if (this.state=="idle"){this.state="running";'+
+ codeForEvent(this.options,'beforeSetup')+
+ (this.setup ? 'this.setup();':'')+
+ codeForEvent(this.options,'afterSetup')+
+ '};if (this.state=="running"){'+
+ 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
+ 'this.position=pos;'+
+ codeForEvent(this.options,'beforeUpdate')+
+ (this.update ? 'this.update(pos);':'')+
+ codeForEvent(this.options,'afterUpdate')+
+ '}}');
+
+ this.event('beforeStart');
+ if (!this.options.sync)
+ Effect.Queues.get(Object.isString(this.options.queue) ?
+ 'global' : this.options.queue.scope).add(this);
+ },
+ loop: function(timePos) {
+ if (timePos >= this.startOn) {
+ if (timePos >= this.finishOn) {
+ this.render(1.0);
+ this.cancel();
+ this.event('beforeFinish');
+ if (this.finish) this.finish();
+ this.event('afterFinish');
+ return;
+ }
+ var pos = (timePos - this.startOn) / this.totalTime,
+ frame = (pos * this.totalFrames).round();
+ if (frame > this.currentFrame) {
+ this.render(pos);
+ this.currentFrame = frame;
+ }
+ }
+ },
+ cancel: function() {
+ if (!this.options.sync)
+ Effect.Queues.get(Object.isString(this.options.queue) ?
+ 'global' : this.options.queue.scope).remove(this);
+ this.state = 'finished';
+ },
+ event: function(eventName) {
+ if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+ if (this.options[eventName]) this.options[eventName](this);
+ },
+ inspect: function() {
+ var data = $H();
+ for(property in this)
+ if (!Object.isFunction(this[property])) data.set(property, this[property]);
+ return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
+ }
+});
+
+Effect.Parallel = Class.create(Effect.Base, {
+ initialize: function(effects) {
+ this.effects = effects || [];
+ this.start(arguments[1]);
+ },
+ update: function(position) {
+ this.effects.invoke('render', position);
+ },
+ finish: function(position) {
+ this.effects.each( function(effect) {
+ effect.render(1.0);
+ effect.cancel();
+ effect.event('beforeFinish');
+ if (effect.finish) effect.finish(position);
+ effect.event('afterFinish');
+ });
+ }
+});
+
+Effect.Tween = Class.create(Effect.Base, {
+ initialize: function(object, from, to) {
+ object = Object.isString(object) ? $(object) : object;
+ var args = $A(arguments), method = args.last(),
+ options = args.length == 5 ? args[3] : null;
+ this.method = Object.isFunction(method) ? method.bind(object) :
+ Object.isFunction(object[method]) ? object[method].bind(object) :
+ function(value) { object[method] = value };
+ this.start(Object.extend({ from: from, to: to }, options || { }));
+ },
+ update: function(position) {
+ this.method(position);
+ }
+});
+
+Effect.Event = Class.create(Effect.Base, {
+ initialize: function() {
+ this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
+ },
+ update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ // make this work on IE on elements without 'layout'
+ if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ var options = Object.extend({
+ from: this.element.getOpacity() || 0.0,
+ to: 1.0
+ }, arguments[1] || { });
+ this.start(options);
+ },
+ update: function(position) {
+ this.element.setOpacity(position);
+ }
+});
+
+Effect.Move = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ x: 0,
+ y: 0,
+ mode: 'relative'
+ }, arguments[1] || { });
+ this.start(options);
+ },
+ setup: function() {
+ this.element.makePositioned();
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+ this.originalTop = parseFloat(this.element.getStyle('top') || '0');
+ if (this.options.mode == 'absolute') {
+ this.options.x = this.options.x - this.originalLeft;
+ this.options.y = this.options.y - this.originalTop;
+ }
+ },
+ update: function(position) {
+ this.element.setStyle({
+ left: (this.options.x * position + this.originalLeft).round() + 'px',
+ top: (this.options.y * position + this.originalTop).round() + 'px'
+ });
+ }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+ return new Effect.Move(element,
+ Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
+};
+
+Effect.Scale = Class.create(Effect.Base, {
+ initialize: function(element, percent) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ scaleX: true,
+ scaleY: true,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleMode: 'box', // 'box' or 'contents' or { } with provided values
+ scaleFrom: 100.0,
+ scaleTo: percent
+ }, arguments[2] || { });
+ this.start(options);
+ },
+ setup: function() {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = this.element.getStyle('position');
+
+ this.originalStyle = { };
+ ['top','left','width','height','fontSize'].each( function(k) {
+ this.originalStyle[k] = this.element.style[k];
+ }.bind(this));
+
+ this.originalTop = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = this.element.getStyle('font-size') || '100%';
+ ['em','px','%','pt'].each( function(fontSizeType) {
+ if (fontSize.indexOf(fontSizeType)>0) {
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
+ }
+ }.bind(this));
+
+ this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+
+ this.dims = null;
+ if (this.options.scaleMode=='box')
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ if (/^content/.test(this.options.scaleMode))
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+ if (!this.dims)
+ this.dims = [this.options.scaleMode.originalHeight,
+ this.options.scaleMode.originalWidth];
+ },
+ update: function(position) {
+ var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+ if (this.options.scaleContent && this.fontSize)
+ this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+ this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+ },
+ finish: function(position) {
+ if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+ },
+ setDimensions: function(height, width) {
+ var d = { };
+ if (this.options.scaleX) d.width = width.round() + 'px';
+ if (this.options.scaleY) d.height = height.round() + 'px';
+ if (this.options.scaleFromCenter) {
+ var topd = (height - this.dims[0])/2;
+ var leftd = (width - this.dims[1])/2;
+ if (this.elementPositioning == 'absolute') {
+ if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
+ if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+ } else {
+ if (this.options.scaleY) d.top = -topd + 'px';
+ if (this.options.scaleX) d.left = -leftd + 'px';
+ }
+ }
+ this.element.setStyle(d);
+ }
+});
+
+Effect.Highlight = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
+ this.start(options);
+ },
+ setup: function() {
+ // Prevent executing on elements not in the layout flow
+ if (this.element.getStyle('display')=='none') { this.cancel(); return; }
+ // Disable background image during the effect
+ this.oldStyle = { };
+ if (!this.options.keepBackgroundImage) {
+ this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+ this.element.setStyle({backgroundImage: 'none'});
+ }
+ if (!this.options.endcolor)
+ this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+ if (!this.options.restorecolor)
+ this.options.restorecolor = this.element.getStyle('background-color');
+ // init color calculations
+ this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+ this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+ },
+ update: function(position) {
+ this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+ return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
+ },
+ finish: function() {
+ this.element.setStyle(Object.extend(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
+ }
+});
+
+Effect.ScrollTo = function(element) {
+ var options = arguments[1] || { },
+ scrollOffsets = document.viewport.getScrollOffsets(),
+ elementOffsets = $(element).cumulativeOffset(),
+ max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();
+
+ if (options.offset) elementOffsets[1] += options.offset;
+
+ return new Effect.Tween(null,
+ scrollOffsets.top,
+ elementOffsets[1] > max ? max : elementOffsets[1],
+ options,
+ function(p){ scrollTo(scrollOffsets.left, p.round()) }
+ );
+};
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ var options = Object.extend({
+ from: element.getOpacity() || 1.0,
+ to: 0.0,
+ afterFinishInternal: function(effect) {
+ if (effect.options.to!=0) return;
+ effect.element.hide().setStyle({opacity: oldOpacity});
+ }
+ }, arguments[1] || { });
+ return new Effect.Opacity(element,options);
+};
+
+Effect.Appear = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+ to: 1.0,
+ // force Safari to render floated elements properly
+ afterFinishInternal: function(effect) {
+ effect.element.forceRerendering();
+ },
+ beforeSetup: function(effect) {
+ effect.element.setOpacity(effect.options.from).show();
+ }}, arguments[1] || { });
+ return new Effect.Opacity(element,options);
+};
+
+Effect.Puff = function(element) {
+ element = $(element);
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
+ position: element.getStyle('position'),
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+ };
+ return new Effect.Parallel(
+ [ new Effect.Scale(element, 200,
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+ Object.extend({ duration: 1.0,
+ beforeSetupInternal: function(effect) {
+ Position.absolutize(effect.effects[0].element)
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().setStyle(oldStyle); }
+ }, arguments[1] || { })
+ );
+};
+
+Effect.BlindUp = function(element) {
+ element = $(element);
+ element.makeClipping();
+ return new Effect.Scale(element, 0,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ restoreAfterFinish: true,
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
+ }, arguments[1] || { })
+ );
+};
+
+Effect.BlindDown = function(element) {
+ element = $(element);
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || { }));
+};
+
+Effect.SwitchOff = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ return new Effect.Appear(element, Object.extend({
+ duration: 0.4,
+ from: 0,
+ transition: Effect.Transitions.flicker,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(effect.element, 1, {
+ duration: 0.3, scaleFromCenter: true,
+ scaleX: false, scaleContent: false, restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makePositioned().makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+ }
+ })
+ }
+ }, arguments[1] || { }));
+};
+
+Effect.DropOut = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left'),
+ opacity: element.getInlineOpacity() };
+ return new Effect.Parallel(
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+ Object.extend(
+ { duration: 0.5,
+ beforeSetup: function(effect) {
+ effect.effects[0].element.makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+ }
+ }, arguments[1] || { }));
+};
+
+Effect.Shake = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ distance: 20,
+ duration: 0.5
+ }, arguments[1] || {});
+ var distance = parseFloat(options.distance);
+ var split = parseFloat(options.duration) / 10.0;
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left') };
+ return new Effect.Move(element,
+ { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
+ effect.element.undoPositioned().setStyle(oldStyle);
+ }}) }}) }}) }}) }}) }});
+};
+
+Effect.SlideDown = function(element) {
+ element = $(element).cleanWhitespace();
+ // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+ var oldInnerBottom = element.down().getStyle('bottom');
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: window.opera ? 0 : 1,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.down().makePositioned();
+ if (window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterUpdateInternal: function(effect) {
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
+ }, arguments[1] || { })
+ );
+};
+
+Effect.SlideUp = function(element) {
+ element = $(element).cleanWhitespace();
+ var oldInnerBottom = element.down().getStyle('bottom');
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, window.opera ? 0 : 1,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ scaleMode: 'box',
+ scaleFrom: 100,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.down().makePositioned();
+ if (window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping().show();
+ },
+ afterUpdateInternal: function(effect) {
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
+ }
+ }, arguments[1] || { })
+ );
+};
+
+// Bug in opera makes the TD containing this element expand for a instance after finish
+Effect.Squish = function(element) {
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
+ restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
+ });
+};
+
+Effect.Grow = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.full
+ }, arguments[1] || { });
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var initialMoveX, initialMoveY;
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ initialMoveX = initialMoveY = moveX = moveY = 0;
+ break;
+ case 'top-right':
+ initialMoveX = dims.width;
+ initialMoveY = moveY = 0;
+ moveX = -dims.width;
+ break;
+ case 'bottom-left':
+ initialMoveX = moveX = 0;
+ initialMoveY = dims.height;
+ moveY = -dims.height;
+ break;
+ case 'bottom-right':
+ initialMoveX = dims.width;
+ initialMoveY = dims.height;
+ moveX = -dims.width;
+ moveY = -dims.height;
+ break;
+ case 'center':
+ initialMoveX = dims.width / 2;
+ initialMoveY = dims.height / 2;
+ moveX = -dims.width / 2;
+ moveY = -dims.height / 2;
+ break;
+ }
+
+ return new Effect.Move(element, {
+ x: initialMoveX,
+ y: initialMoveY,
+ duration: 0.01,
+ beforeSetup: function(effect) {
+ effect.element.hide().makeClipping().makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ new Effect.Parallel(
+ [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+ new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+ new Effect.Scale(effect.element, 100, {
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+ ], Object.extend({
+ beforeSetup: function(effect) {
+ effect.effects[0].element.setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+ }
+ }, options)
+ )
+ }
+ });
+};
+
+Effect.Shrink = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.none
+ }, arguments[1] || { });
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ moveX = moveY = 0;
+ break;
+ case 'top-right':
+ moveX = dims.width;
+ moveY = 0;
+ break;
+ case 'bottom-left':
+ moveX = 0;
+ moveY = dims.height;
+ break;
+ case 'bottom-right':
+ moveX = dims.width;
+ moveY = dims.height;
+ break;
+ case 'center':
+ moveX = dims.width / 2;
+ moveY = dims.height / 2;
+ break;
+ }
+
+ return new Effect.Parallel(
+ [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+ new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+ new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+ ], Object.extend({
+ beforeStartInternal: function(effect) {
+ effect.effects[0].element.makePositioned().makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
+ }, options)
+ );
+};
+
+Effect.Pulsate = function(element) {
+ element = $(element);
+ var options = arguments[1] || { };
+ var oldOpacity = element.getInlineOpacity();
+ var transition = options.transition || Effect.Transitions.sinoidal;
+ var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
+ reverser.bind(transition);
+ return new Effect.Opacity(element,
+ Object.extend(Object.extend({ duration: 2.0, from: 0,
+ afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+ }, options), {transition: reverser}));
+};
+
+Effect.Fold = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height };
+ element.makeClipping();
+ return new Effect.Scale(element, 5, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
+ scaleY: false,
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().setStyle(oldStyle);
+ } });
+ }}, arguments[1] || { }));
+};
+
+Effect.Morph = Class.create(Effect.Base, {
+ initialize: function(element) {
+ this.element = $(element);
+ if (!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ style: { }
+ }, arguments[1] || { });
+
+ if (!Object.isString(options.style)) this.style = $H(options.style);
+ else {
+ if (options.style.include(':'))
+ this.style = options.style.parseStyle();
+ else {
+ this.element.addClassName(options.style);
+ this.style = $H(this.element.getStyles());
+ this.element.removeClassName(options.style);
+ var css = this.element.getStyles();
+ this.style = this.style.reject(function(style) {
+ return style.value == css[style.key];
+ });
+ options.afterFinishInternal = function(effect) {
+ effect.element.addClassName(effect.options.style);
+ effect.transforms.each(function(transform) {
+ effect.element.style[transform.style] = '';
+ });
+ }
+ }
+ }
+ this.start(options);
+ },
+
+ setup: function(){
+ function parseColor(color){
+ if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+ color = color.parseColor();
+ return $R(0,2).map(function(i){
+ return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ });
+ }
+ this.transforms = this.style.map(function(pair){
+ var property = pair[0], value = pair[1], unit = null;
+
+ if (value.parseColor('#zzzzzz') != '#zzzzzz') {
+ value = value.parseColor();
+ unit = 'color';
+ } else if (property == 'opacity') {
+ value = parseFloat(value);
+ if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ } else if (Element.CSS_LENGTH.test(value)) {
+ var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+ value = parseFloat(components[1]);
+ unit = (components.length == 3) ? components[2] : null;
+ }
+
+ var originalValue = this.element.getStyle(property);
+ return {
+ style: property.camelize(),
+ originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+ targetValue: unit=='color' ? parseColor(value) : value,
+ unit: unit
+ };
+ }.bind(this)).reject(function(transform){
+ return (
+ (transform.originalValue == transform.targetValue) ||
+ (
+ transform.unit != 'color' &&
+ (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+ )
+ )
+ });
+ },
+ update: function(position) {
+ var style = { }, transform, i = this.transforms.length;
+ while(i--)
+ style[(transform = this.transforms[i]).style] =
+ transform.unit=='color' ? '#'+
+ (Math.round(transform.originalValue[0]+
+ (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
+ (Math.round(transform.originalValue[1]+
+ (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
+ (Math.round(transform.originalValue[2]+
+ (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
+ (transform.originalValue +
+ (transform.targetValue - transform.originalValue) * position).toFixed(3) +
+ (transform.unit === null ? '' : transform.unit);
+ this.element.setStyle(style, true);
+ }
+});
+
+Effect.Transform = Class.create({
+ initialize: function(tracks){
+ this.tracks = [];
+ this.options = arguments[1] || { };
+ this.addTracks(tracks);
+ },
+ addTracks: function(tracks){
+ tracks.each(function(track){
+ track = $H(track);
+ var data = track.values().first();
+ this.tracks.push($H({
+ ids: track.keys().first(),
+ effect: Effect.Morph,
+ options: { style: data }
+ }));
+ }.bind(this));
+ return this;
+ },
+ play: function(){
+ return new Effect.Parallel(
+ this.tracks.map(function(track){
+ var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
+ var elements = [$(ids) || $$(ids)].flatten();
+ return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
+ }).flatten(),
+ this.options
+ );
+ }
+});
+
+Element.CSS_PROPERTIES = $w(
+ 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+ 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+ 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+ 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+ 'fontSize fontWeight height left letterSpacing lineHeight ' +
+ 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+ 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+ 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+ 'right textIndent top width wordSpacing zIndex');
+
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.__parseStyleElement = document.createElement('div');
+String.prototype.parseStyle = function(){
+ var style, styleRules = $H();
+ if (Prototype.Browser.WebKit)
+ style = new Element('div',{style:this}).style;
+ else {
+ String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
+ style = String.__parseStyleElement.childNodes[0].style;
+ }
+
+ Element.CSS_PROPERTIES.each(function(property){
+ if (style[property]) styleRules.set(property, style[property]);
+ });
+
+ if (Prototype.Browser.IE && this.include('opacity'))
+ styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
+
+ return styleRules;
+};
+
+if (document.defaultView && document.defaultView.getComputedStyle) {
+ Element.getStyles = function(element) {
+ var css = document.defaultView.getComputedStyle($(element), null);
+ return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
+ styles[property] = css[property];
+ return styles;
+ });
+ };
+} else {
+ Element.getStyles = function(element) {
+ element = $(element);
+ var css = element.currentStyle, styles;
+ styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
+ results[property] = css[property];
+ return results;
+ });
+ if (!styles.opacity) styles.opacity = element.getOpacity();
+ return styles;
+ };
+};
+
+Effect.Methods = {
+ morph: function(element, style) {
+ element = $(element);
+ new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
+ return element;
+ },
+ visualEffect: function(element, effect, options) {
+ element = $(element)
+ var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[klass](element, options);
+ return element;
+ },
+ highlight: function(element, options) {
+ element = $(element);
+ new Effect.Highlight(element, options);
+ return element;
+ }
+};
+
+$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
+ 'pulsate shake puff squish switchOff dropOut').each(
+ function(effect) {
+ Effect.Methods[effect] = function(element, options){
+ element = $(element);
+ Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
+ return element;
+ }
+ }
+);
+
+$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
+ function(f) { Effect.Methods[f] = Element[f]; }
+);
+
+Element.addMethods(Effect.Methods);
Property changes on: trunk/docs/common-resources/en/src/main/script/effects.js
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/prototype-1.6.0.2.js
===================================================================
--- trunk/docs/common-resources/en/src/main/script/prototype-1.6.0.2.js (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/prototype-1.6.0.2.js 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,4240 @@
+/* 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/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.6.0.2',
+
+ Browser: {
+ IE: !!(window.attachEvent && !window.opera),
+ Opera: !!window.opera,
+ 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,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ document.createElement('div').__proto__ &&
+ document.createElement('div').__proto__ !==
+ document.createElement('form').__proto__
+ },
+
+ ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+ JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+ emptyFunction: function() { },
+ K: function(x) { return x }
+};
+
+if (Prototype.Browser.MobileSafari)
+ Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+
+/* Based on Alex Arnell's inheritance implementation. */
+var Class = {
+ create: function() {
+ var parent = null, properties = $A(arguments);
+ if (Object.isFunction(properties[0]))
+ parent = properties.shift();
+
+ function klass() {
+ this.initialize.apply(this, arguments);
+ }
+
+ Object.extend(klass, Class.Methods);
+ klass.superclass = parent;
+ klass.subclasses = [];
+
+ if (parent) {
+ var subclass = function() { };
+ subclass.prototype = parent.prototype;
+ klass.prototype = new subclass;
+ parent.subclasses.push(klass);
+ }
+
+ for (var i = 0; i < properties.length; i++)
+ klass.addMethods(properties[i]);
+
+ if (!klass.prototype.initialize)
+ klass.prototype.initialize = Prototype.emptyFunction;
+
+ klass.prototype.constructor = klass;
+
+ return klass;
+ }
+};
+
+Class.Methods = {
+ addMethods: function(source) {
+ var ancestor = this.superclass && this.superclass.prototype;
+ var properties = Object.keys(source);
+
+ if (!Object.keys({ toString: true }).length)
+ properties.push("toString", "valueOf");
+
+ for (var i = 0, length = properties.length; i < length; i++) {
+ var property = properties[i], value = source[property];
+ if (ancestor && Object.isFunction(value) &&
+ value.argumentNames().first() == "$super") {
+ var method = value, value = Object.extend((function(m) {
+ return function() { return ancestor[m].apply(this, arguments) };
+ })(property).wrap(method), {
+ valueOf: function() { return method },
+ toString: function() { return method.toString() }
+ });
+ }
+ this.prototype[property] = value;
+ }
+
+ return this;
+ }
+};
+
+var Abstract = { };
+
+Object.extend = function(destination, source) {
+ for (var property in source)
+ destination[property] = source[property];
+ return destination;
+};
+
+Object.extend(Object, {
+ inspect: function(object) {
+ try {
+ if (Object.isUndefined(object)) return 'undefined';
+ if (object === null) return 'null';
+ return object.inspect ? object.inspect() : String(object);
+ } catch (e) {
+ if (e instanceof RangeError) return '...';
+ throw e;
+ }
+ },
+
+ toJSON: function(object) {
+ var type = typeof object;
+ switch (type) {
+ case 'undefined':
+ case 'function':
+ case 'unknown': return;
+ case 'boolean': return object.toString();
+ }
+
+ if (object === null) return 'null';
+ if (object.toJSON) return object.toJSON();
+ if (Object.isElement(object)) return;
+
+ var results = [];
+ for (var property in object) {
+ var value = Object.toJSON(object[property]);
+ if (!Object.isUndefined(value))
+ results.push(property.toJSON() + ': ' + value);
+ }
+
+ return '{' + results.join(', ') + '}';
+ },
+
+ toQueryString: function(object) {
+ return $H(object).toQueryString();
+ },
+
+ toHTML: function(object) {
+ return object && object.toHTML ? object.toHTML() : String.interpret(object);
+ },
+
+ keys: function(object) {
+ var keys = [];
+ for (var property in object)
+ keys.push(property);
+ return keys;
+ },
+
+ values: function(object) {
+ var values = [];
+ for (var property in object)
+ values.push(object[property]);
+ return values;
+ },
+
+ clone: function(object) {
+ return Object.extend({ }, object);
+ },
+
+ isElement: function(object) {
+ return object && object.nodeType == 1;
+ },
+
+ isArray: function(object) {
+ return object != null && typeof object == "object" &&
+ 'splice' in object && 'join' in object;
+ },
+
+ isHash: function(object) {
+ return object instanceof Hash;
+ },
+
+ isFunction: function(object) {
+ return typeof object == "function";
+ },
+
+ isString: function(object) {
+ return typeof object == "string";
+ },
+
+ isNumber: function(object) {
+ return typeof object == "number";
+ },
+
+ isUndefined: function(object) {
+ return typeof object == "undefined";
+ }
+});
+
+Object.extend(Function.prototype, {
+ argumentNames: function() {
+ var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+ return names.length == 1 && !names[0] ? [] : names;
+ },
+
+ bind: function() {
+ 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)));
+ }
+ },
+
+ bindAsEventListener: function() {
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function(event) {
+ return __method.apply(object, [event || window.event].concat(args));
+ }
+ },
+
+ curry: function() {
+ if (!arguments.length) return this;
+ var __method = this, args = $A(arguments);
+ return function() {
+ return __method.apply(this, args.concat($A(arguments)));
+ }
+ },
+
+ delay: function() {
+ var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+ return window.setTimeout(function() {
+ return __method.apply(__method, args);
+ }, timeout);
+ },
+
+ wrap: function(wrapper) {
+ var __method = this;
+ return function() {
+ return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+ }
+ },
+
+ methodize: function() {
+ if (this._methodized) return this._methodized;
+ var __method = this;
+ return this._methodized = function() {
+ return __method.apply(null, [this].concat($A(arguments)));
+ };
+ }
+});
+
+Function.prototype.defer = Function.prototype.delay.curry(0.01);
+
+Date.prototype.toJSON = function() {
+ return '"' + this.getUTCFullYear() + '-' +
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+ this.getUTCDate().toPaddedString(2) + 'T' +
+ this.getUTCHours().toPaddedString(2) + ':' +
+ this.getUTCMinutes().toPaddedString(2) + ':' +
+ this.getUTCSeconds().toPaddedString(2) + 'Z"';
+};
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0, length = arguments.length; i < length; i++) {
+ var lambda = arguments[i];
+ try {
+ returnValue = lambda();
+ break;
+ } catch (e) { }
+ }
+
+ return returnValue;
+ }
+};
+
+RegExp.prototype.match = RegExp.prototype.test;
+
+RegExp.escape = function(str) {
+ return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create({
+ initialize: function(callback, frequency) {
+ this.callback = callback;
+ this.frequency = frequency;
+ this.currentlyExecuting = false;
+
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ execute: function() {
+ this.callback(this);
+ },
+
+ stop: function() {
+ if (!this.timer) return;
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+
+ onTimerEvent: function() {
+ if (!this.currentlyExecuting) {
+ try {
+ this.currentlyExecuting = true;
+ this.execute();
+ } finally {
+ this.currentlyExecuting = false;
+ }
+ }
+ }
+});
+Object.extend(String, {
+ interpret: function(value) {
+ return value == null ? '' : String(value);
+ },
+ specialChar: {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '\\': '\\\\'
+ }
+});
+
+Object.extend(String.prototype, {
+ gsub: function(pattern, replacement) {
+ var result = '', source = this, match;
+ replacement = arguments.callee.prepareReplacement(replacement);
+
+ while (source.length > 0) {
+ if (match = source.match(pattern)) {
+ result += source.slice(0, match.index);
+ result += String.interpret(replacement(match));
+ source = source.slice(match.index + match[0].length);
+ } else {
+ result += source, source = '';
+ }
+ }
+ return result;
+ },
+
+ sub: function(pattern, replacement, count) {
+ replacement = this.gsub.prepareReplacement(replacement);
+ count = Object.isUndefined(count) ? 1 : count;
+
+ return this.gsub(pattern, function(match) {
+ if (--count < 0) return match[0];
+ return replacement(match);
+ });
+ },
+
+ scan: function(pattern, iterator) {
+ this.gsub(pattern, iterator);
+ return String(this);
+ },
+
+ truncate: function(length, truncation) {
+ length = length || 30;
+ truncation = Object.isUndefined(truncation) ? '...' : truncation;
+ return this.length > length ?
+ this.slice(0, length - truncation.length) + truncation : String(this);
+ },
+
+ strip: function() {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ },
+
+ stripTags: function() {
+ return this.replace(/<\/?[^>]+>/gi, '');
+ },
+
+ stripScripts: function() {
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+ },
+
+ extractScripts: function() {
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+ var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+ return (this.match(matchAll) || []).map(function(scriptTag) {
+ var result = (scriptTag.match(matchOne) || ['', ''])[1];
+ result = result.replace(/</,"<").replace(/\s*<!--[^\r\n]*/, "");
+ return result;
+ });
+ },
+
+ evalScripts: function() {
+ return this.extractScripts().map(function(script) { return eval(script) });
+ },
+
+ escapeHTML: function() {
+ var self = arguments.callee;
+ self.text.data = this;
+ return self.div.innerHTML;
+ },
+
+ unescapeHTML: function() {
+ var div = new Element('div');
+ div.innerHTML = this.stripTags();
+ return div.childNodes[0] ? (div.childNodes.length > 1 ?
+ $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
+ div.childNodes[0].nodeValue) : '';
+ },
+
+ toQueryParams: function(separator) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return { };
+
+ return match[1].split(separator || '&').inject({ }, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var key = decodeURIComponent(pair.shift());
+ var value = pair.length > 1 ? pair.join('=') : pair[0];
+ if (value != undefined) value = decodeURIComponent(value);
+
+ if (key in hash) {
+ if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+ hash[key].push(value);
+ }
+ else hash[key] = value;
+ }
+ return hash;
+ });
+ },
+
+ toArray: function() {
+ return this.split('');
+ },
+
+ succ: function() {
+ return this.slice(0, this.length - 1) +
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+ },
+
+ times: function(count) {
+ return count < 1 ? '' : new Array(count + 1).join(this);
+ },
+
+ camelize: function() {
+ var parts = this.split('-'), len = parts.length;
+ if (len == 1) return parts[0];
+
+ var camelized = this.charAt(0) == '-'
+ ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+ : parts[0];
+
+ for (var i = 1; i < len; i++)
+ camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+ return camelized;
+ },
+
+ capitalize: function() {
+ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+ },
+
+ underscore: function() {
+ return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+ },
+
+ dasherize: function() {
+ return this.gsub(/_/,'-');
+ },
+
+ inspect: function(useDoubleQuotes) {
+ var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
+ var character = String.specialChar[match[0]];
+ return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+ });
+ if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+ },
+
+ toJSON: function() {
+ return this.inspect(true);
+ },
+
+ unfilterJSON: function(filter) {
+ return this.sub(filter || Prototype.JSONFilter, '#{1}');
+ },
+
+ isJSON: function() {
+ 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);
+ },
+
+ evalJSON: function(sanitize) {
+ var json = this.unfilterJSON();
+ try {
+ if (!sanitize || json.isJSON()) return eval('(' + json + ')');
+ } catch (e) { }
+ throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+ },
+
+ include: function(pattern) {
+ return this.indexOf(pattern) > -1;
+ },
+
+ startsWith: function(pattern) {
+ return this.indexOf(pattern) === 0;
+ },
+
+ endsWith: function(pattern) {
+ var d = this.length - pattern.length;
+ return d >= 0 && this.lastIndexOf(pattern) === d;
+ },
+
+ empty: function() {
+ return this == '';
+ },
+
+ blank: function() {
+ return /^\s*$/.test(this);
+ },
+
+ interpolate: function(object, pattern) {
+ return new Template(this, pattern).evaluate(object);
+ }
+});
+
+if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
+ escapeHTML: function() {
+ return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ },
+ unescapeHTML: function() {
+ return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+ if (Object.isFunction(replacement)) return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+};
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+Object.extend(String.prototype.escapeHTML, {
+ div: document.createElement('div'),
+ text: document.createTextNode('')
+});
+
+with (String.prototype.escapeHTML) div.appendChild(text);
+
+var Template = Class.create({
+ initialize: function(template, pattern) {
+ this.template = template.toString();
+ this.pattern = pattern || Template.Pattern;
+ },
+
+ evaluate: function(object) {
+ if (Object.isFunction(object.toTemplateReplacements))
+ object = object.toTemplateReplacements();
+
+ return this.template.gsub(this.pattern, function(match) {
+ if (object == null) return '';
+
+ var before = match[1] || '';
+ if (before == '\\') return match[2];
+
+ var ctx = object, expr = match[3];
+ var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+ match = pattern.exec(expr);
+ if (match == null) return before;
+
+ while (match != null) {
+ var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+ ctx = ctx[comp];
+ if (null == ctx || '' == match[3]) break;
+ expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+ match = pattern.exec(expr);
+ }
+
+ return before + String.interpret(ctx);
+ });
+ }
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+
+var $break = { };
+
+var Enumerable = {
+ each: function(iterator, context) {
+ var index = 0;
+ iterator = iterator.bind(context);
+ try {
+ this._each(function(value) {
+ iterator(value, index++);
+ });
+ } catch (e) {
+ if (e != $break) throw e;
+ }
+ return this;
+ },
+
+ eachSlice: function(number, iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var index = -number, slices = [], array = this.toArray();
+ while ((index += number) < array.length)
+ slices.push(array.slice(index, index+number));
+ return slices.collect(iterator, context);
+ },
+
+ all: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result = true;
+ this.each(function(value, index) {
+ result = result && !!iterator(value, index);
+ if (!result) throw $break;
+ });
+ return result;
+ },
+
+ any: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result = false;
+ this.each(function(value, index) {
+ if (result = !!iterator(value, index))
+ throw $break;
+ });
+ return result;
+ },
+
+ collect: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var results = [];
+ this.each(function(value, index) {
+ results.push(iterator(value, index));
+ });
+ return results;
+ },
+
+ detect: function(iterator, context) {
+ iterator = iterator.bind(context);
+ var result;
+ this.each(function(value, index) {
+ if (iterator(value, index)) {
+ result = value;
+ throw $break;
+ }
+ });
+ return result;
+ },
+
+ findAll: function(iterator, context) {
+ iterator = iterator.bind(context);
+ var results = [];
+ this.each(function(value, index) {
+ if (iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
+
+ grep: function(filter, iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var results = [];
+
+ if (Object.isString(filter))
+ filter = new RegExp(filter);
+
+ this.each(function(value, index) {
+ if (filter.match(value))
+ results.push(iterator(value, index));
+ });
+ return results;
+ },
+
+ include: function(object) {
+ if (Object.isFunction(this.indexOf))
+ if (this.indexOf(object) != -1) return true;
+
+ var found = false;
+ this.each(function(value) {
+ if (value == object) {
+ found = true;
+ throw $break;
+ }
+ });
+ return found;
+ },
+
+ inGroupsOf: function(number, fillWith) {
+ fillWith = Object.isUndefined(fillWith) ? null : fillWith;
+ return this.eachSlice(number, function(slice) {
+ while(slice.length < number) slice.push(fillWith);
+ return slice;
+ });
+ },
+
+ inject: function(memo, iterator, context) {
+ iterator = iterator.bind(context);
+ this.each(function(value, index) {
+ memo = iterator(memo, value, index);
+ });
+ return memo;
+ },
+
+ invoke: function(method) {
+ var args = $A(arguments).slice(1);
+ return this.map(function(value) {
+ return value[method].apply(value, args);
+ });
+ },
+
+ max: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result;
+ this.each(function(value, index) {
+ value = iterator(value, index);
+ if (result == null || value >= result)
+ result = value;
+ });
+ return result;
+ },
+
+ min: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result;
+ this.each(function(value, index) {
+ value = iterator(value, index);
+ if (result == null || value < result)
+ result = value;
+ });
+ return result;
+ },
+
+ partition: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var trues = [], falses = [];
+ this.each(function(value, index) {
+ (iterator(value, index) ?
+ trues : falses).push(value);
+ });
+ return [trues, falses];
+ },
+
+ pluck: function(property) {
+ var results = [];
+ this.each(function(value) {
+ results.push(value[property]);
+ });
+ return results;
+ },
+
+ reject: function(iterator, context) {
+ iterator = iterator.bind(context);
+ var results = [];
+ this.each(function(value, index) {
+ if (!iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
+
+ sortBy: function(iterator, context) {
+ iterator = iterator.bind(context);
+ return this.map(function(value, index) {
+ return {value: value, criteria: iterator(value, index)};
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }).pluck('value');
+ },
+
+ toArray: function() {
+ return this.map();
+ },
+
+ zip: function() {
+ var iterator = Prototype.K, args = $A(arguments);
+ if (Object.isFunction(args.last()))
+ iterator = args.pop();
+
+ var collections = [this].concat(args).map($A);
+ return this.map(function(value, index) {
+ return iterator(collections.pluck(index));
+ });
+ },
+
+ size: function() {
+ return this.toArray().length;
+ },
+
+ inspect: function() {
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
+ }
+};
+
+Object.extend(Enumerable, {
+ map: Enumerable.collect,
+ find: Enumerable.detect,
+ select: Enumerable.findAll,
+ filter: Enumerable.findAll,
+ member: Enumerable.include,
+ entries: Enumerable.toArray,
+ every: Enumerable.all,
+ some: Enumerable.any
+});
+function $A(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
+ while (length--) results[length] = iterable[length];
+ return results;
+}
+
+if (Prototype.Browser.WebKit) {
+ $A = function(iterable) {
+ if (!iterable) return [];
+ if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
+ iterable.toArray) return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
+ while (length--) results[length] = iterable[length];
+ return results;
+ };
+}
+
+Array.from = $A;
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+ _each: function(iterator) {
+ for (var i = 0, length = this.length; i < length; i++)
+ iterator(this[i]);
+ },
+
+ clear: function() {
+ this.length = 0;
+ return this;
+ },
+
+ first: function() {
+ return this[0];
+ },
+
+ last: function() {
+ return this[this.length - 1];
+ },
+
+ compact: function() {
+ return this.select(function(value) {
+ return value != null;
+ });
+ },
+
+ flatten: function() {
+ return this.inject([], function(array, value) {
+ return array.concat(Object.isArray(value) ?
+ value.flatten() : [value]);
+ });
+ },
+
+ without: function() {
+ var values = $A(arguments);
+ return this.select(function(value) {
+ return !values.include(value);
+ });
+ },
+
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
+ },
+
+ reduce: function() {
+ return this.length > 1 ? this : this[0];
+ },
+
+ uniq: function(sorted) {
+ return this.inject([], function(array, value, index) {
+ if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+ array.push(value);
+ return array;
+ });
+ },
+
+ intersect: function(array) {
+ return this.uniq().findAll(function(item) {
+ return array.detect(function(value) { return item === value });
+ });
+ },
+
+ clone: function() {
+ return [].concat(this);
+ },
+
+ size: function() {
+ return this.length;
+ },
+
+ inspect: function() {
+ return '[' + this.map(Object.inspect).join(', ') + ']';
+ },
+
+ toJSON: function() {
+ var results = [];
+ this.each(function(object) {
+ var value = Object.toJSON(object);
+ if (!Object.isUndefined(value)) results.push(value);
+ });
+ return '[' + results.join(', ') + ']';
+ }
+});
+
+// use native browser JS 1.6 implementation if available
+if (Object.isFunction(Array.prototype.forEach))
+ Array.prototype._each = Array.prototype.forEach;
+
+if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
+ i || (i = 0);
+ var length = this.length;
+ if (i < 0) i = length + i;
+ for (; i < length; i++)
+ if (this[i] === item) return i;
+ return -1;
+};
+
+if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
+ i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
+ var n = this.slice(0, i).reverse().indexOf(item);
+ return (n < 0) ? n : i - n - 1;
+};
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string) {
+ if (!Object.isString(string)) return [];
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
+}
+
+if (Prototype.Browser.Opera){
+ Array.prototype.concat = function() {
+ var array = [];
+ for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ for (var i = 0, length = arguments.length; i < length; i++) {
+ if (Object.isArray(arguments[i])) {
+ for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+ array.push(arguments[i][j]);
+ } else {
+ array.push(arguments[i]);
+ }
+ }
+ return array;
+ };
+}
+Object.extend(Number.prototype, {
+ toColorPart: function() {
+ return this.toPaddedString(2, 16);
+ },
+
+ succ: function() {
+ return this + 1;
+ },
+
+ times: function(iterator) {
+ $R(0, this, true).each(iterator);
+ return this;
+ },
+
+ toPaddedString: function(length, radix) {
+ var string = this.toString(radix || 10);
+ return '0'.times(length - string.length) + string;
+ },
+
+ toJSON: function() {
+ return isFinite(this) ? this.toString() : 'null';
+ }
+});
+
+$w('abs round ceil floor').each(function(method){
+ Number.prototype[method] = Math[method].methodize();
+});
+function $H(object) {
+ return new Hash(object);
+};
+
+var Hash = Class.create(Enumerable, (function() {
+
+ function toQueryPair(key, value) {
+ if (Object.isUndefined(value)) return key;
+ return key + '=' + encodeURIComponent(String.interpret(value));
+ }
+
+ return {
+ initialize: function(object) {
+ this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
+ },
+
+ _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;
+ },
+
+ get: function(key) {
+ return this._object[key];
+ },
+
+ unset: function(key) {
+ var value = this._object[key];
+ delete this._object[key];
+ return value;
+ },
+
+ toObject: function() {
+ return Object.clone(this._object);
+ },
+
+ keys: function() {
+ return this.pluck('key');
+ },
+
+ values: function() {
+ return this.pluck('value');
+ },
+
+ index: function(value) {
+ var match = this.detect(function(pair) {
+ return pair.value === value;
+ });
+ return match && match.key;
+ },
+
+ merge: function(object) {
+ return this.clone().update(object);
+ },
+
+ update: function(object) {
+ return new Hash(object).inject(this, function(result, pair) {
+ result.set(pair.key, pair.value);
+ return result;
+ });
+ },
+
+ toQueryString: function() {
+ return this.map(function(pair) {
+ var key = encodeURIComponent(pair.key), values = pair.value;
+
+ if (values && typeof values == 'object') {
+ if (Object.isArray(values))
+ return values.map(toQueryPair.curry(key)).join('&');
+ }
+ return toQueryPair(key, values);
+ }).join('&');
+ },
+
+ inspect: function() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ },
+
+ toJSON: function() {
+ return Object.toJSON(this.toObject());
+ },
+
+ clone: function() {
+ return new Hash(this);
+ }
+ }
+})());
+
+Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
+Hash.from = $H;
+var ObjectRange = Class.create(Enumerable, {
+ initialize: function(start, end, exclusive) {
+ this.start = start;
+ this.end = end;
+ this.exclusive = exclusive;
+ },
+
+ _each: function(iterator) {
+ var value = this.start;
+ while (this.include(value)) {
+ iterator(value);
+ value = value.succ();
+ }
+ },
+
+ include: function(value) {
+ if (value < this.start)
+ return false;
+ if (this.exclusive)
+ return value < this.end;
+ return value <= this.end;
+ }
+});
+
+var $R = function(start, end, exclusive) {
+ return new ObjectRange(start, end, exclusive);
+};
+
+var Ajax = {
+ getTransport: function() {
+ return Try.these(
+ function() {return new XMLHttpRequest()},
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+ ) || false;
+ },
+
+ activeRequestCount: 0
+};
+
+Ajax.Responders = {
+ responders: [],
+
+ _each: function(iterator) {
+ this.responders._each(iterator);
+ },
+
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
+ },
+
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
+ },
+
+ dispatch: function(callback, request, transport, json) {
+ this.each(function(responder) {
+ if (Object.isFunction(responder[callback])) {
+ try {
+ responder[callback].apply(responder, [request, transport, json]);
+ } catch (e) { }
+ }
+ });
+ }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+ onCreate: function() { Ajax.activeRequestCount++ },
+ onComplete: function() { Ajax.activeRequestCount-- }
+});
+
+Ajax.Base = Class.create({
+ initialize: function(options) {
+ this.options = {
+ method: 'post',
+ asynchronous: true,
+ contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
+ parameters: '',
+ evalJSON: true,
+ evalJS: true
+ };
+ 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();
+ }
+});
+
+Ajax.Request = Class.create(Ajax.Base, {
+ _complete: false,
+
+ initialize: function($super, url, options) {
+ $super(options);
+ this.transport = Ajax.getTransport();
+ this.request(url);
+ },
+
+ request: function(url) {
+ this.url = url;
+ this.method = this.options.method;
+ var params = Object.clone(this.options.parameters);
+
+ if (!['get', 'post'].include(this.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.method;
+ this.method = 'post';
+ }
+
+ this.parameters = params;
+
+ if (params = Object.toQueryString(params)) {
+ // when GET, append parameters to URL
+ if (this.method == 'get')
+ this.url += (this.url.include('?') ? '&' : '?') + params;
+ else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ params += '&_=';
+ }
+
+ try {
+ var response = new Ajax.Response(this);
+ if (this.options.onCreate) this.options.onCreate(response);
+ Ajax.Responders.dispatch('onCreate', this, response);
+
+ this.transport.open(this.method.toUpperCase(), this.url,
+ this.options.asynchronous);
+
+ if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
+
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ this.setRequestHeaders();
+
+ this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+ this.transport.send(this.body);
+
+ /* Force Firefox to handle ready state 4 for synchronous requests */
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
+ this.onStateChange();
+
+ }
+ catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState > 1 && !((readyState == 4) && this._complete))
+ this.respondToReadyState(this.transport.readyState);
+ },
+
+ setRequestHeaders: function() {
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
+
+ if (this.method == 'post') {
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
+ }
+
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
+
+ if (Object.isFunction(extras.push))
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
+
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
+ },
+
+ success: function() {
+ var status = this.getStatus();
+ return !status || (status >= 200 && status < 300);
+ },
+
+ getStatus: function() {
+ try {
+ return this.transport.status || 0;
+ } catch (e) { return 0 }
+ },
+
+ respondToReadyState: function(readyState) {
+ var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+ if (state == 'Complete') {
+ try {
+ this._complete = true;
+ (this.options['on' + response.status]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(response, response.headerJSON);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ var contentType = response.getHeader('Content-type');
+ if (this.options.evalJS == 'force'
+ || (this.options.evalJS && this.isSameOrigin() && contentType
+ && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+ Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if (state == 'Complete') {
+ // avoid memory leak in MSIE: clean up
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+ },
+
+ 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) || null;
+ } catch (e) { return null }
+ },
+
+ evalResponse: function() {
+ try {
+ return eval((this.transport.responseText || '').unfilterJSON());
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ dispatchException: function(exception) {
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
+ Ajax.Responders.dispatch('onException', this, exception);
+ }
+});
+
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Response = Class.create({
+ initialize: function(request){
+ this.request = request;
+ var transport = this.transport = request.transport,
+ readyState = this.readyState = transport.readyState;
+
+ if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+ this.status = this.getStatus();
+ this.statusText = this.getStatusText();
+ this.responseText = String.interpret(transport.responseText);
+ this.headerJSON = this._getHeaderJSON();
+ }
+
+ if(readyState == 4) {
+ var xml = transport.responseXML;
+ this.responseXML = Object.isUndefined(xml) ? null : xml;
+ this.responseJSON = this._getResponseJSON();
+ }
+ },
+
+ status: 0,
+ statusText: '',
+
+ getStatus: Ajax.Request.prototype.getStatus,
+
+ getStatusText: function() {
+ try {
+ return this.transport.statusText || '';
+ } catch (e) { return '' }
+ },
+
+ getHeader: Ajax.Request.prototype.getHeader,
+
+ getAllHeaders: function() {
+ try {
+ return this.getAllResponseHeaders();
+ } catch (e) { return null }
+ },
+
+ getResponseHeader: function(name) {
+ return this.transport.getResponseHeader(name);
+ },
+
+ getAllResponseHeaders: function() {
+ return this.transport.getAllResponseHeaders();
+ },
+
+ _getHeaderJSON: function() {
+ var json = this.getHeader('X-JSON');
+ if (!json) return null;
+ json = decodeURIComponent(escape(json));
+ try {
+ return json.evalJSON(this.request.options.sanitizeJSON ||
+ !this.request.isSameOrigin());
+ } catch (e) {
+ this.request.dispatchException(e);
+ }
+ },
+
+ _getResponseJSON: function() {
+ var options = this.request.options;
+ if (!options.evalJSON || (options.evalJSON != 'force' &&
+ !(this.getHeader('Content-type') || '').include('application/json')) ||
+ this.responseText.blank())
+ return null;
+ try {
+ return this.responseText.evalJSON(options.sanitizeJSON ||
+ !this.request.isSameOrigin());
+ } catch (e) {
+ this.request.dispatchException(e);
+ }
+ }
+});
+
+Ajax.Updater = Class.create(Ajax.Request, {
+ initialize: function($super, container, url, options) {
+ this.container = {
+ success: (container.success || container),
+ failure: (container.failure || (container.success ? null : container))
+ };
+
+ options = Object.clone(options);
+ var onComplete = options.onComplete;
+ options.onComplete = (function(response, json) {
+ this.updateContent(response.responseText);
+ if (Object.isFunction(onComplete)) onComplete(response, json);
+ }).bind(this);
+
+ $super(url, options);
+ },
+
+ updateContent: function(responseText) {
+ var receiver = this.container[this.success() ? 'success' : 'failure'],
+ options = this.options;
+
+ if (!options.evalScripts) responseText = responseText.stripScripts();
+
+ if (receiver = $(receiver)) {
+ if (options.insertion) {
+ if (Object.isString(options.insertion)) {
+ var insertion = { }; insertion[options.insertion] = responseText;
+ receiver.insert(insertion);
+ }
+ else options.insertion(receiver, responseText);
+ }
+ else receiver.update(responseText);
+ }
+ }
+});
+
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+ initialize: function($super, container, url, options) {
+ $super(options);
+ this.onComplete = this.options.onComplete;
+
+ this.frequency = (this.options.frequency || 2);
+ this.decay = (this.options.decay || 1);
+
+ this.updater = { };
+ this.container = container;
+ this.url = url;
+
+ this.start();
+ },
+
+ start: function() {
+ this.options.onComplete = this.updateComplete.bind(this);
+ this.onTimerEvent();
+ },
+
+ stop: function() {
+ this.updater.options.onComplete = undefined;
+ clearTimeout(this.timer);
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+ },
+
+ updateComplete: function(response) {
+ if (this.options.decay) {
+ this.decay = (response.responseText == this.lastText ?
+ this.decay * this.options.decay : 1);
+
+ this.lastText = response.responseText;
+ }
+ this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
+ },
+
+ onTimerEvent: function() {
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
+ }
+});
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
+ }
+ if (Object.isString(element))
+ element = document.getElementById(element);
+ return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+ document._getElementsByXPath = function(expression, parentElement) {
+ var results = [];
+ var query = document.evaluate(expression, $(parentElement) || document,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
+ results.push(Element.extend(query.snapshotItem(i)));
+ return results;
+ };
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Node) var Node = { };
+
+if (!Node.ELEMENT_NODE) {
+ // DOM level 2 ECMAScript Language Binding
+ Object.extend(Node, {
+ ELEMENT_NODE: 1,
+ ATTRIBUTE_NODE: 2,
+ TEXT_NODE: 3,
+ CDATA_SECTION_NODE: 4,
+ ENTITY_REFERENCE_NODE: 5,
+ ENTITY_NODE: 6,
+ PROCESSING_INSTRUCTION_NODE: 7,
+ COMMENT_NODE: 8,
+ DOCUMENT_NODE: 9,
+ DOCUMENT_TYPE_NODE: 10,
+ DOCUMENT_FRAGMENT_NODE: 11,
+ NOTATION_NODE: 12
+ });
+}
+
+(function() {
+ var element = this.Element;
+ this.Element = function(tagName, attributes) {
+ attributes = attributes || { };
+ tagName = tagName.toLowerCase();
+ var cache = Element.cache;
+ if (Prototype.Browser.IE && attributes.name) {
+ tagName = '<' + tagName + ' name="' + attributes.name + '">';
+ delete attributes.name;
+ return Element.writeAttribute(document.createElement(tagName), attributes);
+ }
+ if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+ return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+ };
+ Object.extend(this.Element, element || { });
+}).call(window);
+
+Element.cache = { };
+
+Element.Methods = {
+ visible: function(element) {
+ return $(element).style.display != 'none';
+ },
+
+ toggle: function(element) {
+ element = $(element);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ return element;
+ },
+
+ hide: function(element) {
+ $(element).style.display = 'none';
+ return element;
+ },
+
+ show: function(element) {
+ $(element).style.display = '';
+ return element;
+ },
+
+ remove: function(element) {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ return element;
+ },
+
+ update: function(element, content) {
+ element = $(element);
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) return element.update().insert(content);
+ content = Object.toHTML(content);
+ element.innerHTML = content.stripScripts();
+ content.evalScripts.bind(content).defer();
+ return element;
+ },
+
+ replace: function(element, content) {
+ element = $(element);
+ if (content && content.toElement) content = content.toElement();
+ else if (!Object.isElement(content)) {
+ content = Object.toHTML(content);
+ var range = element.ownerDocument.createRange();
+ range.selectNode(element);
+ content.evalScripts.bind(content).defer();
+ content = range.createContextualFragment(content.stripScripts());
+ }
+ element.parentNode.replaceChild(content, element);
+ return element;
+ },
+
+ 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 content, insert, tagName, childNodes;
+
+ for (var position in insertions) {
+ content = insertions[position];
+ position = position.toLowerCase();
+ insert = Element._insertionTranslations[position];
+
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) {
+ insert(element, content);
+ continue;
+ }
+
+ content = Object.toHTML(content);
+
+ 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();
+ }
+
+ return element;
+ },
+
+ wrap: function(element, wrapper, attributes) {
+ element = $(element);
+ if (Object.isElement(wrapper))
+ $(wrapper).writeAttribute(attributes || { });
+ else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+ else wrapper = new Element('div', wrapper);
+ if (element.parentNode)
+ element.parentNode.replaceChild(wrapper, element);
+ wrapper.appendChild(element);
+ return wrapper;
+ },
+
+ inspect: function(element) {
+ element = $(element);
+ var result = '<' + element.tagName.toLowerCase();
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+ var property = pair.first(), attribute = pair.last();
+ var value = (element[property] || '').toString();
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
+ });
+ return result + '>';
+ },
+
+ recursivelyCollect: function(element, property) {
+ element = $(element);
+ var elements = [];
+ while (element = element[property])
+ if (element.nodeType == 1)
+ elements.push(Element.extend(element));
+ return elements;
+ },
+
+ ancestors: function(element) {
+ return $(element).recursivelyCollect('parentNode');
+ },
+
+ descendants: function(element) {
+ return $(element).select("*");
+ },
+
+ firstDescendant: function(element) {
+ element = $(element).firstChild;
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ return $(element);
+ },
+
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
+ previousSiblings: function(element) {
+ return $(element).recursivelyCollect('previousSibling');
+ },
+
+ nextSiblings: function(element) {
+ return $(element).recursivelyCollect('nextSibling');
+ },
+
+ siblings: function(element) {
+ element = $(element);
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
+ },
+
+ match: function(element, selector) {
+ if (Object.isString(selector))
+ selector = new Selector(selector);
+ return selector.match($(element));
+ },
+
+ up: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(element.parentNode);
+ var ancestors = element.ancestors();
+ 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();
+ 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 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 Object.isNumber(expression) ? nextSiblings[expression] :
+ Selector.findElement(nextSiblings, expression, index);
+ },
+
+ select: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element, args);
+ },
+
+ adjacent: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element.parentNode, args).without(element);
+ },
+
+ identify: function(element) {
+ element = $(element);
+ var id = element.readAttribute('id'), self = arguments.callee;
+ if (id) return id;
+ do { id = 'anonymous_element_' + self.counter++ } while ($(id));
+ element.writeAttribute('id', id);
+ return id;
+ },
+
+ readAttribute: function(element, name) {
+ element = $(element);
+ if (Prototype.Browser.IE) {
+ var t = Element._attributeTranslations.read;
+ if (t.values[name]) return t.values[name](element, name);
+ if (t.names[name]) name = t.names[name];
+ if (name.include(':')) {
+ return (!element.attributes || !element.attributes[name]) ? null :
+ element.attributes[name].value;
+ }
+ }
+ return element.getAttribute(name);
+ },
+
+ writeAttribute: function(element, name, value) {
+ element = $(element);
+ var attributes = { }, t = Element._attributeTranslations.write;
+
+ if (typeof name == 'object') attributes = name;
+ else attributes[name] = Object.isUndefined(value) ? true : value;
+
+ for (var attr in attributes) {
+ 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);
+ else if (value === true)
+ element.setAttribute(name, name);
+ else element.setAttribute(name, value);
+ }
+ return element;
+ },
+
+ getHeight: function(element) {
+ return $(element).getDimensions().height;
+ },
+
+ getWidth: function(element) {
+ return $(element).getDimensions().width;
+ },
+
+ classNames: function(element) {
+ return new Element.ClassNames(element);
+ },
+
+ hasClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ var elementClassName = element.className;
+ return (elementClassName.length > 0 && (elementClassName == className ||
+ new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+ },
+
+ addClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ if (!element.hasClassName(className))
+ element.className += (element.className ? ' ' : '') + className;
+ return element;
+ },
+
+ removeClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ element.className = element.className.replace(
+ new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+ return element;
+ },
+
+ toggleClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return element[element.hasClassName(className) ?
+ 'removeClassName' : 'addClassName'](className);
+ },
+
+ // removes whitespace-only text node children
+ cleanWhitespace: function(element) {
+ element = $(element);
+ var node = element.firstChild;
+ while (node) {
+ var nextNode = node.nextSibling;
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+ element.removeChild(node);
+ node = nextNode;
+ }
+ return element;
+ },
+
+ empty: function(element) {
+ return $(element).innerHTML.blank();
+ },
+
+ descendantOf: function(element, ancestor) {
+ element = $(element), ancestor = $(ancestor);
+ var originalAncestor = ancestor;
+
+ if (element.compareDocumentPosition)
+ return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+ if (element.sourceIndex && !Prototype.Browser.Opera) {
+ var e = element.sourceIndex, a = ancestor.sourceIndex,
+ nextAncestor = ancestor.nextSibling;
+ if (!nextAncestor) {
+ do { ancestor = ancestor.parentNode; }
+ while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
+ }
+ if (nextAncestor && nextAncestor.sourceIndex)
+ return (e > a && e < nextAncestor.sourceIndex);
+ }
+
+ while (element = element.parentNode)
+ if (element == originalAncestor) return true;
+ return false;
+ },
+
+ scrollTo: function(element) {
+ element = $(element);
+ var pos = element.cumulativeOffset();
+ window.scrollTo(pos[0], pos[1]);
+ return element;
+ },
+
+ getStyle: function(element, style) {
+ element = $(element);
+ style = style == 'float' ? 'cssFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value) {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css[style] : null;
+ }
+ if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+ return value == 'auto' ? null : value;
+ },
+
+ getOpacity: function(element) {
+ return $(element).getStyle('opacity');
+ },
+
+ setStyle: function(element, styles) {
+ element = $(element);
+ var elementStyle = element.style, match;
+ if (Object.isString(styles)) {
+ element.style.cssText += ';' + styles;
+ return styles.include('opacity') ?
+ element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+ }
+ for (var property in styles)
+ if (property == 'opacity') element.setOpacity(styles[property]);
+ else
+ elementStyle[(property == 'float' || property == 'cssFloat') ?
+ (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
+ property] = styles[property];
+
+ return element;
+ },
+
+ setOpacity: function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1 || value === '') ? '' :
+ (value < 0.00001) ? 0 : value;
+ return element;
+ },
+
+ getDimensions: function(element) {
+ element = $(element);
+ var display = $(element).getStyle('display');
+ if (display != 'none' && display != null) // Safari bug
+ return {width: element.offsetWidth, height: element.offsetHeight};
+
+ // All *Width and *Height properties give 0 on elements with display none,
+ // so enable the element temporarily
+ var els = element.style;
+ var originalVisibility = els.visibility;
+ var originalPosition = els.position;
+ var originalDisplay = els.display;
+ els.visibility = 'hidden';
+ els.position = 'absolute';
+ els.display = 'block';
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ els.display = originalDisplay;
+ els.position = originalPosition;
+ els.visibility = originalVisibility;
+ return {width: originalWidth, height: originalHeight};
+ },
+
+ makePositioned: function(element) {
+ element = $(element);
+ var pos = Element.getStyle(element, 'position');
+ if (pos == 'static' || !pos) {
+ element._madePositioned = true;
+ element.style.position = 'relative';
+ // Opera returns the offset relative to the positioning context, when an
+ // element is position relative but top and left have not been defined
+ if (window.opera) {
+ element.style.top = 0;
+ element.style.left = 0;
+ }
+ }
+ return element;
+ },
+
+ undoPositioned: function(element) {
+ element = $(element);
+ if (element._madePositioned) {
+ element._madePositioned = undefined;
+ element.style.position =
+ element.style.top =
+ element.style.left =
+ element.style.bottom =
+ element.style.right = '';
+ }
+ return element;
+ },
+
+ makeClipping: function(element) {
+ element = $(element);
+ if (element._overflow) return element;
+ element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+ if (element._overflow !== 'hidden')
+ element.style.overflow = 'hidden';
+ return element;
+ },
+
+ undoClipping: function(element) {
+ element = $(element);
+ if (!element._overflow) return element;
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+ element._overflow = null;
+ return element;
+ },
+
+ cumulativeOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return Element._returnOffset(valueL, valueT);
+ },
+
+ positionedOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ if (element.tagName == 'BODY') break;
+ var p = Element.getStyle(element, 'position');
+ if (p !== 'static') break;
+ }
+ } while (element);
+ return Element._returnOffset(valueL, valueT);
+ },
+
+ absolutize: function(element) {
+ element = $(element);
+ if (element.getStyle('position') == 'absolute') return;
+ // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+ var offsets = element.positionedOffset();
+ var top = offsets[1];
+ var left = offsets[0];
+ var width = element.clientWidth;
+ var height = element.clientHeight;
+
+ element._originalLeft = left - parseFloat(element.style.left || 0);
+ element._originalTop = top - parseFloat(element.style.top || 0);
+ element._originalWidth = element.style.width;
+ element._originalHeight = element.style.height;
+
+ element.style.position = 'absolute';
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.width = width + 'px';
+ element.style.height = height + 'px';
+ return element;
+ },
+
+ relativize: function(element) {
+ element = $(element);
+ if (element.getStyle('position') == 'relative') return;
+ // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+ element.style.position = 'relative';
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.height = element._originalHeight;
+ element.style.width = element._originalWidth;
+ return element;
+ },
+
+ cumulativeScrollOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return Element._returnOffset(valueL, valueT);
+ },
+
+ getOffsetParent: function(element) {
+ if (element.offsetParent) return $(element.offsetParent);
+ if (element == document.body) return $(element);
+
+ while ((element = element.parentNode) && element != document.body
+ && Object.isElement(element)/* changed by Nick - http://dev.rubyonrails.org/ticket/11007 */)
+ if (Element.getStyle(element, 'position') != 'static')
+ return $(element);
+
+ return $(document.body);
+ },
+
+ viewportOffset: function(forElement) {
+ var valueT = 0, valueL = 0;
+
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ // Safari fix
+ if (element.offsetParent == document.body &&
+ Element.getStyle(element, 'position') == 'absolute') break;
+
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ }
+ } while (element = element.parentNode);
+
+ return Element._returnOffset(valueL, valueT);
+ },
+
+ clonePosition: function(element, source) {
+ var options = Object.extend({
+ setLeft: true,
+ setTop: true,
+ setWidth: true,
+ setHeight: true,
+ offsetTop: 0,
+ offsetLeft: 0
+ }, arguments[2] || { });
+
+ // find page position of source
+ source = $(source);
+ var p = source.viewportOffset();
+
+ // find coordinate system to use
+ element = $(element);
+ var delta = [0, 0];
+ var parent = null;
+ // delta [0,0] will do fine with position: fixed elements,
+ // position:absolute needs offsetParent deltas
+ if (Element.getStyle(element, 'position') == 'absolute') {
+ parent = element.getOffsetParent();
+ delta = parent.viewportOffset();
+ }
+
+ // correct by body offsets (fixes Safari)
+ if (parent == document.body) {
+ delta[0] -= document.body.offsetLeft;
+ delta[1] -= document.body.offsetTop;
+ }
+
+ // set position
+ if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
+ if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
+ if (options.setWidth) element.style.width = source.offsetWidth + 'px';
+ if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+ return element;
+ }
+};
+
+Element.Methods.identify.counter = 1;
+
+Object.extend(Element.Methods, {
+ getElementsBySelector: Element.Methods.select,
+ childElements: Element.Methods.immediateDescendants
+});
+
+Element._attributeTranslations = {
+ write: {
+ names: {
+ className: 'class',
+ htmlFor: 'for'
+ },
+ values: { }
+ }
+};
+
+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);
+ }
+ }
+ );
+
+ Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
+ function(proceed, element, attribute) {
+ if (attribute === 'title') return element.title;
+ return proceed(element, attribute);
+ }
+ );
+}
+
+else if (Prototype.Browser.IE) {
+ // 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);
+ // 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 });
+ return value;
+ }
+ );
+ });
+
+ Element.Methods.getStyle = function(element, style) {
+ element = $(element);
+ style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value && element.currentStyle) value = element.currentStyle[style];
+
+ if (style == 'opacity') {
+ if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if (value[1]) return parseFloat(value[1]) / 100;
+ return 1.0;
+ }
+
+ if (value == 'auto') {
+ if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+ return element['offset' + style.capitalize()] + 'px';
+ return null;
+ }
+ return value;
+ };
+
+ Element.Methods.setOpacity = function(element, value) {
+ function stripAlpha(filter){
+ return filter.replace(/alpha\([^\)]*\)/gi,'');
+ }
+ element = $(element);
+ var currentStyle = element.currentStyle;
+ if ((currentStyle && !currentStyle.hasLayout) ||
+ (!currentStyle && element.style.zoom == 'normal'))
+ element.style.zoom = 1;
+
+ var filter = element.getStyle('filter'), style = element.style;
+ if (value == 1 || value === '') {
+ (filter = stripAlpha(filter)) ?
+ style.filter = filter : style.removeAttribute('filter');
+ return element;
+ } else if (value < 0.00001) value = 0;
+ style.filter = stripAlpha(filter) +
+ 'alpha(opacity=' + (value * 100) + ')';
+ return element;
+ };
+
+ Element._attributeTranslations = {
+ read: {
+ names: {
+ 'class': 'className',
+ 'for': 'htmlFor'
+ },
+ values: {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+ _getAttrNode: function(element, attribute) {
+ var node = element.getAttributeNode(attribute);
+ return node ? node.value : "";
+ },
+ _getEv: function(element, attribute) {
+ attribute = element.getAttribute(attribute);
+ return attribute ? attribute.toString().slice(23, -2) : null;
+ },
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+ title: function(element) {
+ return element.title;
+ }
+ }
+ }
+ };
+
+ Element._attributeTranslations.write = {
+ names: Object.extend({
+ cellpadding: 'cellPadding',
+ cellspacing: 'cellSpacing'
+ }, Element._attributeTranslations.read.names),
+ values: {
+ checked: function(element, value) {
+ element.checked = !!value;
+ },
+
+ style: function(element, value) {
+ element.style.cssText = value ? value : '';
+ }
+ }
+ };
+
+ Element._attributeTranslations.has = {};
+
+ $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+ 'encType maxLength readOnly longDesc').each(function(attr) {
+ Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+ Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+ });
+
+ (function(v) {
+ Object.extend(v, {
+ href: v._getAttr,
+ src: v._getAttr,
+ type: v._getAttr,
+ action: v._getAttrNode,
+ disabled: v._flag,
+ checked: v._flag,
+ readonly: v._flag,
+ multiple: v._flag,
+ onload: v._getEv,
+ onunload: v._getEv,
+ onclick: v._getEv,
+ ondblclick: v._getEv,
+ onmousedown: v._getEv,
+ onmouseup: v._getEv,
+ onmouseover: v._getEv,
+ onmousemove: v._getEv,
+ onmouseout: v._getEv,
+ onfocus: v._getEv,
+ onblur: v._getEv,
+ onkeypress: v._getEv,
+ onkeydown: v._getEv,
+ onkeyup: v._getEv,
+ onsubmit: v._getEv,
+ onreset: v._getEv,
+ onselect: v._getEv,
+ onchange: v._getEv
+ });
+ })(Element._attributeTranslations.read.values);
+}
+
+else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1) ? 0.999999 :
+ (value === '') ? '' : (value < 0.00001) ? 0 : value;
+ return element;
+ };
+}
+
+else if (Prototype.Browser.WebKit) {
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1 || value === '') ? '' :
+ (value < 0.00001) ? 0 : value;
+
+ if (value == 1)
+ if(element.tagName == 'IMG' && element.width) {
+ element.width++; element.width--;
+ } else try {
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch (e) { }
+
+ return element;
+ };
+
+ // Safari returns margins on body which is incorrect if the child is absolutely
+ // positioned. For performance reasons, redefine Element#cumulativeOffset for
+ // KHTML/WebKit only.
+ Element.Methods.cumulativeOffset = function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if (element.offsetParent == document.body)
+ if (Element.getStyle(element, 'position') == 'absolute') break;
+
+ element = element.offsetParent;
+ } while (element);
+
+ return Element._returnOffset(valueL, valueT);
+ };
+}
+
+if (Prototype.Browser.IE || Prototype.Browser.Opera) {
+ // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
+ Element.Methods.update = function(element, content) {
+ element = $(element);
+
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) return element.update().insert(content);
+
+ content = Object.toHTML(content);
+ var tagName = element.tagName.toUpperCase();
+
+ if (tagName in Element._insertionTranslations.tags) {
+ $A(element.childNodes).each(function(node) { element.removeChild(node) });
+ Element._getContentFromAnonymousElement(tagName, content.stripScripts())
+ .each(function(node) { element.appendChild(node) });
+ }
+ else element.innerHTML = content.stripScripts();
+
+ content.evalScripts.bind(content).defer();
+ return element;
+ };
+}
+
+if ('outerHTML' in document.createElement('div')) {
+ Element.Methods.replace = function(element, content) {
+ element = $(element);
+
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) {
+ element.parentNode.replaceChild(content, element);
+ return element;
+ }
+
+ content = Object.toHTML(content);
+ var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+ if (Element._insertionTranslations.tags[tagName]) {
+ var nextSibling = element.next();
+ var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+ parent.removeChild(element);
+ if (nextSibling)
+ fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
+ else
+ fragments.each(function(node) { parent.appendChild(node) });
+ }
+ else element.outerHTML = content.stripScripts();
+
+ content.evalScripts.bind(content).defer();
+ return element;
+ };
+}
+
+Element._returnOffset = function(l, t) {
+ var result = [l, t];
+ result.left = l;
+ result.top = t;
+ return result;
+};
+
+Element._getContentFromAnonymousElement = function(tagName, html) {
+ var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
+ 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: function(element, node) {
+ element.parentNode.insertBefore(node, element);
+ },
+ top: function(element, node) {
+ element.insertBefore(node, element.firstChild);
+ },
+ bottom: function(element, node) {
+ element.appendChild(node);
+ },
+ after: function(element, node) {
+ element.parentNode.insertBefore(node, element.nextSibling);
+ },
+ tags: {
+ TABLE: ['<table>', '</table>', 1],
+ TBODY: ['<table><tbody>', '</tbody></table>', 2],
+ TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
+ TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
+ SELECT: ['<select>', '</select>', 1]
+ }
+};
+
+(function() {
+ Object.extend(this.tags, {
+ THEAD: this.tags.TBODY,
+ TFOOT: this.tags.TBODY,
+ TH: this.tags.TD
+ });
+}).call(Element._insertionTranslations);
+
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ attribute = Element._attributeTranslations.has[attribute] || attribute;
+ var node = $(element).getAttributeNode(attribute);
+ return node && node.specified;
+ }
+};
+
+Element.Methods.ByTag = { };
+
+Object.extend(Element, Element.Methods);
+
+if (!Prototype.BrowserFeatures.ElementExtensions &&
+ document.createElement('div').__proto__) {
+ window.HTMLElement = { };
+ window.HTMLElement.prototype = document.createElement('div').__proto__;
+ Prototype.BrowserFeatures.ElementExtensions = true;
+}
+
+Element.extend = (function() {
+ if (Prototype.BrowserFeatures.SpecificElementExtensions)
+ return Prototype.K;
+
+ var Methods = { }, ByTag = Element.Methods.ByTag;
+
+ var extend = Object.extend(function(element) {
+ if (!element || element._extendedByPrototype ||
+ element.nodeType != 1 || element == window) return element;
+
+ var methods = Object.clone(Methods),
+ tagName = element.tagName, property, value;
+
+ // extend methods for specific tags
+ if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
+
+ for (property in methods) {
+ value = methods[property];
+ if (Object.isFunction(value) && !(property in element))
+ element[property] = value.methodize();
+ }
+
+ element._extendedByPrototype = Prototype.emptyFunction;
+ return element;
+
+ }, {
+ refresh: function() {
+ // extend methods for all tags (Safari doesn't need this)
+ if (!Prototype.BrowserFeatures.ElementExtensions) {
+ Object.extend(Methods, Element.Methods);
+ Object.extend(Methods, Element.Methods.Simulated);
+ }
+ }
+ });
+
+ extend.refresh();
+ return extend;
+})();
+
+Element.hasAttribute = function(element, attribute) {
+ if (element.hasAttribute) return element.hasAttribute(attribute);
+ return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
+Element.addMethods = function(methods) {
+ var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+ if (!methods) {
+ Object.extend(Form, Form.Methods);
+ Object.extend(Form.Element, Form.Element.Methods);
+ Object.extend(Element.Methods.ByTag, {
+ "FORM": Object.clone(Form.Methods),
+ "INPUT": Object.clone(Form.Element.Methods),
+ "SELECT": Object.clone(Form.Element.Methods),
+ "TEXTAREA": Object.clone(Form.Element.Methods)
+ });
+ }
+
+ if (arguments.length == 2) {
+ var tagName = methods;
+ methods = arguments[1];
+ }
+
+ if (!tagName) Object.extend(Element.Methods, methods || { });
+ else {
+ if (Object.isArray(tagName)) tagName.each(extend);
+ else extend(tagName);
+ }
+
+ function extend(tagName) {
+ tagName = tagName.toUpperCase();
+ if (!Element.Methods.ByTag[tagName])
+ Element.Methods.ByTag[tagName] = { };
+ Object.extend(Element.Methods.ByTag[tagName], methods);
+ }
+
+ function copy(methods, destination, onlyIfAbsent) {
+ onlyIfAbsent = onlyIfAbsent || false;
+ for (var property in methods) {
+ var value = methods[property];
+ if (!Object.isFunction(value)) continue;
+ if (!onlyIfAbsent || !(property in destination))
+ destination[property] = value.methodize();
+ }
+ }
+
+ function findDOMClass(tagName) {
+ var klass;
+ var trans = {
+ "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+ "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+ "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+ "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+ "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+ "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+ "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+ "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+ "FrameSet", "IFRAME": "IFrame"
+ };
+ if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName.capitalize() + 'Element';
+ if (window[klass]) return window[klass];
+
+ window[klass] = { };
+ window[klass].prototype = document.createElement(tagName).__proto__;
+ return window[klass];
+ }
+
+ if (F.ElementExtensions) {
+ copy(Element.Methods, HTMLElement.prototype);
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+ }
+
+ if (F.SpecificElementExtensions) {
+ for (var tag in Element.Methods.ByTag) {
+ var klass = findDOMClass(tag);
+ if (Object.isUndefined(klass)) continue;
+ copy(T[tag], klass.prototype);
+ }
+ }
+
+ Object.extend(Element, Element.Methods);
+ delete Element.ByTag;
+
+ if (Element.extend.refresh) Element.extend.refresh();
+ Element.cache = { };
+};
+
+document.viewport = {
+ getDimensions: function() {
+ var dimensions = { };
+ var B = Prototype.Browser;
+ $w('width height').each(function(d) {
+ var D = d.capitalize();
+ dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
+ (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
+ });
+ return dimensions;
+ },
+
+ getWidth: function() {
+ return this.getDimensions().width;
+ },
+
+ getHeight: function() {
+ return this.getDimensions().height;
+ },
+
+ getScrollOffsets: function() {
+ return Element._returnOffset(
+ window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
+ window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
+ }
+};
+/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+ * license. Please see http://www.yui-ext.com/ for more information. */
+
+var Selector = Class.create({
+ initialize: function(expression) {
+ this.expression = expression.strip();
+ 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() {
+ if (this.shouldUseXPath())
+ return this.compileXPathMatcher();
+
+ var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
+ c = Selector.criteria, le, p, m;
+
+ if (Selector._cache[e]) {
+ this.matcher = Selector._cache[e];
+ return;
+ }
+
+ this.matcher = ["this.matcher = function(root) {",
+ "var r = root, h = Selector.handlers, c = false, n;"];
+
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ p = ps[i];
+ if (m = e.match(p)) {
+ this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
+ new Template(c[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.matcher.push("return h.unique(n);\n}");
+ eval(this.matcher.join('\n'));
+ Selector._cache[this.expression] = this.matcher;
+ },
+
+ compileXPathMatcher: function() {
+ var e = this.expression, ps = Selector.patterns,
+ x = Selector.xpath, le, m;
+
+ if (Selector._cache[e]) {
+ this.xpath = Selector._cache[e]; return;
+ }
+
+ this.matcher = ['.//*'];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ if (m = e.match(ps[i])) {
+ this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
+ new Template(x[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.xpath = this.matcher.join('');
+ Selector._cache[this.expression] = this.xpath;
+ },
+
+ findElements: function(root) {
+ root = root || document;
+ if (this.xpath) return document._getElementsByXPath(this.xpath, root);
+ return this.matcher(root);
+ },
+
+ match: function(element) {
+ this.tokens = [];
+
+ var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
+ var le, p, m;
+
+ while (e && le !== e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ p = ps[i];
+ if (m = e.match(p)) {
+ // use the Selector.assertions methods unless the selector
+ // is too complex.
+ if (as[i]) {
+ this.tokens.push([i, Object.clone(m)]);
+ e = e.replace(m[0], '');
+ } else {
+ // reluctantly do a document-wide search
+ // and look for a match in the array
+ return this.findElements(document).include(element);
+ }
+ }
+ }
+ }
+
+ var match = true, name, matches;
+ for (var i = 0, token; token = this.tokens[i]; i++) {
+ name = token[0], matches = token[1];
+ if (!Selector.assertions[name](element, matches)) {
+ match = false; break;
+ }
+ }
+
+ return match;
+ },
+
+ toString: function() {
+ return this.expression;
+ },
+
+ inspect: function() {
+ return "#<Selector:" + this.expression.inspect() + ">";
+ }
+});
+
+Object.extend(Selector, {
+ _cache: { },
+
+ xpath: {
+ descendant: "//*",
+ child: "/*",
+ adjacent: "/following-sibling::*[1]",
+ laterSibling: '/following-sibling::*',
+ tagName: function(m) {
+ if (m[1] == '*') return '';
+ return "[local-name()='" + m[1].toLowerCase() +
+ "' or local-name()='" + m[1].toUpperCase() + "']";
+ },
+ className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+ id: "[@id='#{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);
+ },
+ pseudo: function(m) {
+ var h = Selector.xpath.pseudos[m[1]];
+ if (!h) return '';
+ if (Object.isFunction(h)) return h(m);
+ return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+ },
+ operators: {
+ '=': "[@#{1}='#{3}']",
+ '!=': "[@#{1}!='#{3}']",
+ '^=': "[starts-with(@#{1}, '#{3}')]",
+ '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+ '*=': "[contains(@#{1}, '#{3}')]",
+ '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+ '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+ },
+ pseudos: {
+ 'first-child': '[not(preceding-sibling::*)]',
+ 'last-child': '[not(following-sibling::*)]',
+ 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
+ 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
+ 'checked': "[@checked]",
+ 'disabled': "[@disabled]",
+ 'enabled': "[not(@disabled)]",
+ 'not': function(m) {
+ var e = m[6], p = Selector.patterns,
+ x = Selector.xpath, le, v;
+
+ var exclusion = [];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in p) {
+ if (m = e.match(p[i])) {
+ v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
+ exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+ return "[not(" + exclusion.join(" and ") + ")]";
+ },
+ 'nth-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+ },
+ 'nth-last-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+ },
+ 'nth-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("position() ", m);
+ },
+ 'nth-last-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+ },
+ 'first-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+ },
+ 'last-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+ },
+ 'only-of-type': function(m) {
+ var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+ },
+ nth: function(fragment, m) {
+ var mm, formula = m[6], predicate;
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ if (mm = formula.match(/^(\d+)$/)) // digit only
+ return '[' + fragment + "= " + mm[1] + ']';
+ if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (mm[1] == "-") mm[1] = -1;
+ var a = mm[1] ? Number(mm[1]) : 1;
+ var b = mm[2] ? Number(mm[2]) : 0;
+ predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+ "((#{fragment} - #{b}) div #{a} >= 0)]";
+ return new Template(predicate).evaluate({
+ fragment: fragment, a: a, b: b });
+ }
+ }
+ }
+ },
+
+ 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); c = false;',
+ attr: function(m) {
+ m[3] = (m[5] || m[6]);
+ 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, '\\"');
+ return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+ },
+ descendant: 'c = "descendant";',
+ child: 'c = "child";',
+ adjacent: 'c = "adjacent";',
+ laterSibling: 'c = "laterSibling";'
+ },
+
+ patterns: {
+ // combinators must be listed first
+ // (and descendant needs to be last combinator)
+ laterSibling: /^\s*~\s*/,
+ child: /^\s*>\s*/,
+ adjacent: /^\s*\+\s*/,
+ descendant: /^\s/,
+
+ // selectors follow
+ 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|[:+~>]))/,
+ attrPresence: /^\[([\w]+)\]/,
+ attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
+ },
+
+ // for Selector.match and Element#match
+ assertions: {
+ tagName: function(element, matches) {
+ return matches[1].toUpperCase() == element.tagName.toUpperCase();
+ },
+
+ className: function(element, matches) {
+ return Element.hasClassName(element, matches[1]);
+ },
+
+ id: function(element, matches) {
+ return element.id === matches[1];
+ },
+
+ attrPresence: function(element, matches) {
+ return Element.hasAttribute(element, matches[1]);
+ },
+
+ attr: function(element, matches) {
+ var nodeValue = Element.readAttribute(element, matches[1]);
+ return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
+ }
+ },
+
+ handlers: {
+ // UTILITY FUNCTIONS
+ // joins two collections
+ concat: function(a, b) {
+ for (var i = 0, node; node = b[i]; i++)
+ a.push(node);
+ return a;
+ },
+
+ // marks an array of nodes for counting
+ mark: function(nodes) {
+ var _true = Prototype.emptyFunction;
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._countedByPrototype = _true;
+ return nodes;
+ },
+
+ unmark: function(nodes) {
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._countedByPrototype = undefined;
+ return nodes;
+ },
+
+ // mark each child node with its position (for nth calls)
+ // "ofType" flag indicates whether we're indexing for nth-of-type
+ // rather than nth-child
+ index: function(parentNode, reverse, ofType) {
+ 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._countedByPrototype)) node.nodeIndex = j++;
+ }
+ } else {
+ for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+ if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
+ }
+ },
+
+ // filters out duplicates and extends all nodes
+ unique: function(nodes) {
+ if (nodes.length == 0) return nodes;
+ var results = [], n;
+ for (var i = 0, l = nodes.length; i < l; i++)
+ if (!(n = nodes[i])._countedByPrototype) {
+ n._countedByPrototype = Prototype.emptyFunction;
+ results.push(Element.extend(n));
+ }
+ return Selector.handlers.unmark(results);
+ },
+
+ // COMBINATOR FUNCTIONS
+ descendant: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName('*'));
+ return results;
+ },
+
+ child: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ for (var j = 0, child; child = node.childNodes[j]; j++)
+ if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+ }
+ return results;
+ },
+
+ adjacent: function(nodes) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ var next = this.nextElementSibling(node);
+ if (next) results.push(next);
+ }
+ return results;
+ },
+
+ laterSibling: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, Element.nextSiblings(node));
+ return results;
+ },
+
+ nextElementSibling: function(node) {
+ while (node = node.nextSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ previousElementSibling: function(node) {
+ while (node = node.previousSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ // TOKEN FUNCTIONS
+ tagName: function(nodes, root, tagName, combinator) {
+ var uTagName = tagName.toUpperCase();
+ var results = [], h = Selector.handlers;
+ if (nodes) {
+ if (combinator) {
+ // fastlane for ordinary descendant combinators
+ if (combinator == "descendant") {
+ for (var i = 0, node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName(tagName));
+ return results;
+ } else nodes = this[combinator](nodes);
+ if (tagName == "*") return nodes;
+ }
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.tagName.toUpperCase() === uTagName) results.push(node);
+ return results;
+ } else return root.getElementsByTagName(tagName);
+ },
+
+ id: function(nodes, root, id, combinator) {
+ var targetNode = $(id), h = Selector.handlers;
+ if (!targetNode) return [];
+ if (!nodes && root == document) return [targetNode];
+ if (nodes) {
+ if (combinator) {
+ if (combinator == 'child') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (targetNode.parentNode == node) return [targetNode];
+ } else if (combinator == 'descendant') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Element.descendantOf(targetNode, node)) return [targetNode];
+ } else if (combinator == 'adjacent') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Selector.handlers.previousElementSibling(targetNode) == node)
+ return [targetNode];
+ } else nodes = h[combinator](nodes);
+ }
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node == targetNode) return [targetNode];
+ return [];
+ }
+ return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+ },
+
+ className: function(nodes, root, className, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ return Selector.handlers.byClassName(nodes, root, className);
+ },
+
+ byClassName: function(nodes, root, className) {
+ if (!nodes) nodes = Selector.handlers.descendant([root]);
+ var needle = ' ' + className + ' ';
+ for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+ nodeClassName = node.className;
+ if (nodeClassName.length == 0) continue;
+ if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+ results.push(node);
+ }
+ return results;
+ },
+
+ 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, 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);
+ if (nodeValue === null) continue;
+ if (handler(nodeValue, value)) results.push(node);
+ }
+ return results;
+ },
+
+ pseudo: function(nodes, name, value, root, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ return Selector.pseudos[name](nodes, value, root);
+ }
+ },
+
+ pseudos: {
+ 'first-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.previousElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'last-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.nextElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'only-child': function(nodes, value, root) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+ results.push(node);
+ return results;
+ },
+ 'nth-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root);
+ },
+ 'nth-last-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true);
+ },
+ 'nth-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, false, true);
+ },
+ 'nth-last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true, true);
+ },
+ 'first-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, false, true);
+ },
+ 'last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, true, true);
+ },
+ 'only-of-type': function(nodes, formula, root) {
+ var p = Selector.pseudos;
+ return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+ },
+
+ // handles the an+b logic
+ getIndices: function(a, b, total) {
+ if (a == 0) return b > 0 ? [b] : [];
+ return $R(1, total).inject([], function(memo, i) {
+ if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+ return memo;
+ });
+ },
+
+ // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+ nth: function(nodes, formula, root, reverse, ofType) {
+ if (nodes.length == 0) return [];
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ var h = Selector.handlers, results = [], indexed = [], m;
+ h.mark(nodes);
+ for (var i = 0, node; node = nodes[i]; i++) {
+ if (!node.parentNode._countedByPrototype) {
+ h.index(node.parentNode, reverse, ofType);
+ indexed.push(node.parentNode);
+ }
+ }
+ if (formula.match(/^\d+$/)) { // just a number
+ formula = Number(formula);
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.nodeIndex == formula) results.push(node);
+ } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (m[1] == "-") m[1] = -1;
+ var a = m[1] ? Number(m[1]) : 1;
+ var b = m[2] ? Number(m[2]) : 0;
+ var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+ for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+ for (var j = 0; j < l; j++)
+ if (node.nodeIndex == indices[j]) results.push(node);
+ }
+ }
+ h.unmark(nodes);
+ h.unmark(indexed);
+ return results;
+ },
+
+ 'empty': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ // IE treats comments as element nodes
+ if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
+ results.push(node);
+ }
+ return results;
+ },
+
+ 'not': function(nodes, selector, root) {
+ var h = Selector.handlers, selectorType, m;
+ var exclusions = new Selector(selector).findElements(root);
+ h.mark(exclusions);
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node._countedByPrototype) results.push(node);
+ h.unmark(exclusions);
+ return results;
+ },
+
+ 'enabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node.disabled) results.push(node);
+ return results;
+ },
+
+ 'disabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.disabled) results.push(node);
+ return results;
+ },
+
+ 'checked': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.checked) results.push(node);
+ return results;
+ }
+ },
+
+ operators: {
+ '=': function(nv, v) { return nv == v; },
+ '!=': function(nv, v) { return nv != v; },
+ '^=': function(nv, v) { return nv.startsWith(v); },
+ '$=': function(nv, v) { return nv.endsWith(v); },
+ '*=': function(nv, v) { return nv.include(v); },
+ '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
+ '|=': 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 = $$(expression), h = Selector.handlers;
+ h.mark(matches);
+ for (var i = 0, results = [], element; element = elements[i]; i++)
+ if (element._countedByPrototype) results.push(element);
+ h.unmark(matches);
+ return results;
+ },
+
+ findElement: function(elements, expression, index) {
+ if (Object.isNumber(expression)) {
+ index = expression; expression = false;
+ }
+ return Selector.matchElements(elements, expression || '*')[index || 0];
+ },
+
+ findChildElements: function(element, expressions) {
+ 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());
+ h.concat(results, selector.findElements(element));
+ }
+ return (l > 1) ? h.unique(results) : results;
+ }
+});
+
+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));
+}
+var Form = {
+ reset: function(form) {
+ $(form).reset();
+ return form;
+ },
+
+ serializeElements: function(elements, options) {
+ if (typeof options != 'object') options = { hash: !!options };
+ else if (Object.isUndefined(options.hash)) options.hash = true;
+ var key, value, submitted = false, submit = options.submit;
+
+ var data = elements.inject({ }, function(result, element) {
+ if (!element.disabled && element.name) {
+ key = element.name; value = $(element).getValue();
+ if (value != null && (element.type != 'submit' || (!submitted &&
+ submit !== false && (!submit || key == submit) && (submitted = true)))) {
+ if (key in result) {
+ // a key is already present; construct an array of values
+ if (!Object.isArray(result[key])) result[key] = [result[key]];
+ result[key].push(value);
+ }
+ else result[key] = value;
+ }
+ }
+ return result;
+ });
+
+ return options.hash ? data : Object.toQueryString(data);
+ }
+};
+
+Form.Methods = {
+ serialize: function(form, options) {
+ return Form.serializeElements(Form.getElements(form), options);
+ },
+
+ getElements: function(form) {
+ return $A($(form).getElementsByTagName('*')).inject([],
+ function(elements, child) {
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ }
+ );
+ },
+
+ getInputs: function(form, typeName, name) {
+ form = $(form);
+ var inputs = form.getElementsByTagName('input');
+
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+ var input = inputs[i];
+ if ((typeName && input.type != typeName) || (name && input.name != name))
+ continue;
+ matchingInputs.push(Element.extend(input));
+ }
+
+ return matchingInputs;
+ },
+
+ disable: function(form) {
+ form = $(form);
+ Form.getElements(form).invoke('disable');
+ return form;
+ },
+
+ enable: function(form) {
+ form = $(form);
+ Form.getElements(form).invoke('enable');
+ return form;
+ },
+
+ findFirstElement: function(form) {
+ var elements = $(form).getElements().findAll(function(element) {
+ return 'hidden' != element.type && !element.disabled;
+ });
+ var firstByIndex = elements.findAll(function(element) {
+ return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+ }).sortBy(function(element) { return element.tabIndex }).first();
+
+ return firstByIndex ? firstByIndex : elements.find(function(element) {
+ return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
+ focusFirstElement: function(form) {
+ form = $(form);
+ form.findFirstElement().activate();
+ return form;
+ },
+
+ request: function(form, options) {
+ form = $(form), options = Object.clone(options || { });
+
+ var params = options.parameters, action = form.readAttribute('action') || '';
+ if (action.blank()) action = window.location.href;
+ options.parameters = form.serialize(true);
+
+ if (params) {
+ if (Object.isString(params)) params = params.toQueryParams();
+ Object.extend(options.parameters, params);
+ }
+
+ if (form.hasAttribute('method') && !options.method)
+ options.method = form.method;
+
+ return new Ajax.Request(action, options);
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+ focus: function(element) {
+ $(element).focus();
+ return element;
+ },
+
+ select: function(element) {
+ $(element).select();
+ return element;
+ }
+};
+
+Form.Element.Methods = {
+ serialize: function(element) {
+ element = $(element);
+ if (!element.disabled && element.name) {
+ var value = element.getValue();
+ if (value != undefined) {
+ var pair = { };
+ pair[element.name] = value;
+ return Object.toQueryString(pair);
+ }
+ }
+ return '';
+ },
+
+ getValue: function(element) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ return Form.Element.Serializers[method](element);
+ },
+
+ setValue: function(element, value) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ Form.Element.Serializers[method](element, value);
+ return element;
+ },
+
+ clear: function(element) {
+ $(element).value = '';
+ return element;
+ },
+
+ present: function(element) {
+ return $(element).value != '';
+ },
+
+ activate: function(element) {
+ element = $(element);
+ try {
+ element.focus();
+ if (element.select && (element.tagName.toLowerCase() != 'input' ||
+ !['button', 'reset', 'submit'].include(element.type)))
+ element.select();
+ } catch (e) { }
+ return element;
+ },
+
+ disable: function(element) {
+ element = $(element);
+ element.blur();
+ element.disabled = true;
+ return element;
+ },
+
+ enable: function(element) {
+ element = $(element);
+ element.disabled = false;
+ return element;
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+var $F = Form.Element.Methods.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+ input: function(element, value) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ return Form.Element.Serializers.inputSelector(element, value);
+ default:
+ return Form.Element.Serializers.textarea(element, value);
+ }
+ },
+
+ inputSelector: function(element, value) {
+ if (Object.isUndefined(value)) return element.checked ? element.value : null;
+ else element.checked = !!value;
+ },
+
+ textarea: function(element, value) {
+ if (Object.isUndefined(value)) return element.value;
+ else element.value = value;
+ },
+
+ select: function(element, index) {
+ if (Object.isUndefined(index))
+ return this[element.type == 'select-one' ?
+ 'selectOne' : 'selectMany'](element);
+ else {
+ var opt, value, single = !Object.isArray(index);
+ for (var i = 0, length = element.length; i < length; i++) {
+ opt = element.options[i];
+ value = this.optionValue(opt);
+ if (single) {
+ if (value == index) {
+ opt.selected = true;
+ return;
+ }
+ }
+ else opt.selected = index.include(value);
+ }
+ }
+ },
+
+ selectOne: function(element) {
+ var index = element.selectedIndex;
+ return index >= 0 ? this.optionValue(element.options[index]) : null;
+ },
+
+ selectMany: function(element) {
+ var values, length = element.length;
+ if (!length) return null;
+
+ for (var i = 0, values = []; i < length; i++) {
+ var opt = element.options[i];
+ if (opt.selected) values.push(this.optionValue(opt));
+ }
+ return values;
+ },
+
+ optionValue: function(opt) {
+ // extend element because hasAttribute may not be native
+ return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
+ initialize: function($super, element, frequency, callback) {
+ $super(callback, frequency);
+ this.element = $(element);
+ this.lastValue = this.getValue();
+ },
+
+ execute: function() {
+ var value = this.getValue();
+ if (Object.isString(this.lastValue) && Object.isString(value) ?
+ this.lastValue != value : String(this.lastValue) != String(value)) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ }
+});
+
+Form.Element.Observer = Class.create(Abstract.TimedObserver, {
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.Observer = Class.create(Abstract.TimedObserver, {
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = Class.create({
+ initialize: function(element, callback) {
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ if (this.element.tagName.toLowerCase() == 'form')
+ this.registerFormCallbacks();
+ else
+ this.registerCallback(this.element);
+ },
+
+ onElementEvent: function() {
+ var value = this.getValue();
+ if (this.lastValue != value) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ },
+
+ registerFormCallbacks: function() {
+ Form.getElements(this.element).each(this.registerCallback, this);
+ },
+
+ registerCallback: function(element) {
+ if (element.type) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
+ break;
+ default:
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
+ break;
+ }
+ }
+ }
+});
+
+Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.EventObserver = Class.create(Abstract.EventObserver, {
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+if (!window.Event) var Event = { };
+
+Object.extend(Event, {
+ KEY_BACKSPACE: 8,
+ KEY_TAB: 9,
+ KEY_RETURN: 13,
+ KEY_ESC: 27,
+ KEY_LEFT: 37,
+ KEY_UP: 38,
+ KEY_RIGHT: 39,
+ KEY_DOWN: 40,
+ KEY_DELETE: 46,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
+ KEY_INSERT: 45,
+
+ cache: { },
+
+ relatedTarget: function(event) {
+ var element;
+ switch(event.type) {
+ case 'mouseover': element = event.fromElement; break;
+ case 'mouseout': element = event.toElement; break;
+ default: return null;
+ }
+ return Element.extend(element);
+ }
+});
+
+Event.Methods = (function() {
+ var isButton;
+
+ if (Prototype.Browser.IE) {
+ var buttonMap = { 0: 1, 1: 4, 2: 2 };
+ isButton = function(event, code) {
+ return event.button == buttonMap[code];
+ };
+
+ } else if (Prototype.Browser.WebKit) {
+ isButton = function(event, code) {
+ switch (code) {
+ case 0: return event.which == 1 && !event.metaKey;
+ case 1: return event.which == 1 && event.metaKey;
+ default: return false;
+ }
+ };
+
+ } else {
+ isButton = function(event, code) {
+ return event.which ? (event.which === code + 1) : (event.button === code);
+ };
+ }
+
+ return {
+ isLeftClick: function(event) { return isButton(event, 0) },
+ isMiddleClick: function(event) { return isButton(event, 1) },
+ isRightClick: function(event) { return isButton(event, 2) },
+
+ element: function(event) {
+ var node = Event.extend(event).target;
+ return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
+ },
+
+ findElement: function(event, expression) {
+ var element = Event.element(event);
+ if (!expression) return element;
+ var elements = [element].concat(element.ancestors());
+ return Selector.findElement(elements, expression, 0);
+ },
+
+ pointer: function(event) {
+ return {
+ x: event.pageX || (event.clientX +
+ (document.documentElement.scrollLeft || document.body.scrollLeft)),
+ y: event.pageY || (event.clientY +
+ (document.documentElement.scrollTop || document.body.scrollTop))
+ };
+ },
+
+ pointerX: function(event) { return Event.pointer(event).x },
+ pointerY: function(event) { return Event.pointer(event).y },
+
+ stop: function(event) {
+ Event.extend(event);
+ event.preventDefault();
+ event.stopPropagation();
+ event.stopped = true;
+ }
+ };
+})();
+
+Event.extend = (function() {
+ var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
+ m[name] = Event.Methods[name].methodize();
+ return m;
+ });
+
+ if (Prototype.Browser.IE) {
+ Object.extend(methods, {
+ stopPropagation: function() { this.cancelBubble = true },
+ preventDefault: function() { this.returnValue = false },
+ inspect: function() { return "[object Event]" }
+ });
+
+ return function(event) {
+ if (!event) return false;
+ if (event._extendedByPrototype) return event;
+
+ event._extendedByPrototype = Prototype.emptyFunction;
+ var pointer = Event.pointer(event);
+ Object.extend(event, {
+ target: event.srcElement,
+ relatedTarget: Event.relatedTarget(event),
+ pageX: pointer.x,
+ pageY: pointer.y
+ });
+ return Object.extend(event, methods);
+ };
+
+ } else {
+ Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
+ Object.extend(Event.prototype, methods);
+ return Prototype.K;
+ }
+})();
+
+// Richfaces: added
+Event.getDOMEventName = function(eventName) {
+ if (eventName && eventName.include(':')) return "dataavailable";
+ return eventName;
+};
+
+Object.extend(Event, (function() {
+ var cache = Event.cache;
+
+ function getEventID(element) {
+ if (element._prototypeEventID) return element._prototypeEventID[0];
+ arguments.callee.id = arguments.callee.id || 1;
+ return element._prototypeEventID = [++arguments.callee.id];
+ }
+// Richfaces: commented
+/*
+ function getDOMEventName(eventName) {
+ if (eventName && eventName.include(':')) return "dataavailable";
+ return eventName;
+ }
+*/
+ function getCacheForID(id) {
+ return cache[id] = cache[id] || { };
+ }
+
+ function getWrappersForEventName(id, eventName) {
+ var c = getCacheForID(id);
+ return c[eventName] = c[eventName] || [];
+ }
+
+ function createWrapper(element, eventName, handler) {
+ var id = getEventID(element);
+ var c = getWrappersForEventName(id, eventName);
+ if (c.pluck("handler").include(handler)) return false;
+
+ var wrapper = function(event) {
+ if (!Event || !Event.extend ||
+ (event.eventName && event.eventName != eventName))
+ return false;
+
+ Event.extend(event);
+ handler.call(element, event);
+ };
+
+ wrapper.handler = handler;
+ c.push(wrapper);
+ return wrapper;
+ }
+
+ function findWrapper(id, eventName, handler) {
+ var c = getWrappersForEventName(id, eventName);
+ return c.find(function(wrapper) { return wrapper.handler == handler });
+ }
+
+ function destroyWrapper(id, eventName, handler) {
+ var c = getCacheForID(id);
+ if (!c[eventName]) return false;
+ c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+ }
+
+// Richfaces: commented
+/*
+ function destroyCache() {
+ for (var id in cache)
+ for (var eventName in cache[id])
+ cache[id][eventName] = null;
+ }
+
+ if (window.attachEvent) {
+ window.attachEvent("onunload", destroyCache);
+ }
+*/
+ return {
+ observe: function(element, eventName, handler) {
+ element = $(element);
+ var name = Event.getDOMEventName(eventName); // Richfaces: Event. added
+
+ var wrapper = createWrapper(element, eventName, handler);
+ if (!wrapper) return element;
+
+ if (element.addEventListener) {
+ element.addEventListener(name, wrapper, false);
+ } else {
+ element.attachEvent("on" + name, wrapper);
+ }
+
+ return element;
+ },
+
+ stopObserving: function(element, eventName, handler) {
+ element = $(element);
+ var id = getEventID(element), name = Event.getDOMEventName(eventName); // Richfaces: Event. added
+
+ if (!handler && eventName) {
+ getWrappersForEventName(id, eventName).each(function(wrapper) {
+ element.stopObserving(eventName, wrapper.handler);
+ });
+ return element;
+
+ } else if (!eventName) {
+ Object.keys(getCacheForID(id)).each(function(eventName) {
+ element.stopObserving(eventName);
+ });
+ return element;
+ }
+
+ var wrapper = findWrapper(id, eventName, handler);
+ if (!wrapper) return element;
+
+ if (element.removeEventListener) {
+ element.removeEventListener(name, wrapper, false);
+ } else {
+ element.detachEvent("on" + name, wrapper);
+ }
+
+ destroyWrapper(id, eventName, handler);
+
+ return element;
+ },
+
+ fire: function(element, eventName, memo) {
+ element = $(element);
+ if (element == document && document.createEvent && !element.dispatchEvent)
+ element = document.documentElement;
+
+ var event;
+ if (document.createEvent) {
+ event = document.createEvent("HTMLEvents");
+ event.initEvent("dataavailable", true, true);
+ } else {
+ event = document.createEventObject();
+ event.eventType = "ondataavailable";
+ }
+
+ event.eventName = eventName;
+ event.memo = memo || { };
+
+ if (document.createEvent) {
+ element.dispatchEvent(event);
+ } else {
+ element.fireEvent(event.eventType, event);
+ }
+
+ return Event.extend(event);
+ }
+ };
+})());
+
+Object.extend(Event, Event.Methods);
+
+Element.addMethods({
+ fire: Event.fire,
+ observe: Event.observe,
+ stopObserving: Event.stopObserving
+});
+
+Object.extend(document, {
+ fire: Element.Methods.fire.methodize(),
+ observe: Element.Methods.observe.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;
+
+ function fireContentLoadedEvent() {
+ if (document.loaded) return;
+ if (timer) window.clearInterval(timer);
+ document.fire("dom:loaded");
+ document.loaded = true;
+ }
+
+ if (document.addEventListener) {
+ if (Prototype.Browser.WebKit) {
+ timer = window.setInterval(function() {
+ if (/loaded|complete/.test(document.readyState))
+ fireContentLoadedEvent();
+ }, 0);
+
+ Event.observe(window, "load", fireContentLoadedEvent);
+
+ } else {
+ document.addEventListener("DOMContentLoaded",
+ fireContentLoadedEvent, false);
+ }
+
+ } else {
+ // added by Pavel Yaschenko // http://jira.jboss.com/jira/browse/RF-3879
+
+ // for 1.6.0.2
+ if (document.loaded) return;
+
+ if (document.readyState != "complete") { // added by Pavel Yaschenko
+ document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
+ $("__onDOMContentLoaded").onreadystatechange = function() {
+ if (this.readyState == "complete") {
+ this.onreadystatechange = null;
+ fireContentLoadedEvent();
+ }
+ };
+ } // added by Pavel Yaschenko
+ }
+})();
+/*------------------------------- DEPRECATED -------------------------------*/
+
+Hash.toQueryString = Object.toQueryString;
+
+var Toggle = { display: Element.toggle };
+
+Element.Methods.childOf = Element.Methods.descendantOf;
+
+var Insertion = {
+ Before: function(element, content) {
+ return Element.insert(element, {before:content});
+ },
+
+ Top: function(element, content) {
+ return Element.insert(element, {top:content});
+ },
+
+ Bottom: function(element, content) {
+ return Element.insert(element, {bottom:content});
+ },
+
+ After: function(element, content) {
+ return Element.insert(element, {after:content});
+ }
+};
+
+var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+
+// This should be moved to script.aculo.us; notice the deprecated methods
+// further below, that map to the newer Element methods.
+var Position = {
+ // set to true if needed, warning: firefox performance problems
+ // NOT neeeded for page scrolling, only if draggable contained in
+ // scrollable elements
+ includeScrollOffsets: false,
+
+ // must be called before calling withinIncludingScrolloffset, every time the
+ // page is scrolled
+ prepare: function() {
+ this.deltaX = window.pageXOffset
+ || document.documentElement.scrollLeft
+ || document.body.scrollLeft
+ || 0;
+ this.deltaY = window.pageYOffset
+ || document.documentElement.scrollTop
+ || document.body.scrollTop
+ || 0;
+ },
+
+ // caches x/y coordinate pair to use with overlap
+ within: function(element, x, y) {
+ if (this.includeScrollOffsets)
+ return this.withinIncludingScrolloffsets(element, x, y);
+ this.xcomp = x;
+ this.ycomp = y;
+ this.offset = Element.cumulativeOffset(element);
+
+ return (y >= this.offset[1] &&
+ y < this.offset[1] + element.offsetHeight &&
+ x >= this.offset[0] &&
+ x < this.offset[0] + element.offsetWidth);
+ },
+
+ withinIncludingScrolloffsets: function(element, x, y) {
+ var offsetcache = Element.cumulativeScrollOffset(element);
+
+ this.xcomp = x + offsetcache[0] - this.deltaX;
+ this.ycomp = y + offsetcache[1] - this.deltaY;
+ this.offset = Element.cumulativeOffset(element);
+
+ return (this.ycomp >= this.offset[1] &&
+ this.ycomp < this.offset[1] + element.offsetHeight &&
+ this.xcomp >= this.offset[0] &&
+ this.xcomp < this.offset[0] + element.offsetWidth);
+ },
+
+ // within must be called directly before
+ overlap: function(mode, element) {
+ if (!mode) return 0;
+ if (mode == 'vertical')
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+ element.offsetHeight;
+ if (mode == 'horizontal')
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+ element.offsetWidth;
+ },
+
+ // Deprecation layer -- use newer Element methods now (1.5.2).
+
+ cumulativeOffset: Element.Methods.cumulativeOffset,
+
+ positionedOffset: Element.Methods.positionedOffset,
+
+ absolutize: function(element) {
+ Position.prepare();
+ return Element.absolutize(element);
+ },
+
+ relativize: function(element) {
+ Position.prepare();
+ return Element.relativize(element);
+ },
+
+ realOffset: Element.Methods.cumulativeScrollOffset,
+
+ offsetParent: Element.Methods.getOffsetParent,
+
+ page: Element.Methods.viewportOffset,
+
+ clone: function(source, target, options) {
+ options = options || { };
+ return Element.clonePosition(target, source, options);
+ }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
+ function iter(name) {
+ return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+ }
+
+ instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+ function(element, className) {
+ className = className.toString().strip();
+ var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+ return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+ } : function(element, className) {
+ className = className.toString().strip();
+ var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+ if (!classNames && !className) return elements;
+
+ var nodes = $(element).getElementsByTagName('*');
+ className = ' ' + className + ' ';
+
+ for (var i = 0, child, cn; child = nodes[i]; i++) {
+ if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+ (classNames && classNames.all(function(name) {
+ return !name.toString().blank() && cn.include(' ' + name + ' ');
+ }))))
+ elements.push(Element.extend(child));
+ }
+ return elements;
+ };
+
+ return function(className, parentElement) {
+ return $(parentElement || document.body).getElementsByClassName(className);
+ };
+}(Element.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+ initialize: function(element) {
+ this.element = $(element);
+ },
+
+ _each: function(iterator) {
+ this.element.className.split(/\s+/).select(function(name) {
+ return name.length > 0;
+ })._each(iterator);
+ },
+
+ set: function(className) {
+ this.element.className = className;
+ },
+
+ add: function(classNameToAdd) {
+ if (this.include(classNameToAdd)) return;
+ this.set($A(this).concat(classNameToAdd).join(' '));
+ },
+
+ remove: function(classNameToRemove) {
+ if (!this.include(classNameToRemove)) return;
+ this.set($A(this).without(classNameToRemove).join(' '));
+ },
+
+ toString: function() {
+ return $A(this).join(' ');
+ }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+
+/*--------------------------------------------------------------------------*/
+
+Element.addMethods();
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/script/prototype-1.6.0.2.js
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/scriptaculous.js
===================================================================
--- trunk/docs/common-resources/en/src/main/script/scriptaculous.js (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/scriptaculous.js 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,58 @@
+// script.aculo.us scriptaculous.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Scriptaculous = {
+ Version: '1.8.1',
+ require: function(libraryName) {
+ // inserting via DOM fails in Safari 2.0, so brute force approach
+ document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
+ },
+ REQUIRED_PROTOTYPE: '1.6.0',
+ load: function() {
+ function convertVersionString(versionString){
+ var r = versionString.split('.');
+ return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
+ }
+
+ if((typeof Prototype=='undefined') ||
+ (typeof Element == 'undefined') ||
+ (typeof Element.Methods=='undefined') ||
+ (convertVersionString(Prototype.Version) <
+ convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
+ throw("script.aculo.us requires the Prototype JavaScript framework >= " +
+ Scriptaculous.REQUIRED_PROTOTYPE);
+
+ $A(document.getElementsByTagName("script")).findAll( function(s) {
+ return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+ }).each( function(s) {
+ var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
+ var includes = s.src.match(/\?.*load=([a-z,]*)/);
+ (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
+ function(include) { Scriptaculous.require(path+include+'.js') });
+ });
+ }
+}
+
+Scriptaculous.load();
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/script/scriptaculous.js
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/send_mail.php
===================================================================
--- trunk/docs/common-resources/en/src/main/script/send_mail.php (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/send_mail.php 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,78 @@
+<?php
+//define messages
+$message_error = "Please, enter your message";
+$email_error = "Please, specify your email address";
+$subject_error = "Subject should be maximum 255 chars length";
+$message_not_sent = "Error sending message!";
+$message_success = "Message is sent successfully";
+
+//get $_REQUEST Array
+$_REQUEST = array_map('trim', $_REQUEST);
+$email = $_REQUEST['email'];
+$name= $_REQUEST['name'];
+$subject = $_REQUEST['subject'];
+$message = $_REQUEST['message'];
+$path = $_REQUEST['path'];
+//define patterns
+$email_pat = "/^([A-z0-9|.|-|_]{2,256})(a)(([A-z0-9|.|-]{2,256}).([a-z]{2,4}))*$/";
+$general_pat = "/^(\s)+$/";
+
+// check if 'subject' field has been filled or not
+if(!$subject){
+ $subject="(no subject)";
+}else{
+ $subject = substr(htmlentities($subject), 0, 255);
+}
+
+// check if 'name' field has been filled or not
+if(!$name){
+ $name="(no name)";
+}else{
+ $name = substr(htmlentities($name), 0, 255);
+}
+
+// check if 'message' field has been filled or not
+if(!$message || preg_match($general_pat, $message)){
+ echo $message_error;
+ exit();
+}else{
+ $message = "Feedback from ".$path."\n"."Message: ".substr(htmlentities($message), 0, 3000);
+}
+
+// check if 'email' field has been filled or not
+if(!preg_match($email_pat, $email)){
+ echo $email_error;
+ exit();
+}
+
+// define MIME headers
+$headers="MIME-Version 1.0"."\r\n"."Content-Type: text/plain; charset=utf-8"."\r\n"."From: \"".$name."\" "."<".$email.">"."Reply-to: \"".$name."\" "."<".$email.">";
+
+ //Load in the files we'll need
+require_once "swift_lib/Swift.php";
+require_once "swift_lib/Swift/Connection/SMTP.php";
+require_once "swift_lib/Swift/Connection/Sendmail.php";
+try{
+//Start Swift
+$sendmail =& new Swift_Connection_Sendmail();
+$sendmail->setTimeout(3); //3 seconds
+
+//$swift =& new Swift(new Swift_Connection_SMTP("localhost"));
+
+$swift =& new Swift($sendmail);
+$sender =& new Swift_Address($email, $name);
+$me =& new Swift_Address("ggalkin(a)exadel.com");
+$body =& new Swift_Message($subject, $message);
+ if($swift->send($body, $me, $sender)){
+ echo $message_success;
+ exit();
+ }else{
+ echo $message_not_sent;
+ exit();
+ }
+}catch (Swift_ConnectionException $e) {
+ echo "There was a problem communicating with SMTP: " . $e->getMessage();
+} catch (Swift_Message_MimeException $e) {
+ echo "There was an unexpected problem building the email:" . $e->getMessage();
+}
+?>
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/script/send_mail.php
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/script/toggle.js
===================================================================
--- trunk/docs/common-resources/en/src/main/script/toggle.js (rev 0)
+++ trunk/docs/common-resources/en/src/main/script/toggle.js 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,60 @@
+// attach handler to window object
+ Event.observe(window,'load',initializeEmailClient,false);
+
+// initialize email application
+function initializeEmailClient(){
+ Event.observe('feedback-mailform', 'submit', sendEmail);
+}
+
+ // send http request
+function sendEmail(e){
+
+ // prevent form from submitting
+ Event.stop(e);
+ var params='subject='+$F('subject')+'&message='+escape($F('message'))+'&name='+$F('name')+'&email='+$F('email')+'&path='+window.location;
+ var xmlobj=new Ajax.Updater('feedback-state','script/send_mail.php',{method:'get',parameters: params});
+}
+
+function dbToggle(node, expandText, collapseText) {
+ var dt = node.parentNode;
+ if (dt.nodeName.toLowerCase() == 'dt') {
+ var dd = dt.nextSibling;
+
+ if (dd && dd.nodeName.toLowerCase() == 'dd') {
+
+ if (dd.style && dd.style.display == 'none') {
+ dd.style.display = '';
+ node.innerHTML = collapseText;
+ } else {
+ dd.style.display = 'none';
+ node.innerHTML = expandText;
+ }
+
+ }
+
+ }
+
+}
+
+var toc = {
+ expand: function(node) {
+ toc.show(toc.findDD(node))
+ toc.hide(node);
+ toc.show(node.nextSibling);
+ },
+ collapse : function(node) {
+ toc.hide(toc.findDD(node))
+ toc.hide(node);
+ toc.show(node.previousSibling);
+ },
+ findDD : function(node) {
+ return node.parentNode.nextSibling;
+ },
+
+ hide: function(node) {
+ node.style.display = "none";
+ },
+ show: function(node) {
+ node.style.display = "";
+ }
+};
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/script/toggle.js
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/collapsing-navigation.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/collapsing-navigation.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/collapsing-navigation.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,199 @@
+<!DOCTYPE xsl:stylesheet>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0" xmlns="http://www.w3.org/TR/xhtml1/transitional"
+ exclude-result-prefixes="#default">
+
+ <xsl:template name="subtoc">
+ <xsl:param name="toc-context" select="." />
+ <xsl:param name="nodes" select="NOT-AN-ELEMENT" />
+
+ <xsl:variable name="toc.mark">
+ <xsl:apply-templates mode="toc.mark" select="." />
+ </xsl:variable>
+
+ <xsl:variable name="should.collapse.list"
+ select="string-length(string($toc.mark)) > 0">
+ </xsl:variable>
+
+ <xsl:variable name="toc.on.plus.mark">
+ <xsl:choose>
+ <xsl:when test="$should.collapse.list">
+ <xsl:copy-of select="$toc.mark"></xsl:copy-of>
+ </xsl:when>
+ <xsl:otherwise>
+ <span class="expand_collapse_toc" style="visibility:hidden;">  </span>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="nodes.plus" select="$nodes | qandaset" />
+
+ <xsl:variable name="subtoc">
+ <xsl:element name="{$toc.list.type}">
+ <xsl:choose>
+ <xsl:when test="$qanda.in.toc != 0">
+ <xsl:apply-templates mode="toc"
+ select="$nodes.plus">
+ <xsl:with-param name="toc-context"
+ select="$toc-context" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="toc"
+ select="$nodes">
+ <xsl:with-param name="toc-context"
+ select="$toc-context" />
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:element>
+ </xsl:variable>
+
+ <xsl:variable name="depth">
+ <xsl:choose>
+ <xsl:when test="local-name(.) = 'section'">
+ <xsl:value-of select="count(ancestor::section) + 1" />
+ </xsl:when>
+ <xsl:when test="local-name(.) = 'sect1'">1</xsl:when>
+ <xsl:when test="local-name(.) = 'sect2'">2</xsl:when>
+ <xsl:when test="local-name(.) = 'sect3'">3</xsl:when>
+ <xsl:when test="local-name(.) = 'sect4'">4</xsl:when>
+ <xsl:when test="local-name(.) = 'sect5'">5</xsl:when>
+ <xsl:when test="local-name(.) = 'refsect1'">1</xsl:when>
+ <xsl:when test="local-name(.) = 'refsect2'">2</xsl:when>
+ <xsl:when test="local-name(.) = 'refsect3'">3</xsl:when>
+ <xsl:when test="local-name(.) = 'simplesect'">
+ <!-- sigh... -->
+ <xsl:choose>
+ <xsl:when test="local-name(..) = 'section'">
+ <xsl:value-of
+ select="count(ancestor::section)" />
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'sect1'">
+ 2
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'sect2'">
+ 3
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'sect3'">
+ 4
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'sect4'">
+ 5
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'sect5'">
+ 6
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'refsect1'">
+ 2
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'refsect2'">
+ 3
+ </xsl:when>
+ <xsl:when test="local-name(..) = 'refsect3'">
+ 4
+ </xsl:when>
+ <xsl:otherwise>1</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="depth.from.context"
+ select="count(ancestor::*)-count($toc-context/ancestor::*)" />
+
+ <xsl:variable name="subtoc.list">
+ <xsl:choose>
+ <xsl:when test="$toc.dd.type = ''">
+ <xsl:copy-of select="$subtoc" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:element name="{$toc.dd.type}">
+ <xsl:if test="$should.collapse.list">
+ <xsl:attribute name="style">display:none;</xsl:attribute>
+ </xsl:if>
+ <xsl:copy-of select="$subtoc" />
+ </xsl:element>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+
+ <xsl:element name="{$toc.listitem.type}">
+
+ <xsl:copy-of select="$toc.on.plus.mark"></xsl:copy-of>
+ <xsl:call-template name="toc.line">
+ <xsl:with-param name="toc-context"
+ select="$toc-context" />
+ </xsl:call-template>
+
+ <xsl:if
+ test="$toc.listitem.type = 'li'
+ and $toc.section.depth > $depth and
+ ( ($qanda.in.toc = 0 and count($nodes)>0) or
+ ($qanda.in.toc != 0 and count($nodes.plus)>0) )
+ and $toc.max.depth > $depth.from.context">
+ <xsl:copy-of select="$subtoc.list" />
+ </xsl:if>
+ </xsl:element>
+ <xsl:if
+ test="$toc.listitem.type != 'li'
+ and $toc.section.depth > $depth and
+ ( ($qanda.in.toc = 0 and count($nodes)>0) or
+ ($qanda.in.toc != 0 and count($nodes.plus)>0) )
+ and $toc.max.depth > $depth.from.context">
+ <xsl:copy-of select="$subtoc.list" />
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="section|chapter" mode="toc.mark">
+ <xsl:variable name="subchapters">
+ <xsl:apply-templates select="child::section" mode="toc" />
+ </xsl:variable>
+
+ <xsl:if test="string-length(string($subchapters))">
+ <xsl:call-template name="toggle.expand.mark" />
+ <xsl:call-template name="toggle.collapse.mark" />
+ </xsl:if>
+
+ </xsl:template>
+
+ <xsl:template match="*" mode="toc.mark">
+
+ </xsl:template>
+
+ <xsl:template name="user.head.content">
+ <xsl:param name="node" select="." />
+ <script type="text/javascript" src="script/toggle.js"><xsl:comment>If you see this message, your web browser doesn't support JavaScript or JavaScript is disabled.</xsl:comment></script>
+ </xsl:template>
+
+ <xsl:template name="toggle.expand.mark">
+ <xsl:param name="visible" select="true()"/>
+ <span onclick="toc.expand(this)" class="expand_collapse_toc">
+ <xsl:call-template name="render.display">
+ <xsl:with-param name="visible" select="$visible" />
+ </xsl:call-template>
+ <xsl:text>+</xsl:text>
+ </span>
+ </xsl:template>
+
+ <xsl:template name="toggle.collapse.mark">
+ <xsl:param name="visible" select="false()"/>
+ <span onclick="toc.collapse(this)" class="expand_collapse_toc">
+ <xsl:call-template name="render.display">
+ <xsl:with-param name="visible" select="$visible" />
+ </xsl:call-template>
+ <xsl:text>-</xsl:text>
+ </span>
+ </xsl:template>
+
+ <xsl:template name="render.display">
+ <xsl:param name="visible" select="false()"/>
+ <xsl:attribute name="style">
+ <xsl:if test="not($visible)">display:none;</xsl:if>
+ </xsl:attribute>
+ </xsl:template>
+
+
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/collapsing-navigation.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/f.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/f.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/f.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:javaee="http://java.sun.com/xml/ns/javaee"
+ version="1.0" exclude-result-prefixes="javaee">
+ <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
+ omit-xml-declaration="yes" />
+ <xsl:param name="lang" />
+ <xsl:param name="title" />
+ <xsl:param name="separator" />
+ <xsl:param name="prefix" />
+
+ <xsl:template match="javaee:taglib | taglib">
+ <xsl:variable name="excluded-tag-names">
+ header2,header3,header4,header5,header6
+ </xsl:variable>
+
+ <xsl:for-each select="javaee:tag | tag">
+
+ <!--xsl:value-of select="./name/text()" /-->
+
+ <xsl:if
+ test="not(contains($excluded-tag-names, javaee:name))">
+ <xsl:call-template name="tag" />
+ </xsl:if>
+ <xsl:if
+ test="not(contains($excluded-tag-names, ./name/text()))">
+ <xsl:call-template name="tag" />
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="tag">
+ <section role="NotInToc">
+ <xsl:variable name="tag_name">
+ <xsl:choose>
+ <xsl:when test="javaee:name">
+ <xsl:value-of select="javaee:name" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="./name/text()" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <!--
+ <xsl:variable name="prefix">
+ <xsl:choose>
+ <xsl:when test="/javaee:taglib/javaee:short-name">
+ <xsl:value-of select="/javaee:taglib/javaee:short-name" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="/taglib/short-name/text()" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ -->
+ <xsl:attribute name="id"><xsl:value-of select="$tag_name" />
+ </xsl:attribute>
+ <title>
+ <
+ <xsl:value-of select="concat($prefix,':', $tag_name)" />
+ >
+ </title>
+ <xsl:for-each
+ select="document(concat($lang, $separator,'included',$separator,$tag_name, '.desc.xml'))/*">
+ <xsl:copy-of select="./*" />
+ </xsl:for-each>
+ <table>
+ <title>
+ <xsl:value-of select="$prefix" />
+ :
+ <xsl:value-of select="javaee:name" />
+ <xsl:value-of select="name" />
+ attributes
+ </title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Attribute Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <xsl:for-each select="javaee:attribute | attribute">
+ <xsl:sort select="javaee:name|name" />
+ <row>
+ <entry>
+ <xsl:value-of select="javaee:name"/>
+ <xsl:value-of select="name"/>
+ </entry>
+ <entry>
+ <xsl:value-of select="javaee:description" disable-output-escaping="yes"/>
+ <xsl:value-of select="description" disable-output-escaping="yes"/>
+ </entry>
+ </row>
+ </xsl:for-each>
+ </tbody>
+ </tgroup>
+ </table>
+ <xsl:for-each
+ select="document(concat($lang, $separator,'included',$separator,$tag_name, '.xml'))/*">
+ <xsl:copy-of select="./*" />
+ </xsl:for-each>
+ </section>
+ </xsl:template>
+</xsl:transform>
\ No newline at end of file
Property changes on: trunk/docs/common-resources/en/src/main/xslt/f.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,285 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:diffmk="http://diffmk.sf.net/ns/diff" xmlns:date="http://exslt.org/dates-and-times" exclude-result-prefixes="date">
+
+ <xsl:import href="collapsing-navigation.xsl"/>
+ <xsl:param name="generate.toc" select="'book toc'"/>
+ <xsl:param name="toc.section.depth" select="5"/>
+ <!--
+From: xhtml/docbook.xsl
+Reason: Remove inline style for draft mode
+Version: 1.72.0
+-->
+
+<xsl:template name="head.content">
+ <xsl:param name="node" select="."/>
+ <xsl:param name="title">
+ <xsl:apply-templates select="$node" mode="object.title.markup.textonly"/>
+ </xsl:param>
+
+ <title xmlns="http://www.w3.org/1999/xhtml" >
+ <xsl:copy-of select="$title"/>
+ </title>
+
+ <xsl:if test="$html.stylesheet != ''">
+ <xsl:call-template name="output.html.stylesheets">
+ <xsl:with-param name="stylesheets" select="normalize-space($html.stylesheet)"/>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:if test="$link.mailto.url != ''">
+ <link rev="made" href="{$link.mailto.url}"/>
+ </xsl:if>
+
+ <xsl:if test="$html.base != ''">
+ <base href="{$html.base}"/>
+ </xsl:if>
+
+ <meta xmlns="http://www.w3.org/1999/xhtml" name="generator" content="DocBook {$DistroTitle} V{$VERSION}"/>
+
+ <xsl:if test="$generate.meta.abstract != 0">
+ <xsl:variable name="info" select="(articleinfo |bookinfo |prefaceinfo |chapterinfo |appendixinfo |sectioninfo |sect1info |sect2info |sect3info |sect4info |sect5info |referenceinfo |refentryinfo |partinfo |info |docinfo)[1]"/>
+ <xsl:if test="$info and $info/abstract">
+ <meta xmlns="http://www.w3.org/1999/xhtml" name="description">
+ <xsl:attribute name="content">
+ <xsl:for-each select="$info/abstract[1]/*">
+ <xsl:value-of select="normalize-space(.)"/>
+ <xsl:if test="position() < last()">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:attribute>
+ </meta>
+ </xsl:if>
+ </xsl:if>
+
+ <link rel="shortcut icon" type="image/vnd.microsoft.icon" href="images/favicon.ico" />
+
+ <xsl:apply-templates select="." mode="head.keywords.content"/>
+ <script type="text/javascript" src="script/prototype-1.6.0.2.js"><xsl:comment>If you see this message, your web browser doesn't support JavaScript or JavaScript is disabled.</xsl:comment></script>
+ <script type="text/javascript" src="script/effects.js"><xsl:comment>If you see this message, your web browser doesn't support JavaScript or JavaScript is disabled.</xsl:comment></script>
+ <script type="text/javascript" src="script/scriptaculous.js"><xsl:comment>If you see this message, your web browser doesn't support JavaScript or JavaScript is disabled.</xsl:comment></script>
+
+</xsl:template>
+
+<xsl:template match="abstract" mode="titlepage.mode">
+ <div id="timestamp">
+ <xsl:text>Last published: </xsl:text>
+ <xsl:call-template name="datetime.format">
+ <xsl:with-param name="date" select="date:date-time()"/>
+ <xsl:with-param name="format" select="'B d, Y'"/>
+ </xsl:call-template>
+ </div>
+ <div>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+ <xsl:apply-templates mode="titlepage.mode"/>
+ </div>
+</xsl:template>
+
+ <!-- Overriding toc.line -->
+ <xsl:template name="toc.line">
+ <xsl:param name="toc-context" select="."/>
+ <xsl:param name="depth" select="1"/>
+ <xsl:param name="depth.from.context" select="8"/>
+
+ <span>
+ <xsl:attribute name="class"><xsl:value-of select="local-name(.)"/></xsl:attribute>
+
+ <!-- * if $autotoc.label.in.hyperlink is zero, then output the label -->
+ <!-- * before the hyperlinked title (as the DSSSL stylesheet does) -->
+ <xsl:if test="$autotoc.label.in.hyperlink = 0">
+ <xsl:variable name="label">
+ <xsl:apply-templates select="." mode="label.markup"/>
+ </xsl:variable>
+ <xsl:copy-of select="$label"/>
+ <xsl:if test="$label != ''">
+ <xsl:value-of select="$autotoc.label.separator"/>
+ </xsl:if>
+ </xsl:if>
+
+ <a>
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="context" select="$toc-context"/>
+ <xsl:with-param name="toc-context" select="$toc-context"/>
+ </xsl:call-template>
+ </xsl:attribute>
+
+ <xsl:choose>
+ <xsl:when test="@role='new' or @role='updated'">
+ <xsl:attribute name="class">
+ <xsl:value-of select="@role"/>
+ </xsl:attribute>
+ </xsl:when>
+ <!-- For mkdiff compatibility-->
+ <xsl:when test="@revisionflag='added' or @revisionflag='changed'">
+ <xsl:attribute name="class">
+ <xsl:value-of select="@revisionflag"/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@diffmk:change='added' or @diffmk:change='changed'">
+ <xsl:attribute name="class">
+ <xsl:value-of select="@diffmk:change"/>
+ </xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+
+ <!-- * if $autotoc.label.in.hyperlink is non-zero, then output the label -->
+ <!-- * as part of the hyperlinked title -->
+ <xsl:if test="not($autotoc.label.in.hyperlink = 0)">
+ <xsl:variable name="label">
+ <xsl:apply-templates select="." mode="label.markup"/>
+ </xsl:variable>
+ <xsl:copy-of select="$label"/>
+ <xsl:if test="$label != ''">
+ <xsl:value-of select="$autotoc.label.separator"/>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:apply-templates select="." mode="titleabbrev.markup"/>
+ </a>
+ </span>
+ </xsl:template>
+ <!-- XHTML and PDF -->
+
+ <xsl:template match="//diffmk:wrapper">
+ <xsl:choose>
+ <xsl:when test="@diffmk:change='deleted'">
+ <xsl:text> </xsl:text>
+ </xsl:when>
+ <xsl:when test="parent::node()[local-name()='title']">
+ <xsl:value-of select="."/>
+ </xsl:when>
+ <xsl:otherwise>
+ <span class="diffmkwrapper">
+ <xsl:value-of select="."/>
+ </span>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- THERE ARE 2 TEMPLATES FOR ADDING 'ADDED', 'CHANGED' ICONS TO ALL OF THE TITLES-->
+
+<xsl:template name="component.title">
+ <xsl:param name="node" select="."/>
+
+ <xsl:variable name="level">
+ <xsl:choose>
+ <xsl:when test="ancestor::section">
+ <xsl:value-of select="count(ancestor::section)+1"/>
+ </xsl:when>
+ <xsl:when test="ancestor::sect5">6</xsl:when>
+ <xsl:when test="ancestor::sect4">5</xsl:when>
+ <xsl:when test="ancestor::sect3">4</xsl:when>
+ <xsl:when test="ancestor::sect2">3</xsl:when>
+ <xsl:when test="ancestor::sect1">2</xsl:when>
+ <xsl:otherwise>1</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <!-- Let's handle the case where a component (bibliography, for example)
+ occurs inside a section; will we need parameters for this? -->
+
+ <xsl:element name="h{$level+1}">
+ <xsl:attribute name="class">
+ title
+ </xsl:attribute>
+ <xsl:if test="$generate.id.attributes = 0">
+ <xsl:call-template name="anchor">
+ <xsl:with-param name="node" select="$node"/>
+ <xsl:with-param name="conditional" select="0"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="$node" mode="object.title.markup">
+ <xsl:with-param name="allow-anchors" select="1"/>
+ </xsl:apply-templates>
+ </xsl:element>
+
+ <xsl:choose>
+ <xsl:when test="../@role='new' or ../@revisionflag='added' or ../@diffmk:change='added'">
+ <img src="images/new.png" alt="new" class="img_marker" />
+ </xsl:when>
+ <!-- For mkdiff compatibility-->
+ <xsl:when test="../@role='updated' or ../@revisionflag='changed' or ../@diffmk:change='changed'">
+ <img src="images/updated.png" alt="updated" class="img_marker" />
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+<xsl:template name="section.heading">
+ <xsl:param name="section" select="."/>
+ <xsl:param name="level" select="1"/>
+ <xsl:param name="allow-anchors" select="1"/>
+ <xsl:param name="title"/>
+ <xsl:param name="class" select="'title'"/>
+
+ <xsl:variable name="id">
+ <xsl:choose>
+ <!-- if title is in an *info wrapper, get the grandparent -->
+ <xsl:when test="contains(local-name(..), 'info')">
+ <xsl:call-template name="object.id">
+ <xsl:with-param name="object" select="../.."/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="object.id">
+ <xsl:with-param name="object" select=".."/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <!-- HTML H level is one higher than section level -->
+ <xsl:variable name="hlevel">
+ <xsl:choose>
+ <!-- highest valid HTML H level is H6; so anything nested deeper
+ than 5 levels down just becomes H6 -->
+ <xsl:when test="$level > 5">6</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$level + 1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:element name="h{$hlevel}">
+ <xsl:attribute name="class">
+ <xsl:value-of select="$class"/>
+ </xsl:attribute>
+ <xsl:if test="$css.decoration != '0'">
+ <xsl:if test="$hlevel<3">
+ <xsl:attribute name="style">clear: both</xsl:attribute>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$allow-anchors != 0 and $generate.id.attributes = 0">
+ <xsl:call-template name="anchor">
+ <xsl:with-param name="node" select="$section"/>
+ <xsl:with-param name="conditional" select="0"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$generate.id.attributes != 0 and not(local-name(.) = 'appendix')">
+ <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
+ </xsl:if>
+ <xsl:copy-of select="$title"/>
+ </xsl:element>
+ <xsl:choose>
+ <xsl:when test="../@role='new' or ../@revisionflag='added' or ../@diffmk:change='added'">
+ <img src="images/new.png" alt="new" class="img_marker" />
+ </xsl:when>
+ <!-- For mkdiff compatibility-->
+ <xsl:when test="../@role='updated' or ../@revisionflag='changed' or ../@diffmk:change='changed'">
+ <img src="images/updated.png" alt="updated" class="img_marker" />
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!-- ==================================================================== -->
+
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml-common-reldiffmk.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml-common.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-common.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-common.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,84 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:date="http://exslt.org/dates-and-times" exclude-result-prefixes="date">
+
+ <xsl:import href="collapsing-navigation.xsl"/>
+ <xsl:param name="generate.toc" select="'book toc'"/>
+ <xsl:param name="toc.section.depth" select="5"/>
+ <!--
+From: xhtml/docbook.xsl
+Reason: Remove inline style for draft mode
+Version: 1.72.0
+-->
+
+<xsl:template name="head.content">
+ <xsl:param name="node" select="."/>
+ <xsl:param name="title">
+ <xsl:apply-templates select="$node" mode="object.title.markup.textonly"/>
+ </xsl:param>
+
+ <title xmlns="http://www.w3.org/1999/xhtml" >
+ <xsl:copy-of select="$title"/>
+ </title>
+
+ <xsl:if test="$html.stylesheet != ''">
+ <xsl:call-template name="output.html.stylesheets">
+ <xsl:with-param name="stylesheets" select="normalize-space($html.stylesheet)"/>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:if test="$link.mailto.url != ''">
+ <link rev="made" href="{$link.mailto.url}"/>
+ </xsl:if>
+
+ <xsl:if test="$html.base != ''">
+ <base href="{$html.base}"/>
+ </xsl:if>
+
+ <meta xmlns="http://www.w3.org/1999/xhtml" name="generator" content="DocBook {$DistroTitle} V{$VERSION}"/>
+
+ <xsl:if test="$generate.meta.abstract != 0">
+ <xsl:variable name="info" select="(articleinfo |bookinfo |prefaceinfo |chapterinfo |appendixinfo |sectioninfo |sect1info |sect2info |sect3info |sect4info |sect5info |referenceinfo |refentryinfo |partinfo |info |docinfo)[1]"/>
+ <xsl:if test="$info and $info/abstract">
+ <meta xmlns="http://www.w3.org/1999/xhtml" name="description">
+ <xsl:attribute name="content">
+ <xsl:for-each select="$info/abstract[1]/*">
+ <xsl:value-of select="normalize-space(.)"/>
+ <xsl:if test="position() < last()">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:attribute>
+ </meta>
+ </xsl:if>
+ </xsl:if>
+
+ <link rel="shortcut icon" type="image/vnd.microsoft.icon" href="images/favicon.ico" />
+
+ <xsl:apply-templates select="." mode="head.keywords.content"/>
+ <script type="text/javascript" src="script/prototype-1.6.0.2.js"><xsl:comment>If you see this message, your web browser doesn't support JavaScript or JavaScript is disabled.</xsl:comment></script>
+ <script type="text/javascript" src="script/effects.js"><xsl:comment>If you see this message, your web browser doesn't support JavaScript or JavaScript is disabled.</xsl:comment></script>
+ <script type="text/javascript" src="script/scriptaculous.js"><xsl:comment>If you see this message, your web browser doesn't support JavaScript or JavaScript is disabled.</xsl:comment></script>
+
+</xsl:template>
+
+<xsl:template match="abstract" mode="titlepage.mode">
+ <div id="timestamp">
+ <xsl:text>Last published: </xsl:text>
+ <xsl:call-template name="datetime.format">
+ <xsl:with-param name="date" select="date:date-time()"/>
+ <xsl:with-param name="format" select="'B d, Y'"/>
+ </xsl:call-template>
+ </div>
+ <div>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+ <xsl:apply-templates mode="titlepage.mode"/>
+ </div>
+</xsl:template>
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml-common.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml-diffmk.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-diffmk.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-diffmk.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,226 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="classpath:/xslt/org/jboss/xhtml.xsl"/>
+ <xsl:import href="xhtml-common-reldiffmk.xsl"/>
+
+<xsl:param name="chunk.fast" select="1"/>
+ <xsl:param name="html.stylesheet" select="'css/html-release.css'"/>
+
+<xsl:template name="header.navigation">
+ <xsl:param name="prev" select="/foo"/>
+ <xsl:param name="next" select="/foo"/>
+ <xsl:param name="nav.context"/>
+ <xsl:variable name="home" select="/*[1]"/>
+ <xsl:variable name="up" select="parent::*"/>
+ <xsl:variable name="row1" select="$navig.showtitles != 0"/>
+ <xsl:variable name="row2" select="count($prev) > 0 or (count($up) > 0 and generate-id($up) != generate-id($home) and $navig.showtitles != 0) or count($next) > 0"/>
+ <xsl:if test="$suppress.navigation = '0' and $suppress.header.navigation = '0'">
+ <xsl:if test="$row1 or $row2">
+ <xsl:if test="$row1">
+ <div id="overlay">
+ <xsl:text> </xsl:text>
+ </div>
+
+ <!-- FEEDBACK -->
+ <div id="feedback-maincontainer" style="display:none">
+ <div id="feedback-header">
+ Send your remarks, comments or wishes to doc team
+ </div>
+ <a href="#" onclick="$('feedback-maincontainer').hide(); return false;" id="feedback-close">
+ <img src="images/close.png" class="feedback-images" />
+ </a>
+ <div id="feedback-state"><xsl:text> </xsl:text></div>
+
+ <form id="feedback-mailform">
+ <div class="feedback-textbox-div">
+ Subject:<input type="text" id="subject" name="subject" title="Enter the subject of your message" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ <span style="vertical-align: top;">Message:</span>
+ <textarea name="message" title="Type here the text of your message" id="message"><xsl:text> </xsl:text></textarea>
+ </div>
+ <div class="feedback-textbox-div">
+ Your name:<input type="text" id="name" name="name" title="Enter your name" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ Your email:<input type="text" id="email" name="email" title="Enter your email address" class="feedback-textbox" />
+ </div>
+ <span class="feedback-button-container">
+ <input type="submit" value="Send Message" name="submit" class="feedback-formbutton" title="Send Message" />
+ </span>
+ <span class="feedback-button-container">
+ <input type="reset" value="Clear All Fields" class="feedback-formbutton" title="Clear All Fields" />
+ </span>
+ </form>
+ </div>
+ <div id="feedback-wrapper">
+ <a id="feedback-link" href="#" onclick="$('feedback-maincontainer').appear(); return false;">
+ <img src="images/feedback_logo.png" class="feedback-images" width="100px"/>
+ </a>
+ </div>
+ <!-- FEEDBACK ENDS -->
+
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:attribute name="id">
+ <xsl:text>title</xsl:text>
+ </xsl:attribute>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$siteHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>site_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$siteLinkText"/>
+ </strong>
+ </a>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$docHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>doc_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$docLinkText"/>
+ </strong>
+ </a>
+ </p>
+ </xsl:if>
+ <xsl:if test="$row2">
+ <ul class="docnav" xmlns="http://www.w3.org/1999/xhtml">
+ <li class="previous">
+ <xsl:if test="count($prev)>0">
+ <a accesskey="p">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$prev"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <strong>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'prev'"/>
+ </xsl:call-template>
+ </strong>
+ </a>
+ </xsl:if>
+ </li>
+ <li class="next">
+ <xsl:if test="count($next)>0">
+ <a accesskey="n">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$next"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <strong>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'next'"/>
+ </xsl:call-template>
+ </strong>
+ </a>
+ </xsl:if>
+ </li>
+ </ul>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$header.rule != 0">
+ <hr/>
+ </xsl:if>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="chunk">
+ <xsl:param name="node" select="."/>
+
+ <xsl:choose>
+ <xsl:when test="not($node/parent::*)">1</xsl:when>
+ <xsl:when test="$node/parent::node()/processing-instruction('forseChanks') and local-name($node)!='title' and local-name($node)!='para' and local-name($node)='section'" >1</xsl:when>
+ <xsl:when test="local-name($node) = 'sect1'
+ and $chunk.section.depth >= 1
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect1) > 0)">
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect2'
+ and $chunk.section.depth >= 2
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect2) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect3'
+ and $chunk.section.depth >= 3
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect3) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect4'
+ and $chunk.section.depth >= 4
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect4) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect5'
+ and $chunk.section.depth >= 5
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect5) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'section'
+ and $chunk.section.depth >= count($node/ancestor::section)+1
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::section) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="local-name($node)='preface'">1</xsl:when>
+ <xsl:when test="local-name($node)='chapter'">1</xsl:when>
+ <xsl:when test="local-name($node)='appendix'">1</xsl:when>
+ <xsl:when test="local-name($node)='article'">1</xsl:when>
+ <xsl:when test="local-name($node)='part'">1</xsl:when>
+ <xsl:when test="local-name($node)='reference'">1</xsl:when>
+ <xsl:when test="local-name($node)='refentry'">1</xsl:when>
+ <xsl:when test="local-name($node)='index' and ($generate.index != 0 or count($node/*) > 0)
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='bibliography'
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='glossary'
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='colophon'">1</xsl:when>
+ <xsl:when test="local-name($node)='book'">1</xsl:when>
+ <xsl:when test="local-name($node)='set'">1</xsl:when>
+ <xsl:when test="local-name($node)='setindex'">1</xsl:when>
+ <xsl:when test="local-name($node)='legalnotice'
+ and $generate.legalnotice.link != 0">1</xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml-diffmk.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml-release.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-release.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-release.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,222 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="classpath:/xslt/org/jboss/xhtml.xsl"/>
+ <xsl:import href="xhtml-common-reldiffmk.xsl"/>
+
+<xsl:param name="chunk.fast" select="1"/>
+ <xsl:param name="html.stylesheet" select="'css/html-release.css'"/>
+
+<xsl:template name="header.navigation">
+ <xsl:param name="prev" select="/foo"/>
+ <xsl:param name="next" select="/foo"/>
+ <xsl:param name="nav.context"/>
+ <xsl:variable name="home" select="/*[1]"/>
+ <xsl:variable name="up" select="parent::*"/>
+ <xsl:variable name="row1" select="$navig.showtitles != 0"/>
+ <xsl:variable name="row2" select="count($prev) > 0 or (count($up) > 0 and generate-id($up) != generate-id($home) and $navig.showtitles != 0) or count($next) > 0"/>
+ <xsl:if test="$suppress.navigation = '0' and $suppress.header.navigation = '0'">
+ <xsl:if test="$row1 or $row2">
+ <xsl:if test="$row1">
+ <!-- FEEDBACK -->
+ <div id="feedback-maincontainer" style="display:none">
+ <div id="feedback-header">
+ Send your remarks, comments or wishes to doc team
+ </div>
+ <a href="#" onclick="$('feedback-maincontainer').hide(); return false;" id="feedback-close">
+ <img src="images/close.png" class="feedback-images" />
+ </a>
+ <div id="feedback-state"><xsl:text> </xsl:text></div>
+
+ <form id="feedback-mailform">
+ <div class="feedback-textbox-div">
+ Subject:<input type="text" id="subject" name="subject" title="Enter the subject of your message" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ <span style="vertical-align: top;">Message:</span>
+ <textarea name="message" title="Type here the text of your message" id="message"><xsl:text> </xsl:text></textarea>
+ </div>
+ <div class="feedback-textbox-div">
+ Your name:<input type="text" id="name" name="name" title="Enter your name" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ Your email:<input type="text" id="email" name="email" title="Enter your email address" class="feedback-textbox" />
+ </div>
+ <span class="feedback-button-container">
+ <input type="submit" value="Send Message" name="submit" class="feedback-formbutton" title="Send Message" />
+ </span>
+ <span class="feedback-button-container">
+ <input type="reset" value="Clear All Fields" class="feedback-formbutton" title="Clear All Fields" />
+ </span>
+ </form>
+ </div>
+ <div id="feedback-wrapper">
+ <a id="feedback-link" href="#" onclick="$('feedback-maincontainer').appear(); return false;">
+ <img src="images/feedback_logo.png" class="feedback-images" width="100px"/>
+ </a>
+ </div>
+ <!-- FEEDBACK ENDS -->
+
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:attribute name="id">
+ <xsl:text>title</xsl:text>
+ </xsl:attribute>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$siteHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>site_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$siteLinkText"/>
+ </strong>
+ </a>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$docHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>doc_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$docLinkText"/>
+ </strong>
+ </a>
+ </p>
+ </xsl:if>
+ <xsl:if test="$row2">
+ <ul class="docnav" xmlns="http://www.w3.org/1999/xhtml">
+ <li class="previous">
+ <xsl:if test="count($prev)>0">
+ <a accesskey="p">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$prev"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <strong>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'prev'"/>
+ </xsl:call-template>
+ </strong>
+ </a>
+ </xsl:if>
+ </li>
+ <li class="next">
+ <xsl:if test="count($next)>0">
+ <a accesskey="n">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$next"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <strong>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'next'"/>
+ </xsl:call-template>
+ </strong>
+ </a>
+ </xsl:if>
+ </li>
+ </ul>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$header.rule != 0">
+ <hr/>
+ </xsl:if>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="chunk">
+ <xsl:param name="node" select="."/>
+
+ <xsl:choose>
+ <xsl:when test="not($node/parent::*)">1</xsl:when>
+ <xsl:when test="$node/parent::node()/processing-instruction('forseChanks') and local-name($node)!='title' and local-name($node)!='para' and local-name($node)='section'" >1</xsl:when>
+ <xsl:when test="local-name($node) = 'sect1'
+ and $chunk.section.depth >= 1
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect1) > 0)">
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect2'
+ and $chunk.section.depth >= 2
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect2) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect3'
+ and $chunk.section.depth >= 3
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect3) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect4'
+ and $chunk.section.depth >= 4
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect4) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect5'
+ and $chunk.section.depth >= 5
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect5) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'section'
+ and $chunk.section.depth >= count($node/ancestor::section)+1
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::section) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="local-name($node)='preface'">1</xsl:when>
+ <xsl:when test="local-name($node)='chapter'">1</xsl:when>
+ <xsl:when test="local-name($node)='appendix'">1</xsl:when>
+ <xsl:when test="local-name($node)='article'">1</xsl:when>
+ <xsl:when test="local-name($node)='part'">1</xsl:when>
+ <xsl:when test="local-name($node)='reference'">1</xsl:when>
+ <xsl:when test="local-name($node)='refentry'">1</xsl:when>
+ <xsl:when test="local-name($node)='index' and ($generate.index != 0 or count($node/*) > 0)
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='bibliography'
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='glossary'
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='colophon'">1</xsl:when>
+ <xsl:when test="local-name($node)='book'">1</xsl:when>
+ <xsl:when test="local-name($node)='set'">1</xsl:when>
+ <xsl:when test="local-name($node)='setindex'">1</xsl:when>
+ <xsl:when test="local-name($node)='legalnotice'
+ and $generate.legalnotice.link != 0">1</xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml-release.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml-single-diffmk.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-single-diffmk.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-single-diffmk.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,130 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="classpath:/xslt/org/jboss/xhtml-single.xsl"/>
+ <xsl:import href="xhtml-common-reldiffmk.xsl"/>
+ <xsl:param name="html.stylesheet" select="'css/html-release.css'"/>
+ <xsl:template name="book.titlepage.recto">
+ <div id="overlay">
+ <xsl:text> </xsl:text>
+ </div>
+<!-- FEEDBACK -->
+ <div id="feedback-maincontainer" style="display:none">
+ <div id="feedback-header">
+ Send your remarks, comments or wishes to doc team
+ </div>
+ <a href="#" onclick="$('feedback-maincontainer').hide(); return false;" id="feedback-close">
+ <img src="images/close.png" class="feedback-images" />
+ </a>
+ <div id="feedback-state"><xsl:text> </xsl:text></div>
+ <form id="feedback-mailform">
+ <div class="feedback-textbox-div">
+ Subject:<input type="text" id="subject" name="subject" title="Enter the subject of your message" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ <span style="vertical-align: top;">Message:</span>
+ <textarea name="message" title="Type here the text of your message" id="message"><xsl:text> </xsl:text></textarea>
+ </div>
+ <div class="feedback-textbox-div">
+ Your name:<input type="text" id="name" name="name" title="Enter your name" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ Your email:<input type="text" id="email" name="email" title="Enter your email address" class="feedback-textbox" />
+ </div>
+ <span class="feedback-button-container">
+ <input type="submit" value="Send Message" name="submit" class="feedback-formbutton" title="Send Message" />
+ </span>
+ <span class="feedback-button-container">
+ <input type="reset" value="Clear All Fields" class="feedback-formbutton" title="Clear All Fields" />
+ </span>
+ </form>
+ </div>
+ <div id="feedback-wrapper">
+ <a id="feedback-link" href="#" onclick="$('feedback-maincontainer').appear(); return false;">
+ <img src="images/feedback_logo.png" class="feedback-images" width="100px"/>
+ </a>
+ </div>
+ <!-- FEEDBACK ENDS -->
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:attribute name="id">
+ <xsl:text>title</xsl:text>
+ </xsl:attribute>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$siteHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>site_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$siteLinkText"/>
+ </strong>
+ </a>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$docHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>doc_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$docLinkText"/>
+ </strong>
+ </a>
+ </p>
+ <xsl:choose>
+ <xsl:when test="bookinfo/title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/title"/>
+ </xsl:when>
+ <xsl:when test="info/title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/title"/>
+ </xsl:when>
+ <xsl:when test="title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="title"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="bookinfo/subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/subtitle"/>
+ </xsl:when>
+ <xsl:when test="info/subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/subtitle"/>
+ </xsl:when>
+ <xsl:when test="subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="subtitle"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/corpauthor"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/corpauthor"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/authorgroup"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/authorgroup"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/author"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/author"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/othercredit"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/othercredit"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/releaseinfo"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/releaseinfo"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/legalnotice"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/legalnotice"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/revision"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/revision"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/revhistory"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/revhistory"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/abstract"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/abstract"/>
+</xsl:template>
+
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml-single-diffmk.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml-single-release.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-single-release.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-single-release.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,127 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="classpath:/xslt/org/jboss/xhtml-single.xsl"/>
+ <xsl:import href="xhtml-common-reldiffmk.xsl"/>
+ <xsl:param name="html.stylesheet" select="'css/html-release.css'"/>
+ <xsl:template name="book.titlepage.recto">
+<!-- FEEDBACK -->
+ <div id="feedback-maincontainer" style="display:none">
+ <div id="feedback-header">
+ Send your remarks, comments or wishes to doc team
+ </div>
+ <a href="#" onclick="$('feedback-maincontainer').hide(); return false;" id="feedback-close">
+ <img src="images/close.png" class="feedback-images" />
+ </a>
+ <div id="feedback-state"><xsl:text> </xsl:text></div>
+ <form id="feedback-mailform">
+ <div class="feedback-textbox-div">
+ Subject:<input type="text" id="subject" name="subject" title="Enter the subject of your message" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ <span style="vertical-align: top;">Message:</span>
+ <textarea name="message" title="Type here the text of your message" id="message"><xsl:text> </xsl:text></textarea>
+ </div>
+ <div class="feedback-textbox-div">
+ Your name:<input type="text" id="name" name="name" title="Enter your name" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ Your email:<input type="text" id="email" name="email" title="Enter your email address" class="feedback-textbox" />
+ </div>
+ <span class="feedback-button-container">
+ <input type="submit" value="Send Message" name="submit" class="feedback-formbutton" title="Send Message" />
+ </span>
+ <span class="feedback-button-container">
+ <input type="reset" value="Clear All Fields" class="feedback-formbutton" title="Clear All Fields" />
+ </span>
+ </form>
+ </div>
+ <div id="feedback-wrapper">
+ <a id="feedback-link" href="#" onclick="$('feedback-maincontainer').appear(); return false;">
+ <img src="images/feedback_logo.png" class="feedback-images" width="100px"/>
+ </a>
+ </div>
+ <!-- FEEDBACK ENDS -->
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:attribute name="id">
+ <xsl:text>title</xsl:text>
+ </xsl:attribute>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$siteHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>site_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$siteLinkText"/>
+ </strong>
+ </a>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$docHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>doc_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$docLinkText"/>
+ </strong>
+ </a>
+ </p>
+ <xsl:choose>
+ <xsl:when test="bookinfo/title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/title"/>
+ </xsl:when>
+ <xsl:when test="info/title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/title"/>
+ </xsl:when>
+ <xsl:when test="title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="title"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="bookinfo/subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/subtitle"/>
+ </xsl:when>
+ <xsl:when test="info/subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/subtitle"/>
+ </xsl:when>
+ <xsl:when test="subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="subtitle"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/corpauthor"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/corpauthor"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/authorgroup"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/authorgroup"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/author"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/author"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/othercredit"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/othercredit"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/releaseinfo"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/releaseinfo"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/legalnotice"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/legalnotice"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/revision"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/revision"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/revhistory"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/revhistory"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/abstract"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/abstract"/>
+</xsl:template>
+
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml-single-release.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml-single.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml-single.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml-single.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,131 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:import href="classpath:/xslt/org/jboss/xhtml-single.xsl"/>
+<xsl:import href="xhtml-common.xsl"/>
+<xsl:param name="html.stylesheet" select="'css/html.css'"/>
+
+<xsl:template name="book.titlepage.recto">
+ <div id="overlay">
+ <xsl:text> </xsl:text>
+ </div>
+<!-- FEEDBACK -->
+ <div id="feedback-maincontainer" style="display:none">
+ <div id="feedback-header">
+ Send your remarks, comments or wishes to doc team
+ </div>
+ <a href="#" onclick="$('feedback-maincontainer').hide(); return false;" id="feedback-close">
+ <img src="images/close.png" class="feedback-images" />
+ </a>
+ <div id="feedback-state"><xsl:text> </xsl:text></div>
+ <form id="feedback-mailform">
+ <div class="feedback-textbox-div">
+ Subject:<input type="text" id="subject" name="subject" title="Enter the subject of your message" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ <span style="vertical-align: top;">Message:</span>
+ <textarea name="message" title="Type here the text of your message" id="message"><xsl:text> </xsl:text></textarea>
+ </div>
+ <div class="feedback-textbox-div">
+ Your name:<input type="text" id="name" name="name" title="Enter your name" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ Your email:<input type="text" id="email" name="email" title="Enter your email address" class="feedback-textbox" />
+ </div>
+ <span class="feedback-button-container">
+ <input type="submit" value="Send Message" name="submit" class="feedback-formbutton" title="Send Message" />
+ </span>
+ <span class="feedback-button-container">
+ <input type="reset" value="Clear All Fields" class="feedback-formbutton" title="Clear All Fields" />
+ </span>
+ </form>
+ </div>
+ <div id="feedback-wrapper">
+ <a id="feedback-link" href="#" onclick="$('feedback-maincontainer').appear(); return false;">
+ <img src="images/feedback_logo.png" class="feedback-images" width="100px"/>
+ </a>
+ </div>
+ <!-- FEEDBACK ENDS -->
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:attribute name="id">
+ <xsl:text>title</xsl:text>
+ </xsl:attribute>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$siteHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>site_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$siteLinkText"/>
+ </strong>
+ </a>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$docHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>doc_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$docLinkText"/>
+ </strong>
+ </a>
+ </p>
+ <xsl:choose>
+ <xsl:when test="bookinfo/title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/title"/>
+ </xsl:when>
+ <xsl:when test="info/title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/title"/>
+ </xsl:when>
+ <xsl:when test="title">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="title"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="bookinfo/subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/subtitle"/>
+ </xsl:when>
+ <xsl:when test="info/subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/subtitle"/>
+ </xsl:when>
+ <xsl:when test="subtitle">
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="subtitle"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/corpauthor"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/corpauthor"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/authorgroup"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/authorgroup"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/author"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/author"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/othercredit"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/othercredit"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/releaseinfo"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/releaseinfo"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/copyright"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/legalnotice"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/legalnotice"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/pubdate"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/revision"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/revision"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/revhistory"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/revhistory"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="bookinfo/abstract"/>
+ <xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="info/abstract"/>
+</xsl:template>
+
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml-single.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/en/src/main/xslt/xhtml.xsl
===================================================================
--- trunk/docs/common-resources/en/src/main/xslt/xhtml.xsl (rev 0)
+++ trunk/docs/common-resources/en/src/main/xslt/xhtml.xsl 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,226 @@
+<?xml version='1.0'?>
+
+<!--
+ Copyright 2008 JBoss, a division of Red Hat
+ License: LGPL
+ Author: Mark Newton <mark.newton(a)jboss.org>
+-->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="classpath:/xslt/org/jboss/xhtml.xsl"/>
+ <xsl:import href="xhtml-common.xsl"/>
+
+<xsl:param name="chunk.fast" select="1"/>
+<xsl:param name="html.stylesheet" select="'css/html.css'"/>
+
+<xsl:template name="header.navigation">
+ <xsl:param name="prev" select="/foo"/>
+ <xsl:param name="next" select="/foo"/>
+ <xsl:param name="nav.context"/>
+ <xsl:variable name="home" select="/*[1]"/>
+ <xsl:variable name="up" select="parent::*"/>
+ <xsl:variable name="row1" select="$navig.showtitles != 0"/>
+ <xsl:variable name="row2" select="count($prev) > 0 or (count($up) > 0 and generate-id($up) != generate-id($home) and $navig.showtitles != 0) or count($next) > 0"/>
+ <xsl:if test="$suppress.navigation = '0' and $suppress.header.navigation = '0'">
+ <xsl:if test="$row1 or $row2">
+ <xsl:if test="$row1">
+ <div id="overlay">
+ <xsl:text> </xsl:text>
+ </div>
+
+ <!-- FEEDBACK -->
+ <div id="feedback-maincontainer" style="display:none">
+ <div id="feedback-header">
+ Send your remarks, comments or wishes to doc team
+ </div>
+ <a href="#" onclick="$('feedback-maincontainer').hide(); return false;" id="feedback-close">
+ <img src="images/close.png" class="feedback-images" />
+ </a>
+ <div id="feedback-state"><xsl:text> </xsl:text></div>
+
+ <form id="feedback-mailform">
+ <div class="feedback-textbox-div">
+ Subject:<input type="text" id="subject" name="subject" title="Enter the subject of your message" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ <span style="vertical-align: top;">Message:</span>
+ <textarea name="message" title="Type here the text of your message" id="message"><xsl:text> </xsl:text></textarea>
+ </div>
+ <div class="feedback-textbox-div">
+ Your name:<input type="text" id="name" name="name" title="Enter your name" class="feedback-textbox" />
+ </div>
+ <div class="feedback-textbox-div">
+ Your email:<input type="text" id="email" name="email" title="Enter your email address" class="feedback-textbox" />
+ </div>
+ <span class="feedback-button-container">
+ <input type="submit" value="Send Message" name="submit" class="feedback-formbutton" title="Send Message" />
+ </span>
+ <span class="feedback-button-container">
+ <input type="reset" value="Clear All Fields" class="feedback-formbutton" title="Clear All Fields" />
+ </span>
+ </form>
+ </div>
+ <div id="feedback-wrapper">
+ <a id="feedback-link" href="#" onclick="$('feedback-maincontainer').appear(); return false;">
+ <img src="images/feedback_logo.png" class="feedback-images" width="100px"/>
+ </a>
+ </div>
+ <!-- FEEDBACK ENDS -->
+
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:attribute name="id">
+ <xsl:text>title</xsl:text>
+ </xsl:attribute>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$siteHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>site_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$siteLinkText"/>
+ </strong>
+ </a>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="$docHref" />
+ </xsl:attribute>
+ <xsl:attribute name="class">
+ <xsl:text>doc_href</xsl:text>
+ </xsl:attribute>
+ <strong>
+ <xsl:value-of select="$docLinkText"/>
+ </strong>
+ </a>
+ </p>
+ </xsl:if>
+ <xsl:if test="$row2">
+ <ul class="docnav" xmlns="http://www.w3.org/1999/xhtml">
+ <li class="previous">
+ <xsl:if test="count($prev)>0">
+ <a accesskey="p">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$prev"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <strong>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'prev'"/>
+ </xsl:call-template>
+ </strong>
+ </a>
+ </xsl:if>
+ </li>
+ <li class="next">
+ <xsl:if test="count($next)>0">
+ <a accesskey="n">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$next"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <strong>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'next'"/>
+ </xsl:call-template>
+ </strong>
+ </a>
+ </xsl:if>
+ </li>
+ </ul>
+ </xsl:if>
+ </xsl:if>
+ <xsl:if test="$header.rule != 0">
+ <hr/>
+ </xsl:if>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="chunk">
+ <xsl:param name="node" select="."/>
+
+ <xsl:choose>
+ <xsl:when test="not($node/parent::*)">1</xsl:when>
+ <xsl:when test="$node/parent::node()/processing-instruction('forseChanks') and local-name($node)!='title' and local-name($node)!='para' and local-name($node)='section'" >1</xsl:when>
+ <xsl:when test="local-name($node) = 'sect1'
+ and $chunk.section.depth >= 1
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect1) > 0)">
+ <xsl:text>1</xsl:text>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect2'
+ and $chunk.section.depth >= 2
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect2) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect3'
+ and $chunk.section.depth >= 3
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect3) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect4'
+ and $chunk.section.depth >= 4
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect4) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'sect5'
+ and $chunk.section.depth >= 5
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::sect5) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name($node) = 'section'
+ and $chunk.section.depth >= count($node/ancestor::section)+1
+ and ($chunk.first.sections != 0
+ or count($node/preceding-sibling::section) > 0)">
+ <xsl:call-template name="chunk">
+ <xsl:with-param name="node" select="$node/parent::*"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="local-name($node)='preface'">1</xsl:when>
+ <xsl:when test="local-name($node)='chapter'">1</xsl:when>
+ <xsl:when test="local-name($node)='appendix'">1</xsl:when>
+ <xsl:when test="local-name($node)='article'">1</xsl:when>
+ <xsl:when test="local-name($node)='part'">1</xsl:when>
+ <xsl:when test="local-name($node)='reference'">1</xsl:when>
+ <xsl:when test="local-name($node)='refentry'">1</xsl:when>
+ <xsl:when test="local-name($node)='index' and ($generate.index != 0 or count($node/*) > 0)
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='bibliography'
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='glossary'
+ and (local-name($node/parent::*) = 'article'
+ or local-name($node/parent::*) = 'book'
+ or local-name($node/parent::*) = 'part'
+ )">1</xsl:when>
+ <xsl:when test="local-name($node)='colophon'">1</xsl:when>
+ <xsl:when test="local-name($node)='book'">1</xsl:when>
+ <xsl:when test="local-name($node)='set'">1</xsl:when>
+ <xsl:when test="local-name($node)='setindex'">1</xsl:when>
+ <xsl:when test="local-name($node)='legalnotice'
+ and $generate.legalnotice.link != 0">1</xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+</xsl:stylesheet>
Property changes on: trunk/docs/common-resources/en/src/main/xslt/xhtml.xsl
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/common-resources/pom.xml
===================================================================
--- trunk/docs/common-resources/pom.xml (rev 0)
+++ trunk/docs/common-resources/pom.xml 2008-11-18 13:07:37 UTC (rev 11206)
@@ -0,0 +1,29 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>docs</artifactId>
+ <groupId>org.richfaces</groupId>
+ <version>3.3.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces.docs</groupId>
+ <artifactId>common-resources</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Documentation common resources</name>
+ <description>Common resources</description>
+ <modules>
+ <module>en</module>
+ </modules>
+ <!--build>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build-->
+</project>
\ No newline at end of file
Property changes on: trunk/docs/common-resources/pom.xml
___________________________________________________________________
Name: svn:executable
+ *
17 years, 6 months
JBoss Rich Faces SVN: r11205 - trunk/docs.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2008-11-18 08:07:06 -0500 (Tue, 18 Nov 2008)
New Revision: 11205
Modified:
trunk/docs/pom.xml
Log:
https://jira.jboss.org/jira/browse/RF-4107 - one resources folder was added
Modified: trunk/docs/pom.xml
===================================================================
--- trunk/docs/pom.xml 2008-11-18 13:04:02 UTC (rev 11204)
+++ trunk/docs/pom.xml 2008-11-18 13:07:06 UTC (rev 11205)
@@ -70,6 +70,20 @@
</modules>
</profile>
+ <profile>
+ <id>release_docs</id>
+ <properties>
+ <xsl_html_single>classpath:/common-resources/xslt/xhtml-single-release.xsl</xsl_html_single>
+ <xsl_html>classpath:/common-resources/xslt/xhtml-release.xsl</xsl_html>
+ </properties>
+ </profile>
+ <profile>
+ <id>diffmk</id>
+ <properties>
+ <xsl_html_single>classpath:/common-resources/xslt/xhtml-single-diffmk.xsl</xsl_html_single>
+ <xsl_html>classpath:/common-resources/xslt/xhtml-diffmk.xsl</xsl_html>
+ </properties>
+ </profile>
</profiles>
<build>
@@ -87,4 +101,8 @@
</plugins>
</pluginManagement>
</build>
+ <properties>
+ <xsl_html_single>classpath:/common-resources/xslt/xhtml-single.xsl</xsl_html_single>
+ <xsl_html>classpath:/common-resources/xslt/xhtml.xsl</xsl_html>
+ </properties>
</project>
\ No newline at end of file
17 years, 6 months
JBoss Rich Faces SVN: r11204 - in trunk/docs/cdkguide: en/src/main/docbook/modules and 2 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2008-11-18 08:04:02 -0500 (Tue, 18 Nov 2008)
New Revision: 11204
Removed:
trunk/docs/cdkguide/en/src/main/resources/css/
trunk/docs/cdkguide/en/src/main/resources/images/favicon.ico
trunk/docs/cdkguide/en/src/main/resources/images/ico_important.gif
trunk/docs/cdkguide/en/src/main/resources/images/ico_note.gif
trunk/docs/cdkguide/en/src/main/resources/images/ico_tip.gif
trunk/docs/cdkguide/en/src/main/resources/images/richfaces_label2.png
trunk/docs/cdkguide/en/src/main/resources/script/
trunk/docs/cdkguide/en/src/main/resources/xslt/
Modified:
trunk/docs/cdkguide/en/src/main/docbook/modules/namingconv.xml
trunk/docs/cdkguide/pom.xml
Log:
https://jira.jboss.org/jira/browse/RF-4107 - one resources folder was added
Modified: trunk/docs/cdkguide/en/src/main/docbook/modules/namingconv.xml
===================================================================
--- trunk/docs/cdkguide/en/src/main/docbook/modules/namingconv.xml 2008-11-18 11:52:53 UTC (rev 11203)
+++ trunk/docs/cdkguide/en/src/main/docbook/modules/namingconv.xml 2008-11-18 13:04:02 UTC (rev 11204)
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<chapter id="namingconv" xreflabel="namingconv">
+<chapter id="namingconv" xreflabel="namingconv" role="new">
<?dbhtml filename="namingconv.html"?>
<chapterinfo>
<keywordset>
Deleted: trunk/docs/cdkguide/en/src/main/resources/images/favicon.ico
===================================================================
(Binary files differ)
Deleted: trunk/docs/cdkguide/en/src/main/resources/images/ico_important.gif
===================================================================
(Binary files differ)
Deleted: trunk/docs/cdkguide/en/src/main/resources/images/ico_note.gif
===================================================================
(Binary files differ)
Deleted: trunk/docs/cdkguide/en/src/main/resources/images/ico_tip.gif
===================================================================
(Binary files differ)
Deleted: trunk/docs/cdkguide/en/src/main/resources/images/richfaces_label2.png
===================================================================
(Binary files differ)
Modified: trunk/docs/cdkguide/pom.xml
===================================================================
--- trunk/docs/cdkguide/pom.xml 2008-11-18 11:52:53 UTC (rev 11203)
+++ trunk/docs/cdkguide/pom.xml 2008-11-18 13:04:02 UTC (rev 11204)
@@ -26,11 +26,51 @@
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
+
<build>
<pluginManagement>
<plugins>
-
+
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>
+ org.richfaces.docs.common-resources
+ </groupId>
+ <artifactId>
+ ${project.translation}
+ </artifactId>
+ <version>
+ ${project.version}
+ </version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>
+ ${project.build.directory}
+ </outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ <overWriteReleases>
+ false
+ </overWriteReleases>
+ <overWriteSnapshots>
+ true
+ </overWriteSnapshots>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-jdocbook-plugin</artifactId>
<version>2.1.0-200803311251UTC-MPJDOCBOOK-8</version>
@@ -69,6 +109,12 @@
<version>1.1.0-SNAPSHOT</version>
<type>jdocbook-style</type>
</dependency>
+ <dependency>
+ <groupId>org.richfaces.docs.common-resources</groupId>
+ <artifactId>${translation}</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ </dependency>
</dependencies>
<configuration>
<sourceDirectory>
@@ -81,15 +127,13 @@
</imageResource>
<cssResource>
<directory>
- ${basedir}/src/main/resources
+ ${project.build.directory}/common-resources
</directory>
</cssResource>
-
<sourceDocumentName>
master.xml
</sourceDocumentName>
<formats>
-
<format>
<formatName>pdf</formatName>
<stylesheetResource>
@@ -105,7 +149,7 @@
<format>
<formatName>html</formatName>
<stylesheetResource>
- file:${pom.basedir}/src/main/resources/xslt/org/jboss/richfaces/xhtml.xsl
+ ${xsl_html}
</stylesheetResource>
<finalName>
index.html
@@ -117,11 +161,10 @@
false
</imagePathSettingRequired>
</format>
-
<format>
<formatName>html_single</formatName>
<stylesheetResource>
- file:${pom.basedir}/src/main/resources/xslt/org/jboss/richfaces/xhtml-single.xsl
+ ${xsl_html_single}
</stylesheetResource>
<imageCopyingRequired>
true
17 years, 6 months
JBoss Rich Faces SVN: r11203 - trunk/samples/richfaces-demo/src/main/webapp/richfaces/extendedDataTable/examples.
by richfaces-svn-commits@lists.jboss.org
Author: pgolawski
Date: 2008-11-18 06:52:53 -0500 (Tue, 18 Nov 2008)
New Revision: 11203
Modified:
trunk/samples/richfaces-demo/src/main/webapp/richfaces/extendedDataTable/examples/simple.xhtml
Log:
filter "State Capital" column by capital name instead of state name, probably copy/paste bug
Modified: trunk/samples/richfaces-demo/src/main/webapp/richfaces/extendedDataTable/examples/simple.xhtml
===================================================================
--- trunk/samples/richfaces-demo/src/main/webapp/richfaces/extendedDataTable/examples/simple.xhtml 2008-11-18 11:38:40 UTC (rev 11202)
+++ trunk/samples/richfaces-demo/src/main/webapp/richfaces/extendedDataTable/examples/simple.xhtml 2008-11-18 11:52:53 UTC (rev 11203)
@@ -24,7 +24,7 @@
</f:facet>
<h:outputText value="#{cap.state}"/>
</rich:column>
- <rich:column sortable="true" sortBy="#{cap.name}" filterBy="#{cap.state}" filterEvent="onkeyup" width="170px" label="State Capital">
+ <rich:column sortable="true" sortBy="#{cap.name}" filterBy="#{cap.name}" filterEvent="onkeyup" width="170px" label="State Capital">
<f:facet name="header">
<h:outputText value="State Capital"/>
</f:facet>
17 years, 6 months
JBoss Rich Faces SVN: r11202 - in trunk/sandbox: samples/editor-sample/src/main/webapp/WEB-INF and 3 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: pyaschenko
Date: 2008-11-18 06:38:40 -0500 (Tue, 18 Nov 2008)
New Revision: 11202
Added:
trunk/sandbox/samples/editor-sample/src/main/java/org/richfaces/MiracleBean.java
trunk/sandbox/samples/editor-sample/src/main/webapp/pages/miracle-editor.jsp
Modified:
trunk/sandbox/samples/editor-sample/src/main/webapp/WEB-INF/faces-config.xml
trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/editor.js
trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/tiny_mce/themes/advanced/skins/richfaces/ui.xcss
Log:
miracleBean added & some css fixes
Added: trunk/sandbox/samples/editor-sample/src/main/java/org/richfaces/MiracleBean.java
===================================================================
--- trunk/sandbox/samples/editor-sample/src/main/java/org/richfaces/MiracleBean.java (rev 0)
+++ trunk/sandbox/samples/editor-sample/src/main/java/org/richfaces/MiracleBean.java 2008-11-18 11:38:40 UTC (rev 11202)
@@ -0,0 +1,119 @@
+package org.richfaces;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.html.HtmlCommandButton;
+import javax.faces.component.html.HtmlInputText;
+import javax.faces.component.html.HtmlOutputLabel;
+import javax.faces.component.html.HtmlPanelGrid;
+import javax.faces.component.html.HtmlSelectBooleanCheckbox;
+import javax.faces.context.FacesContext;
+
+
+public class MiracleBean {
+
+ private UIComponent component;
+
+ private UIComponent containerComponent;
+
+ private Map<String, Object> values = new HashMap<String, Object>();
+
+ public UIComponent getComponent() {
+ return component;
+ }
+
+ public void setComponent(UIComponent component) {
+ this.component = component;
+ }
+
+ public UIComponent getContainerComponent() {
+ if (containerComponent == null) {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ containerComponent = new HtmlPanelGrid();
+
+ List<UIComponent> children = containerComponent.getChildren();
+ children.clear();
+
+ try {
+ BeanInfo beanInfo = java.beans.Introspector.getBeanInfo(component.getClass());
+
+ for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
+ String name = pd.getName();
+
+ if ("submittedValue".equals(name) || "id".equals(name) || "transient".equals(name) || "rendered".equals(name) || "rendererType".equals(name) || "localValueSet".equals(name)) {
+ continue;
+ }
+
+ UIInput input = null;
+
+ Class<?> type = pd.getPropertyType();
+ if (pd.getWriteMethod() != null) {
+ if (Boolean.class.isAssignableFrom(type) || Boolean.TYPE.equals(type)) {
+ input = new HtmlSelectBooleanCheckbox();
+ } else if (type.getName().startsWith("java.lang.") || type.isPrimitive()) {
+ input = new HtmlInputText();
+ }
+
+ if (input != null) {
+ input.setConverter(facesContext.getApplication().createConverter(type));
+
+ HtmlOutputLabel label = new HtmlOutputLabel();
+ label.setValue(name);
+ label.setFor(name);
+ label.setId(name + "_lbl");
+
+ children.add(label);
+
+ input.setId(name);
+ input.setValueExpression("value",
+ facesContext.getApplication().getExpressionFactory().createValueExpression(
+ facesContext.getELContext(), "#{miracleBean.values['"+name+"']}", type));
+
+ children.add(input);
+ }
+ }
+ }
+ } catch (IntrospectionException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ HtmlCommandButton button = new HtmlCommandButton();
+ button.setValue("Submit");
+ button.setActionExpression(facesContext.getApplication().getExpressionFactory().createMethodExpression(facesContext.getELContext(), "#{miracleBean.applyValues}", Void.TYPE, new Class[0]));
+
+ children.add(button);
+ }
+
+ return containerComponent;
+ }
+
+ public void setContainerComponent(UIComponent containerComponent) {
+ this.containerComponent = containerComponent;
+ }
+
+ public Map<String, Object> getValues() {
+ return values;
+ }
+
+ public void setValues(Map<String, Object> values) {
+ this.values = values;
+ }
+
+ public void applyValues() {
+ Map<String, Object> attributes = component.getAttributes();
+
+ for (Map.Entry<String, Object> entry : values.entrySet()) {
+ attributes.put(entry.getKey(), entry.getValue());
+ }
+ }
+}
Modified: trunk/sandbox/samples/editor-sample/src/main/webapp/WEB-INF/faces-config.xml
===================================================================
--- trunk/sandbox/samples/editor-sample/src/main/webapp/WEB-INF/faces-config.xml 2008-11-18 10:23:45 UTC (rev 11201)
+++ trunk/sandbox/samples/editor-sample/src/main/webapp/WEB-INF/faces-config.xml 2008-11-18 11:38:40 UTC (rev 11202)
@@ -11,6 +11,11 @@
<managed-bean-name>editorBean</managed-bean-name>
<managed-bean-class>org.richfaces.EditorBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
+ </managed-bean>
+ <managed-bean>
+ <managed-bean-name>miracleBean</managed-bean-name>
+ <managed-bean-class>org.richfaces.MiracleBean</managed-bean-class>
+ <managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Added: trunk/sandbox/samples/editor-sample/src/main/webapp/pages/miracle-editor.jsp
===================================================================
--- trunk/sandbox/samples/editor-sample/src/main/webapp/pages/miracle-editor.jsp (rev 0)
+++ trunk/sandbox/samples/editor-sample/src/main/webapp/pages/miracle-editor.jsp 2008-11-18 11:38:40 UTC (rev 11202)
@@ -0,0 +1,37 @@
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
+<%@ taglib uri="http://labs.jboss.com/jbossrichfaces/ui/ui/editor" prefix="ed" %>
+<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j" %>
+<html>
+ <head>
+ <title></title>
+ <style>
+ .myStyle{
+ border:1px solid;
+
+ }
+ </style>
+ </head>
+ <body>
+ <f:view >
+ <h:form>
+ <h:panelGrid columns="1">
+ <h:selectOneRadio binding="#{skinBean.component}" />
+ <h:commandLink action="#{skinBean.change}" value="set skin" />
+ <h:outputText value="Current Skin: #{skinBean.skin}"/>
+ </h:panelGrid>
+ </h:form>
+
+ <h:form id="formId">
+
+ <ed:editor binding="#{miracleBean.component}"
+ plugins="safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,myemotions">
+ </ed:editor>
+
+ <h:panelGrid columns="2" binding="#{miracleBean.containerComponent}" />
+
+
+ </h:form>
+ </f:view>
+ </body>
+</html>
Modified: trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/editor.js
===================================================================
--- trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/editor.js 2008-11-18 10:23:45 UTC (rev 11201)
+++ trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/editor.js 2008-11-18 11:38:40 UTC (rev 11202)
@@ -60,10 +60,10 @@
if(this.params.useSeamText){
this.tinyparams.plugins = Richfaces.Editor.SeamTextConfiguration.plugins;
- this.tinyparams.theme_advanced_buttons1 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons1;
- this.tinyparams.theme_advanced_buttons2 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons2;
- this.tinyparams.theme_advanced_buttons3 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons3;
- this.tinyparams.theme_advanced_buttons4 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons4;
+ //this.tinyparams.theme_advanced_buttons1 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons1;
+ //this.tinyparams.theme_advanced_buttons2 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons2;
+ //this.tinyparams.theme_advanced_buttons3 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons3;
+ //this.tinyparams.theme_advanced_buttons4 = Richfaces.Editor.SeamTextConfiguration.theme_advanced_buttons4;
}
}
@@ -74,9 +74,9 @@
plugins : "safari,spellchecker,style,table,save,advhr,advimage,advlink,iespell,inlinepopups,insertdatetime,preview,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
// Theme options
- theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,|,cut,copy,paste,pastetext,pasteword",
- theme_advanced_buttons2 : "search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
- theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,iespell,advhr,|,print,|,ltr,rtl,|,fullscreen",
- theme_advanced_buttons4 : "styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote"
+ //theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,|,cut,copy,paste,pastetext,pasteword",
+ //theme_advanced_buttons2 : "search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
+ //theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,iespell,advhr,|,print,|,ltr,rtl,|,fullscreen",
+ //theme_advanced_buttons4 : "styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote"
}
\ No newline at end of file
Modified: trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/tiny_mce/themes/advanced/skins/richfaces/ui.xcss
===================================================================
--- trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/tiny_mce/themes/advanced/skins/richfaces/ui.xcss 2008-11-18 10:23:45 UTC (rev 11201)
+++ trunk/sandbox/ui/editor/src/main/resources/org/richfaces/renderkit/html/scripts/tiny_mce/themes/advanced/skins/richfaces/ui.xcss 2008-11-18 11:38:40 UTC (rev 11202)
@@ -247,10 +247,10 @@
</u:selector>
<u:selector name=".richfacesSkin .mceListBox .mceText">
- <u:style name="background" skin="additionalBackgroundColor"/>
+ <u:style name="background" skin="tableBackgroundColor"/>
<u:style name="border-width" value="1px"/>
<u:style name="border-style" value="solid"/>
- <u:style name="border-color" skin="additionalBackgroundColor"/>
+ <u:style name="border-color" skin="panelBorderColor"/>
<u:style name="border-right" value="0"/>
<u:style name="font-family" skin="generalFamilyFont"/>
</u:selector>
17 years, 6 months
JBoss Rich Faces SVN: r11201 - trunk/docs/userguide/en/src/main/docbook/included.
by richfaces-svn-commits@lists.jboss.org
Author: cluts
Date: 2008-11-18 05:23:45 -0500 (Tue, 18 Nov 2008)
New Revision: 11201
Modified:
trunk/docs/userguide/en/src/main/docbook/included/calendar.xml
trunk/docs/userguide/en/src/main/docbook/included/datascroller.xml
trunk/docs/userguide/en/src/main/docbook/included/dropDownMenu.xml
trunk/docs/userguide/en/src/main/docbook/included/extendedDataTable.xml
trunk/docs/userguide/en/src/main/docbook/included/listShuttle.xml
trunk/docs/userguide/en/src/main/docbook/included/menuGroup.xml
trunk/docs/userguide/en/src/main/docbook/included/menuItem.xml
trunk/docs/userguide/en/src/main/docbook/included/message.xml
trunk/docs/userguide/en/src/main/docbook/included/messages.xml
trunk/docs/userguide/en/src/main/docbook/included/modalPanel.xml
trunk/docs/userguide/en/src/main/docbook/included/orderingList.xml
Log:
RF-4502 - tables were added for the following components: calendar, datascroller(the table incomplete), dropDownMenu, extendedDataTable, listShuttle, menuGroup, menuItem, message, messages, modalPanel, orderingList
Modified: trunk/docs/userguide/en/src/main/docbook/included/calendar.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/calendar.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/calendar.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -812,6 +812,50 @@
</table>
</section>
+
+
+ <section>
+ <title>
+ Facets
+ </title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>header</entry>
+ <entry>Redefines calendar header. Related attribute is "showHeader"</entry>
+ </row>
+ <row>
+ <entry>footer</entry>
+ <entry>Redefines calendar footer. Related attribute is "showFooter"</entry>
+ </row>
+ <row>
+ <entry>optionalHeader</entry>
+ <entry>Defines calendar's optional header</entry>
+ </row>
+ <row>
+ <entry>optionalFooter</entry>
+ <entry>Defines calendar's optional footer</entry>
+ </row>
+ <row>
+ <entry>weekNumber</entry>
+ <entry>Redefines week number</entry>
+ </row>
+ <row>
+ <entry>weekDay</entry>
+ <entry>Redefines names of the week days. Related attributes are "weekDayLabels" and "weekDayLabelsShort"</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
Modified: trunk/docs/userguide/en/src/main/docbook/included/datascroller.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/datascroller.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/datascroller.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -331,6 +331,43 @@
</emphasis>, will be rendered in browser. </para>
</note>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>controlSeparator</entry>
+ <entry>Redefines optional separators between controls</entry>
+ </row>
+ <row>
+ <entry>first</entry>
+ <entry>Redefines the "first" button with the content set</entry>
+ </row>
+ <row>
+ <entry>first_disabled</entry>
+ <entry>Redefines the disabled "first" button with the content set</entry>
+ </row>
+ <row>
+ <entry>last</entry>
+ <entry>Redefines the "last" button with the content set</entry>
+ </row>
+ <row>
+ <entry>last_disabled</entry>
+ <entry>Redefines the disabled "last" button with the content set</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
Modified: trunk/docs/userguide/en/src/main/docbook/included/dropDownMenu.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/dropDownMenu.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/dropDownMenu.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -345,6 +345,31 @@
...]]></programlisting>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>label</entry>
+ <entry>Redefines the content set of label</entry>
+ </row>
+ <row>
+ <entry>labelDisabled</entry>
+ <entry>Redefines the content set of disabled label</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
Modified: trunk/docs/userguide/en/src/main/docbook/included/extendedDataTable.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/extendedDataTable.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/extendedDataTable.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -286,7 +286,38 @@
</section>
+
<section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>header</entry>
+ <entry>Redefines the header content</entry>
+ </row>
+ <row>
+ <entry>footer</entry>
+ <entry>Redefines the footer content</entry>
+ </row>
+ <row>
+ <entry>caption</entry>
+ <entry>Redefines the caption content</entry>
+ </row>
+ </tbody>
+ </tgroup>
+
+ </table>
+ </section>
+
+ <section>
<title>Look-and-Feel Customization</title>
<para>For skinnability implementation, the components use a <emphasis>
Modified: trunk/docs/userguide/en/src/main/docbook/included/listShuttle.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/listShuttle.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/listShuttle.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -474,7 +474,53 @@
</tgroup>
</table>
</section>
+
<section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>copyAllControl</entry>
+ <entry>Redefines the label content for the "copyAll" control. Related attribute is "copyAllControlLabel"</entry>
+ </row>
+ <row>
+ <entry>removeAllControl</entry>
+ <entry>Redefines the label content for the "removeAll" control. Related attribute is "removeAllControlLabel"</entry>
+ </row>
+ <row>
+ <entry>copyControl</entry>
+ <entry>Redefines the label content for the "copy" control. Related attribute is "copyControlLabel"</entry>
+ </row>
+ <row>
+ <entry>removeControl</entry>
+ <entry>Redefines the label content for the "remove" control. Related attribute is "removeControlLabel"</entry>
+ </row>
+ <row>
+ <entry>copyAllControlDisabled</entry>
+ <entry>Redefines the disabled label content for the "copyAll" control</entry>
+ </row>
+ <row>
+ <entry>removeAllControlDisabled</entry>
+ <entry>Redefines the disabled label content for the "removeAll" control</entry>
+ </row>
+ <row>
+ <entry>caption</entry>
+ <entry>Redefines the caption control. Related attribute is "targetCaptionLabel"</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
<title>Look-and-Feel Customization</title>
<para>For skinnability implementation, the components use a <emphasis>
<property>style class redefinition method.</property>
Modified: trunk/docs/userguide/en/src/main/docbook/included/menuGroup.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/menuGroup.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/menuGroup.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -159,6 +159,31 @@
<property><rich:menuGroup></property>
</emphasis> component was designed to be used only for pop-up menu list creation.</para></note>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>icon</entry>
+ <entry>Redefines the icon for the enabled item state. Related attribute is "icon"</entry>
+ </row>
+ <row>
+ <entry>iconFolder</entry>
+ <entry>Redefines the folder icon for the enabled item state. Related attribute is "iconFolder"</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
Modified: trunk/docs/userguide/en/src/main/docbook/included/menuItem.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/menuItem.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/menuItem.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -178,6 +178,31 @@
</emphasis> attribute usage you can find <link linkend="process"
>here</link>. </para>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>icon</entry>
+ <entry>Redefines the icon for the enabled item state. Related attribute is "icon"</entry>
+ </row>
+ <row>
+ <entry>iconDisabled</entry>
+ <entry>Redefines the folder icon the disabled item state. Related attribute is "iconDisabled"</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
Modified: trunk/docs/userguide/en/src/main/docbook/included/message.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/message.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/message.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -118,6 +118,43 @@
]]></programlisting>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>errorMarker</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "ERROR"</entry>
+ </row>
+ <row>
+ <entry>fatalError</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "FATAL"</entry>
+ </row>
+ <row>
+ <entry>infoError</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "INFO"</entry>
+ </row>
+ <row>
+ <entry>warnError</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "WARN"</entry>
+ </row>
+ <row>
+ <entry>passedError</entry>
+ <entry>Redefines the content for the marker if there is no message</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
Modified: trunk/docs/userguide/en/src/main/docbook/included/messages.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/messages.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/messages.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -164,6 +164,43 @@
]]></programlisting>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>errorMarker</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "ERROR"</entry>
+ </row>
+ <row>
+ <entry>fatalError</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "FATAL"</entry>
+ </row>
+ <row>
+ <entry>infoError</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "INFO"</entry>
+ </row>
+ <row>
+ <entry>warnError</entry>
+ <entry>Redefines the content for the marker if there is message with a severity class of "WARN"</entry>
+ </row>
+ <row>
+ <entry>passedError</entry>
+ <entry>Redefines the content for the marker if there is no message</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
Modified: trunk/docs/userguide/en/src/main/docbook/included/modalPanel.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/modalPanel.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/modalPanel.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -394,6 +394,31 @@
</table>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>header</entry>
+ <entry>Define the header content</entry>
+ </row>
+ <row>
+ <entry>controls</entry>
+ <entry>Defines the control elements on the header</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
Modified: trunk/docs/userguide/en/src/main/docbook/included/orderingList.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/orderingList.xml 2008-11-18 08:48:26 UTC (rev 11200)
+++ trunk/docs/userguide/en/src/main/docbook/included/orderingList.xml 2008-11-18 10:23:45 UTC (rev 11201)
@@ -447,6 +447,59 @@
</tgroup>
</table>
</section>
+
+ <section>
+ <title>Facets</title>
+ <table>
+ <title>Facets</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Facet</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>caption</entry>
+ <entry>Redefines the caption content. Related attribute is "captionLabel"</entry>
+ </row>
+ <row>
+ <entry>topControl</entry>
+ <entry>Redefines the label for the "Top" control. Related attribute is "topControlLabel"</entry>
+ </row>
+ <row>
+ <entry>bottomControl</entry>
+ <entry>Redefines the label for the "Bottom" control. Related attribute is "bottomControlLabel"</entry>
+ </row>
+ <row>
+ <entry>upControl</entry>
+ <entry>Redefines the label for the "Up" control. Related attribute is "upControlLabel"</entry>
+ </row>
+ <row>
+ <entry>downControl</entry>
+ <entry>Redefines the label for the "Down" control. Related attribute is "downControlLabel"</entry>
+ </row>
+ <row>
+ <entry>topControlDisabled</entry>
+ <entry>Redefines the disabled label for the "Top" control</entry>
+ </row>
+ <row>
+ <entry>bottomControlDisabled</entry>
+ <entry>Redefines the disabled label for the "Bottom" control</entry>
+ </row>
+ <row>
+ <entry>upControlDisabled</entry>
+ <entry>Redefines the disabled label for the "Up" control</entry>
+ </row>
+ <row>
+ <entry>downControlDisabled</entry>
+ <entry>Redefines the disabled label for the "Down" control</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
<section>
<title>Look-and-Feel Customization</title>
17 years, 6 months