Compare commits

..

71 Commits

Author SHA1 Message Date
John Bintz a36b6d3e76 add unit test for getStyle where passed object does not have style attribute 2010-01-15 14:00:07 -05:00
John Bintz 2ede0b24e2 coding style change 2010-01-12 14:51:36 -05:00
John Bintz 1c21c2f1b6 remaining IE6 fixes for offset positioning where null objects are being returned 2010-01-12 14:46:52 -05:00
John Bintz 8a5b3209f4 add check to getStyle to ensure provided element has a style attribute 2010-01-06 19:43:10 -05:00
John Bintz 5992866e46 Revert "potential workaround for IE 5 issue where element can become something other than a DOM node"
This reverts commit ef78a973ef.
2010-01-06 19:41:33 -05:00
John Bintz ef78a973ef potential workaround for IE 6 issue where element can become something other than a DOM node 2010-01-06 16:52:58 -05:00
Tobie Langel 6839886699 doc: Update PDoc. Default to BlueCloth Markdown parser to avoid Maruku warning. 2009-12-31 19:34:35 +01:00
Juriy Zaytsev 475f1797e1 No need to check for `window.Node`, since `var Node` already declares it if missing. 2009-12-30 01:45:59 -05:00
Juriy Zaytsev e0a102b510 Merge branch 'master' of github.com:sstephenson/prototype 2009-12-30 01:41:27 -05:00
Juriy Zaytsev a260913a30 Remove SETATTRIBUTE_IGNORES_NAME feature test, replacing it with a simpler HAS_EXTENDED_CREATE_ELEMENT_SYNTAX one. This avoids invalid injection of FORM into a root element (HTML). 2009-12-30 01:33:37 -05:00
Tobie Langel 6c1790ac4e doc: Fix Template doc to avoid issues with Sprockets. 2009-12-29 01:54:56 +01:00
Tobie Langel 4cc67f2e8e doc: Minor cleanup. 2009-12-29 01:53:16 +01:00
Tobie Langel 8a8af0a729 doc: Fix documentation for Template. 2009-12-24 07:32:32 +01:00
Tobie Langel 2e3e02d92c doc: Fix documentation errors in Ajax.Response. 2009-12-24 03:19:14 +01:00
Tobie Langel bccb541797 Merge branch 'master' of git@github.com:sstephenson/prototype 2009-12-24 03:18:11 +01:00
Juriy Zaytsev 56fb5b84a1 No need to use expensive try/catch when check for element being orphaned suffices. 2009-12-23 01:54:19 -05:00
Tobie Langel d085d97a56 Revert back to PDoc's default templates. 2009-12-23 06:51:56 +01:00
Tobie Langel fb93b80b59 doc: using pygments for syntax highlighting. 2009-12-23 06:32:59 +01:00
Tobie Langel a7f05ee8b5 doc: Fix a typo in Prototype.Selector.find which prevented proper documentation parsing. Add a default value for the index argument. 2009-12-23 05:52:51 +01:00
Juriy Zaytsev 647d93bcc4 Use native `Array.isArray` when available; currently present in nightly webkit (up to 17x faster) and Opera 10.5 alpha (up to 5x faster). 2009-12-22 18:05:30 -05:00
Andrew Dupont d6ed7efe94 Tweak the PDoc templates. 2009-12-17 14:52:27 -06:00
Andrew Dupont 83b0c153d3 Add examples for String#gsub and String#sub.
(cherry picked from commit 591b25eb2604953754f08c40e9ef99791a6bb51b)
2009-12-04 18:29:40 -06:00
Andrew Dupont c028935279 Add note about mouseenter/leave support to docs.
(cherry picked from commit 1c4c2005341ef587dca7eacc8d347367e3eb7ef7)
2009-12-04 18:28:31 -06:00
Andrew Dupont 0dd600974c Add documentation for event key codes.
(cherry picked from commit 93bd2048e2c106ecc309292be358ef398df05984)
2009-12-04 18:27:49 -06:00
Andrew Dupont e7c9072872 Merge branch 'master' of git@github.com:sstephenson/prototype 2009-12-04 18:25:23 -06:00
Sam Stephenson fa0dce2488 Revert Event#findElement changes from 6bb309a 2009-12-03 00:31:35 -06:00
Sam Stephenson 6bb309afb7 Selector API change: replace Prototype.Selector.filter with Prototype.Selector.find, which works like the old Selector.findElement. 2009-12-02 15:57:58 -06:00
Sam Stephenson 7770ab99dc Fix 'rake' without SELECTOR_ENGINE environment variable set 2009-12-02 15:14:18 -06:00
Tobie Langel a44a8db6ae Avoid automatically fetching the vendor/sizzle git submodule. 2009-12-02 21:41:52 +01:00
Sam Stephenson 797c231bfa Move ext/sizzle into src so it's available in the default Sprockets load path. 2009-12-02 14:18:01 -06:00
Tobie Langel 9d4711281d Fix typo in Rakefile. 2009-12-02 00:47:16 +01:00
Samuel Lebeau 74c5d45511 Fix custom selector engine load path resolution. 2009-11-30 12:45:13 +01:00
Tobie Langel 6b00f24963 Merge branch 'selector_agnostic'
Conflicts:
	src/dom/selector.js
2009-11-30 11:32:09 +01:00
Juriy Zaytsev b3fc07922c Avoid object creation and an unnecessary function call in `Class#addMethods`, when working around JScript DontEnum bug. 2009-11-13 15:49:22 -05:00
Juriy Zaytsev 18f2ac65c3 Optimize Element#immediateDescendants. 2009-11-13 14:28:27 -05:00
Juriy Zaytsev 82c9b9c783 Remove unnecessary function object creation and `Number#times` in `Element._getContentFromAnonymousElement`. 2009-11-13 14:21:14 -05:00
Juriy Zaytsev 9ef3f8d2ed Eliminate runtime forking and long method lookup in `Element.hasAttribute`. 2009-11-13 12:27:10 -05:00
Juriy Zaytsev 829800834d Do not create translations object every time method is called. 2009-11-12 21:21:42 -05:00
Juriy Zaytsev c272e40042 Minor optimization in class module. 2009-11-12 21:17:37 -05:00
Juriy Zaytsev f40fd5a7d6 Remove redundant ternary. 2009-11-12 21:15:52 -05:00
Juriy Zaytsev 1f167f8754 `if` should be followed by space. 2009-11-11 17:43:25 -05:00
Juriy Zaytsev 01a229011a Avoid repeating declaration statements. 2009-11-11 17:32:19 -05:00
Andrew Dupont 5d027eb939 Merge branch 'master' of git@github.com:sstephenson/prototype 2009-10-30 02:59:14 -05:00
Tobie Langel af89847a4f Make Event.stopObserving return element in all cases. [#810 state:resolved] 2009-10-23 07:51:50 +02:00
Tobie Langel bf8e404805 Make Event.stopObserving return element in all cases. [#810 state:resolved] 2009-10-23 07:49:57 +02:00
Yaffle 2d3e423230 Add missing semicolons. [#837 state:resolved] 2009-10-21 18:25:27 +02:00
Tobie Langel f9c680a9ba More nitpicking. 2009-10-21 17:58:09 +02:00
Tobie Langel 8783065b8e Cosmetic rewrite of String#startsWith and String#endsWith with performance-related comments. 2009-10-21 17:24:09 +02:00
Tobie Langel 35ed99ba2e doc: nitpicking. 2009-10-21 17:00:17 +02:00
Tobie Langel 067a0ec364 Update to latest PDoc release. 2009-10-21 16:35:43 +02:00
tjcrowder 859197ca8b doc: Merged/updated old docs for Element.descendants. 2009-10-09 17:20:39 +01:00
tjcrowder d10aad7bfa doc: Merged/updated old docs for Element.descendantOf. 2009-10-09 17:15:15 +01:00
tjcrowder adf80ad1b3 doc: Merged/updated old docs for Element.cumulativeScrollOffset, clarified units, added example. 2009-10-09 17:10:13 +01:00
tjcrowder f1f6fca60b doc: Clarified units in Element.cumulativeOffset and added example. 2009-10-09 17:01:40 +01:00
tjcrowder c448b38f7b doc: Merged/updated old docs for Element.clonePosition. 2009-10-09 16:55:42 +01:00
tjcrowder 9ce1ea06b5 doc: Merged/updated old docs for Element.cleanWhitespace. 2009-10-09 16:10:44 +01:00
tjcrowder 1e29e3c6c9 doc: Merged/updated old docs for Element.classNames, mostly by marking it deprecated. 2009-10-09 15:49:54 +01:00
tjcrowder 892eb9d6b3 doc: Merged/updated old docs for Element.childElements / Element.immediateDescendants. Made immediateDescendants an alias of childElements rather than vice-versa as the latter is depreceated. 2009-10-09 15:34:39 +01:00
tjcrowder e3c89c08c6 doc: Merged/updated old docs for Element.ancestors. 2009-10-09 14:48:47 +01:00
tjcrowder 402a2d408e doc: Merged/updated old docs for Element.adjacent 2009-10-09 14:31:02 +01:00
tjcrowder 77832408bd doc: Merged/updated old docs for Element.addClassName 2009-10-09 14:14:14 +01:00
tjcrowder 7df62ce864 doc: Merged/updated old docs for Element.extend 2009-10-09 13:56:39 +01:00
tjcrowder d6d3ab1fef doc: Merged/updated old docs for Element constructor 2009-10-09 13:36:14 +01:00
tjcrowder 7d073ad56a doc: Merged/updated old docs for Element overview 2009-10-09 13:35:38 +01:00
tjcrowder d2874c0294 doc: Merged old docs for Element.addMethods. 2009-10-08 14:46:14 +01:00
Juriy Zaytsev 3b525f194d String#startsWith, String#endsWith performance optimization [#808 state:resolved] 2009-09-28 19:21:37 -04:00
Samuel Lebeau f4ea4c6ef7 Rewrite `String#camelize` using `String#replace` with a replacement function [#297 state:resolved] 2009-09-26 13:36:42 -04:00
Andrew Dupont 4dedcd3b62 Merge branch 'master' of git@github.com:sstephenson/prototype 2009-09-15 18:27:56 -05:00
Andrew Dupont 58a2f9db28 Update to latest PDoc. 2009-09-15 18:27:46 -05:00
Andrew Dupont 19615e7a00 Cleanup on PDoc templates. 2009-09-15 18:27:35 -05:00
Andrew Dupont 5ccf8cbefd Change all H4s in _method_ documentation blocks to H5s. (Start with H5 when using headings in a method doc block; start with H4 when using headings in a namespace/class doc block.) 2009-09-09 23:18:45 -05:00
67 changed files with 714 additions and 9881 deletions

View File

@ -1,3 +1,21 @@
* Avoid object creation and an unnecessary function call in `Class#addMethods`, when working around JScript DontEnum bug. Replace with feature test and a simple boolean check at runtime. (kangax)
* Optimize Element#immediateDescendants. (kangax, Tobie Langel)
* Remove unnecessary function object creation and `Number#times` in `Element._getContentFromAnonymousElement`. (kangax)
* Eliminate runtime forking and long method lookup in `Element.hasAttribute`. (kangax)
* Remove redundant ternary. (kangax)
* Avoid repeating declaration statements where it makes sense, for slightly better runtime performance and minification. (kangax)
* Make `Event.stopObserving` return element in all cases. [#810 state:resolved] (Yaffle, Tobie Langel)
* String#startsWith, String#endsWith performance optimization (Yaffle, Tobie Langel, kangax)
* Rewrite String#camelize using String#replace with a replacement function (Phred, John-David Dalton, Samuel Lebeau, kangax)
*1.6.1* (August 24, 2009)
* Avoid triggering a warning when Java is disabled in IE8. [#668 state:resolved] (orv, kangax, Andrew Dupont, Tobie Langel)

View File

@ -13,6 +13,7 @@ module PrototypeHelper
TEST_UNIT_DIR = File.join(TEST_DIR, 'unit')
TMP_DIR = File.join(TEST_UNIT_DIR, 'tmp')
VERSION = YAML.load(IO.read(File.join(SRC_DIR, 'constants.yml')))['PROTOTYPE_VERSION']
DEFAULT_SELECTOR_ENGINE = 'sizzle'
%w[sprockets pdoc unittest_js caja_builder].each do |name|
$:.unshift File.join(PrototypeHelper::ROOT_DIR, 'vendor', name, 'lib')
@ -43,11 +44,10 @@ module PrototypeHelper
}.merge(options)
require_sprockets
load_path = [SRC_DIR, File.join(ROOT_DIR, 'ext', 'sizzle')]
load_path = [SRC_DIR]
if selector = options[:selector_engine]
get_selector_engine(selector)
load_path << File.join(ROOT_DIR, 'vendor', selector)
if selector_path = get_selector_engine(options[:selector_engine])
load_path << selector_path
end
secretary = Sprockets::Secretary.new(
@ -67,16 +67,18 @@ module PrototypeHelper
:path => 'src',
:source => file,
:destination => temp_path,
:selector_engine => ENV['SELECTOR_ENGINE'] || 'sizzle',
:selector_engine => ENV['SELECTOR_ENGINE'] || DEFAULT_SELECTOR_ENGINE,
:strip_comments => false
)
rm_rf DOC_DIR
PDoc::Runner.new(temp_path, {
:output => DOC_DIR,
:templates => File.join(TEMPLATES_DIR, "html"),
:index_page => 'README.markdown'
}).run
PDoc.run({
:source_files => [temp_path],
:destination => DOC_DIR,
:index_page => 'README.markdown',
:syntax_highlighter => :pygments,
:markdown_parser => :bluecloth
})
rm_rf temp_path
end
@ -98,14 +100,14 @@ module PrototypeHelper
end
def self.get_selector_engine(name)
submodule = File.join(ROOT_DIR, 'vendor', name, 'repository')
ext = File.join(ROOT_DIR, 'ext', name)
unless File.exist?(submodule) || File.exist?(ext)
get_submodule('the required selector engine', "#{name}/repository")
unless File.exist?(submodule)
puts "The selector engine you required isn't available at vendor/#{name}.\n\n"
exit
end
return if name == DEFAULT_SELECTOR_ENGINE || !name
submodule_path = File.join(ROOT_DIR, "vendor", name)
return submodule_path if File.exist?(File.join(submodule_path, "repository", ".git"))
get_submodule('the required selector engine', "#{name}/repository")
unless File.exist?(submodule_path)
puts "The selector engine you required isn't available at vendor/#{name}.\n\n"
exit
end
end
@ -151,7 +153,7 @@ task :dist do
PrototypeHelper.sprocketize(
:path => 'src',
:source => 'prototype.js',
:selector_engine => ENV['SELECTOR_ENGINE'] || 'sizzle'
:selector_engine => ENV['SELECTOR_ENGINE'] || PrototypeHelper::DEFAULT_SELECTOR_ENGINE
)
end

View File

@ -64,14 +64,14 @@ Ajax.Response = Class.create({
var transport = this.transport = request.transport,
readyState = this.readyState = transport.readyState;
if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
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) {
if (readyState == 4) {
var xml = transport.responseXML;
this.responseXML = Object.isUndefined(xml) ? null : xml;
this.responseJSON = this._getResponseJSON();
@ -121,7 +121,7 @@ Ajax.Response = Class.create({
},
/**
* Ajax.Response.getResponseHeader(name) -> String
* Ajax.Response#getResponseHeader(name) -> String
*
* Returns the value of the requested header if present; throws an error
* otherwise. This is just a wrapper around the `XmlHttpRequest` method of
@ -132,7 +132,7 @@ Ajax.Response = Class.create({
},
/**
* Ajax.Response.getAllResponseHeaders() -> String
* Ajax.Response#getAllResponseHeaders() -> String
*
* Returns a string containing all headers separated by line breaks; throws
* an error if no headers exist. This is just a wrapper around the

View File

@ -1,6 +1,6 @@
/** section: DOM, related to: Element
* $(id) -> Element
* $(id...) -> [Element]...
* $(id...) -> [Element...]
* - id (String | Element): A DOM node or a string that references a node's
* ID.
*
@ -38,7 +38,7 @@ if (Prototype.BrowserFeatures.XPath) {
/*--------------------------------------------------------------------------*/
if (!window.Node) var Node = { };
if (!Node) var Node = { };
if (!Node.ELEMENT_NODE) {
// DOM level 2 ECMAScript Language Binding
@ -60,41 +60,76 @@ if (!Node.ELEMENT_NODE) {
/** section: DOM
* class Element
*
* The `Element` object provides a variety of powerful DOM methods for
* interacting with DOM elements&nbsp;&mdash; creating them, updating them,
* traversing them, etc. You can access these either as methods of `Element`
* itself, passing in the element to work with as the first argument, or as
* methods on extended element *instances*:
*
* // Using Element:
* Element.addClassName('target', 'highlighted');
*
* // Using an extended element instance:
* $('target').addClassName('highlighted');
*
* `Element` is also a constructor for building element instances from scratch,
* see [`new Element`](#new-constructor) for details.
*
* Most `Element` methods return the element instance, so that you can chain
* them easily:
*
* $('message').addClassName('read').update('I read this message!');
*
* ##### More Information
*
* For more information about extended elements, check out ["How Prototype
* extends the DOM"](http://prototypejs.org/learn/extensions), which will walk
* you through the inner workings of Prototype's DOM extension mechanism.
**/
/**
* new Element(tagName[, attributes])
* - tagName (String): The name of the HTML element to create.
* - attributes (Object): A list of attribute/value pairs to set on the
* element.
* - tagName (String): The name of the HTML element to create.
* - attributes (Object): An optional group of attribute/value pairs to set on
* the element.
*
* Creates an HTML element with `tagName` as the tag name.
* Creates an HTML element with `tagName` as the tag name, optionally with the
* given attributes. This can be markedly more concise than working directly
* with the DOM methods, and takes advantage of Prototype's workarounds for
* various browser issues with certain attributes:
*
* ##### Example
*
* // The old way:
* var a = document.createElement('a');
* a.setAttribute('class', 'foo');
* a.setAttribute('href', '/foo.html');
* a.appendChild(document.createTextNode("Next page"));
*
* // The new way:
* var a = new Element('a', {'class': 'foo', href: '/foo.html'}).update("Next page");
**/
(function(global) {
// setAttribute is broken in IE (particularly when setting name attribute)
// see: http://msdn.microsoft.com/en-us/library/ms536389.aspx
var SETATTRIBUTE_IGNORES_NAME = (function(){
var elForm = document.createElement("form");
var elInput = document.createElement("input");
var root = document.documentElement;
elInput.setAttribute("name", "test");
elForm.appendChild(elInput);
root.appendChild(elForm);
var isBuggy = elForm.elements
? (typeof elForm.elements.test == "undefined")
: null;
root.removeChild(elForm);
elForm = elInput = null;
return isBuggy;
(function(global) {
var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
try {
var el = document.createElement('<input name="x">');
return el.tagName.toLowerCase() === 'input' && el.name === 'x';
}
catch(err) {
return false;
}
})();
var element = global.Element;
global.Element = function(tagName, attributes) {
attributes = attributes || { };
tagName = tagName.toLowerCase();
var cache = Element.cache;
if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
tagName = '<' + tagName + ' name="' + attributes.name + '">';
delete attributes.name;
return Element.writeAttribute(document.createElement(tagName), attributes);
@ -102,12 +137,14 @@ if (!Node.ELEMENT_NODE) {
if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
};
Object.extend(global.Element, element || { });
if (element) global.Element.prototype = element.prototype;
})(this);
Element.cache = { };
Element.idCounter = 1;
Element.cache = { };
Element.Methods = {
/**
@ -403,8 +440,9 @@ Element.Methods = {
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();
var property = pair.first(),
attribute = pair.last(),
value = (element[property] || '').toString();
if (value) result += ' ' + attribute + '=' + value.inspect(true);
});
return result + '>';
@ -436,8 +474,34 @@ Element.Methods = {
/**
* Element.ancestors(@element) -> [Element...]
*
* Collects all of `element`'s ancestors and returns them as an array of
* elements.
* Collects all of `element`'s ancestor elements and returns them as an
* array of extended elements.
*
* The returned array's first element is `element`'s direct ancestor (its
* `parentNode`), the second one is its grandparent, and so on until the
* `html` element is reached. `html` will always be the last member of the
* array. Calling `ancestors` on the `html` element will return an empty
* array.
*
* ##### Example
*
* Assuming:
*
* language: html
* <html>
* [...]
* <body>
* <div id="father">
* <div id="kid">
* </div>
* </div>
* </body>
* </html>
*
* Then:
*
* $('kid').ancestors();
* // -> [div#father, body, html]
**/
ancestors: function(element) {
return Element.recursivelyCollect(element, 'parentNode');
@ -446,8 +510,10 @@ Element.Methods = {
/**
* Element.descendants(@element) -> [Element...]
*
* Collects all of element's descendants and returns them as an array of
* elements.
* Collects all of the element's descendants (its children, their children,
* etc.) and returns them as an array of extended elements. As with all of
* Prototype's DOM traversal methods, only Elements are returned, other
* nodes (text nodes, etc.) are skipped.
**/
descendants: function(element) {
return Element.select(element, "*");
@ -467,17 +533,20 @@ Element.Methods = {
return $(element);
},
/**
/** deprecated, alias of: Element.childElements
* Element.immediateDescendants(@element) -> [Element...]
*
* Collects all of `element`'s immediate descendants (i.e., children) and
* returns them as an array of elements.
* **This method is deprecated, please see [[Element.childElements]]**.
**/
immediateDescendants: function(element) {
if (!(element = $(element).firstChild)) return [];
while (element && element.nodeType != 1) element = element.nextSibling;
if (element) return [element].concat($(element).nextSiblings());
return [];
var results = [], child = $(element).firstChild;
while (child) {
if (child.nodeType === 1) {
results.push(Element.extend(child));
}
child = child.nextSibling;
}
return results;
},
/**
@ -539,7 +608,7 @@ Element.Methods = {
if (arguments.length == 1) return $(element.parentNode);
var ancestors = Element.ancestors(element);
return Object.isNumber(expression) ? ancestors[expression] :
Prototype.Selector.filter(ancestors, expression)[index || 0];
Prototype.Selector.find(ancestors, expression, index);
},
/**
@ -575,7 +644,7 @@ Element.Methods = {
if (!Object.isNumber(index)) index = 0;
if (expression) {
return Prototype.Selector.filter(element.previousSiblings(), expression)[index];
return Prototype.Selector.find(element.previousSiblings(), expression, index);
} else {
return element.recursivelyCollect("previousSibling", index + 1)[index];
}
@ -597,7 +666,7 @@ Element.Methods = {
if (!Object.isNumber(index)) index = 0;
if (expression) {
return Prototype.Selector.filter(element.nextSiblings(), expression)[index];
return Prototype.Selector.find(element.nextSiblings(), expression, index);
} else {
var maximumLength = Object.isNumber(index) ? index + 1 : 1;
return element.recursivelyCollect("nextSibling", index + 1)[index];
@ -623,7 +692,30 @@ Element.Methods = {
* - selector (String): A CSS selector.
*
* Finds all siblings of the current element that match the given
* selector(s).
* selector(s). If you provide multiple selectors, siblings matching *any*
* of the selectors are included. If a sibling matches multiple selectors,
* it is only included once. The order of the returned array is not defined.
*
* ##### Example
*
* Assuming this list:
*
* language: html
* <ul id="cities">
* <li class="us" id="nyc">New York</li>
* <li class="uk" id="lon">London</li>
* <li class="us" id="chi">Chicago</li>
* <li class="jp" id="tok">Tokyo</li>
* <li class="us" id="la">Los Angeles</li>
* <li class="us" id="aus">Austin</li>
* </ul>
*
* Then:
*
* $('nyc').adjacent('li.us');
* // -> [li#chi, li#la, li#aus]
* $('nyc').adjacent('li.uk', 'li.jp');
* // -> [li#lon, li#tok]
**/
adjacent: function(element) {
element = $(element);
@ -710,11 +802,15 @@ Element.Methods = {
return Element.getDimensions(element).width;
},
/**
/** deprecated
* Element.classNames(@element) -> [String...]
*
* Returns a new instance of [[Element.ClassNames]], an [[Enumerable]]
* object used to read and write CSS class names of `element`.
*
* **Deprecated**, please see [[Element.addClassName]],
* [[Element.removeClassName]], and [[Element.hasClassName]]. If you want
* an array of classnames, you can use `$w(element.className)`.
**/
classNames: function(element) {
return new Element.ClassNames(element);
@ -734,8 +830,24 @@ Element.Methods = {
/**
* Element.addClassName(@element, className) -> Element
* - className (String): The class name to add.
*
* Adds a CSS class to `element`.
* Adds the given CSS class to `element`.
*
* ##### Example
*
* Assuming this HTML:
*
* language: html
* <div id="mutsu" class="apple fruit"></div>
*
* Then:
*
* $('mutsu').className;
* // -> 'apple fruit'
* $('mutsu').addClassName('food');
* $('mutsu').className;
* // -> 'apple fruit food'
**/
addClassName: function(element, className) {
if (!(element = $(element))) return;
@ -770,7 +882,44 @@ Element.Methods = {
/**
* Element.cleanWhitespace(@element) -> Element
*
* Removes whitespace-only text node children from `element`.
* Removes all of `element`'s child text nodes that contain *only*
* whitespace. Returns `element`.
*
* This can be very useful when using standard properties like `nextSibling`,
* `previousSibling`, `firstChild` or `lastChild` to walk the DOM. Usually
* you'd only do that if you are interested in all of the DOM nodes, not
* just Elements (since if you just need to traverse the Elements in the
* DOM tree, you can use [[Element.up]], [[Element.down]],
* [[Element.next]], and [[Element.previous]] instead).
*
* #### Example
*
* Consider the following HTML snippet:
*
* language: html
* <ul id="apples">
* <li>Mutsu</li>
* <li>McIntosh</li>
* <li>Ida Red</li>
* </ul>
*
* Let's grab what we think is the first list item using the raw DOM
* method:
*
* var element = $('apples');
* element.firstChild.innerHTML;
* // -> undefined
*
* It's undefined because the `firstChild` of the `apples` element is a
* text node containing the whitespace after the end of the `ul` and before
* the first `li`.
*
* If we remove the useless whitespace, then `firstChild` works as expected:
*
* var element = $('apples');
* element.cleanWhitespace();
* element.firstChild.innerHTML;
* // -> 'Mutsu'
**/
cleanWhitespace: function(element) {
element = $(element);
@ -795,8 +944,28 @@ Element.Methods = {
/**
* Element.descendantOf(@element, ancestor) -> Boolean
* - ancestor (Element | String): The element to check against (or its ID).
*
* Checks if `element` is a descendant of `ancestor`.
*
* ##### Example
*
* Assuming:
*
* language: html
* <div id="australopithecus">
* <div id="homo-erectus">
* <div id="homo-sapiens"></div>
* </div>
* </div>
*
* Then:
*
* $('homo-sapiens').descendantOf('australopithecus');
* // -> true
*
* $('homo-erectus').descendantOf('homo-sapiens');
* // -> false
**/
descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
@ -835,6 +1004,9 @@ Element.Methods = {
**/
getStyle: function(element, style) {
element = $(element);
if (!element.style)
return null;
style = style == 'float' ? 'cssFloat' : style.camelize();
var value = element.style[style];
if (!value || value == 'auto') {
@ -906,16 +1078,16 @@ Element.Methods = {
// 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;
var els = element.style,
originalVisibility = els.visibility,
originalPosition = els.position,
originalDisplay = els.display;
els.visibility = 'hidden';
if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
els.position = 'absolute';
els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
var originalWidth = element.clientWidth,
originalHeight = element.clientHeight;
els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
@ -997,18 +1169,34 @@ Element.Methods = {
* Element.cumulativeOffset(@element) -> Array
*
* Returns the offsets of `element` from the top left corner of the
* document.
* document, in pixels.
*
* Returns an array in the form of `[leftValue, topValue]`. Also accessible
* as properties: `{ left: leftValue, top: topValue }`.
*
* ##### Example
*
* Assuming the div `foo` is at (25,40), then:
*
* var offset = $('foo').cumulativeOffset();
* offset[0];
* // -> 25
* offset[1];
* // -> 40
* offset.left;
* // -> 25
* offset.top;
* // -> 40
**/
cumulativeOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
if (element.parentNode) {
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
}
return Element._returnOffset(valueL, valueT);
},
@ -1046,11 +1234,11 @@ Element.Methods = {
element = $(element);
if (Element.getStyle(element, 'position') == 'absolute') return element;
var offsets = Element.positionedOffset(element);
var top = offsets[1];
var left = offsets[0];
var width = element.clientWidth;
var height = element.clientHeight;
var offsets = Element.positionedOffset(element),
top = offsets[1],
left = offsets[0],
width = element.clientWidth,
height = element.clientHeight;
element._originalLeft = left - parseFloat(element.style.left || 0);
element._originalTop = top - parseFloat(element.style.top || 0);
@ -1078,8 +1266,8 @@ Element.Methods = {
if (Element.getStyle(element, 'position') == 'relative') return element;
element.style.position = 'relative';
var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
var top = parseFloat(element.style.top || 0) - (element._originalTop || 0),
left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
element.style.top = top + 'px';
element.style.left = left + 'px';
@ -1091,11 +1279,25 @@ Element.Methods = {
/**
* Element.cumulativeScrollOffset(@element) -> Array
*
* Calculates the cumulative scroll offset of an element in nested
* scrolling containers.
* Calculates the cumulative scroll offset (in pixels) of an element in
* nested scrolling containers.
*
* Returns an array in the form of `[leftValue, topValue]`. Also accessible
* as properties: `{ left: leftValue, top: topValue }`.
*
* ##### Example
*
* Assuming the div `foo` is at scroll offset (0,257), then:
*
* var offset = $('foo').cumulativeOffset();
* offset[0];
* // -> 0
* offset[1];
* // -> 257
* offset.left;
* // -> 0
* offset.top;
* // -> 257
**/
cumulativeScrollOffset: function(element) {
var valueT = 0, valueL = 0;
@ -1133,9 +1335,10 @@ Element.Methods = {
* as properties: `{ left: leftValue, top: topValue }`.
**/
viewportOffset: function(forElement) {
var valueT = 0, valueL = 0;
var element = forElement;
var valueT = 0,
valueL = 0,
element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
@ -1159,15 +1362,60 @@ Element.Methods = {
/**
* Element.clonePosition(@element, source[, options]) -> Element
* - source (Element | String): The source element (or its ID).
* - options (Object): The position fields to clone.
*
* Clones the position and/or dimensions of `source` onto `element` as
* defined by `options`.
* Clones the position and/or dimensions of `source` onto the element as
* defined by `options`, with an optional offset for the `left` and `top`
* properties.
*
* Valid keys for `options` are: `setLeft`, `setTop`, `setWidth`, and
* `setHeight` (all booleans which default to `true`); and `offsetTop`
* and `offsetLeft` (numbers which default to `0`). Use these to control
* which aspects of `source`'s layout are cloned and how much to offset
* the resulting position of `element`.
* Note that the element will be positioned exactly like `source` whether or
* not it is part of the same [CSS containing
* block](http://www.w3.org/TR/CSS21/visudet.html#containing-block-details).
*
* ##### Options
*
* <table class='options'>
* <thead>
* <tr>
* <th style='text-align: left; padding-right: 1em'>Name</th>
* <th style='text-align: left; padding-right: 1em'>Default</th>
* <th style='text-align: left; padding-right: 1em'>Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td><code>setLeft</code></td>
* <td><code>true</code></td>
* <td>Clones <code>source</code>'s <code>left</code> CSS property onto <code>element</code>.</td>
* </tr>
* <tr>
* <td><code>setTop</code></td>
* <td><code>true</code></td>
* <td>Clones <code>source</code>'s <code>top</code> CSS property onto <code>element</code>.</td>
* </tr>
* <tr>
* <td><code>setWidth</code></td>
* <td><code>true</code></td>
* <td>Clones <code>source</code>'s <code>width</code> onto <code>element</code>.</td>
* </tr>
* <tr>
* <td><code>setHeight</code></td>
* <td><code>true</code></td>
* <td>Clones <code>source</code>'s <code>width</code> onto <code>element</code>.</td>
* </tr>
* <tr>
* <td><code>offsetLeft</code></td>
* <td><code>0</code></td>
* <td>Number by which to offset <code>element</code>'s <code>left</code> CSS property.</td>
* </tr>
* <tr>
* <td><code>offsetTop</code></td>
* <td><code>0</code></td>
* <td>Number by which to offset <code>element</code>'s <code>top</code> CSS property.</td>
* </tr>
* </tbody>
* </table>
**/
clonePosition: function(element, source) {
var options = Object.extend({
@ -1181,12 +1429,11 @@ Element.Methods = {
// find page position of source
source = $(source);
var p = Element.viewportOffset(source);
var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
// 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') {
@ -1215,8 +1462,40 @@ Object.extend(Element.Methods, {
**/
getElementsBySelector: Element.Methods.select,
/** alias of: Element.immediateDescendants
/**
* Element.childElements(@element) -> [Element...]
*
* Collects all of the element's children and returns them as an array of
* [extended](http://prototypejs.org/api/element/extend) elements, in
* document order. The first entry in the array is the topmost child of
* `element`, the next is the child after that, etc.
*
* Like all of Prototype's DOM traversal methods, `childElements` ignores
* text nodes and returns element nodes only.
*
* ##### Example
*
* Assuming:
*
* language: html
* <div id="australopithecus">
* Some text in a text node
* <div id="homo-erectus">
* <div id="homo-neanderthalensis"></div>
* <div id="homo-sapiens"></div>
* </div>
* </div>
*
* Then:
*
* $('australopithecus').childElements();
* // -> [div#homo-erectus]
*
* $('homo-erectus').childElements();
* // -> [div#homo-neanderthalensis, div#homo-sapiens]
*
* $('homo-sapiens').childElements();
* // -> []
**/
childElements: Element.Methods.immediateDescendants
});
@ -1281,8 +1560,7 @@ else if (Prototype.Browser.IE) {
function(proceed, element) {
element = $(element);
// IE throws an error if element is not in document
try { element.offsetParent }
catch(e) { return $(document.body) }
if (!element.parentNode) return $(document.body);
var position = element.getStyle('position');
if (position !== 'static') return proceed(element);
element.setStyle({ position: 'relative' });
@ -1296,15 +1574,15 @@ else if (Prototype.Browser.IE) {
Element.Methods[method] = Element.Methods[method].wrap(
function(proceed, element) {
element = $(element);
try { element.offsetParent }
catch(e) { return Element._returnOffset(0,0) }
if (!element.parentNode) return Element._returnOffset(0, 0);
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 });
if (offsetParent.getStyle)
if (offsetParent && offsetParent.getStyle('position') === 'fixed')
offsetParent.setStyle({ zoom: 1 });
element.setStyle({ position: 'relative' });
var value = proceed(element);
element.setStyle({ position: position });
@ -1313,16 +1591,11 @@ else if (Prototype.Browser.IE) {
);
});
Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
function(proceed, element) {
try { element.offsetParent }
catch(e) { return Element._returnOffset(0,0) }
return proceed(element);
}
);
Element.Methods.getStyle = function(element, style) {
element = $(element);
if (!element.style)
return null;
style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
var value = element.style[style];
if (!value && element.currentStyle) value = element.currentStyle[style];
@ -1364,10 +1637,9 @@ else if (Prototype.Browser.IE) {
Element._attributeTranslations = (function(){
var classProp = 'className';
var forProp = 'for';
var el = document.createElement('div');
var classProp = 'className',
forProp = 'for',
el = document.createElement('div');
// try "className" first (IE <8)
el.setAttribute(classProp, 'x');
@ -1412,10 +1684,9 @@ else if (Prototype.Browser.IE) {
},
_getEv: (function(){
var el = document.createElement('div');
var el = document.createElement('div'), f;
el.onclick = Prototype.emptyFunction;
var value = el.getAttribute('onclick');
var f;
// IE<8
if (String(value).indexOf('{') > -1) {
@ -1549,7 +1820,7 @@ else if (Prototype.Browser.WebKit) {
(value < 0.00001) ? 0 : value;
if (value == 1)
if(element.tagName.toUpperCase() == 'IMG' && element.width) {
if (element.tagName.toUpperCase() == 'IMG' && element.width) {
element.width++; element.width--;
} else try {
var n = document.createTextNode(' ');
@ -1592,8 +1863,8 @@ if ('outerHTML' in document.documentElement) {
var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
if (Element._insertionTranslations.tags[tagName]) {
var nextSibling = element.next();
var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
var nextSibling = element.next(),
fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
parent.removeChild(element);
if (nextSibling)
fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
@ -1615,11 +1886,17 @@ Element._returnOffset = function(l, t) {
};
Element._getContentFromAnonymousElement = function(tagName, html) {
var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
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;
for (var i = t[2]; i--; ) {
div = div.firstChild;
}
}
else {
div.innerHTML = html;
}
return $A(div.childNodes);
};
@ -1676,16 +1953,31 @@ Object.extend(Element, Element.Methods);
div = null;
})(document.createElement('div'))
})(document.createElement('div'));
/**
* Element.extend(element) -> Element
*
* Extends `element` with all of the methods contained in `Element.Methods`
* and `Element.Methods.Simulated`.
* If `element` is an `input`, `textarea`, or `select` tag, it will also be
* extended with the methods from `Form.Element.Methods`. If it is a `form`
* tag, it will also be extended with the methods from `Form.Methods`.
* Extends the given element instance with all of the Prototype goodness and
* syntactic sugar, as well as any extensions added via [[Element.addMethods]].
* (If the element instance was already extended, this is a no-op.)
*
* You only need to use `Element.extend` on element instances you've acquired
* directly from the DOM; **all** Prototype methods that return element
* instances (such as [[$]], [[Element.down]], etc.) will pre-extend the
* element before returning it.
*
* Check out ["How Prototype extends the
* DOM"](http://prototypejs.org/learn/extensions) for more about element
* extensions.
*
* ##### Details
*
* Specifically, `Element.extend` extends the given instance with the methods
* contained in `Element.Methods` and `Element.Methods.Simulated`. If `element`
* is an `input`, `textarea`, or `select` element, it will also be extended
* with the methods from `Form.Element.Methods`. If it is a `form` element, it
* will also be extended with the methods from `Form.Methods`.
**/
Element.extend = (function() {
@ -1693,8 +1985,8 @@ Element.extend = (function() {
if (typeof window.Element != 'undefined') {
var proto = window.Element.prototype;
if (proto) {
var id = '_' + (Math.random()+'').slice(2);
var el = document.createElement(tagName);
var id = '_' + (Math.random()+'').slice(2),
el = document.createElement(tagName);
proto[id] = 'x';
var isBuggy = (el[id] !== 'x');
delete proto[id];
@ -1768,20 +2060,138 @@ Element.extend = (function() {
return extend;
})();
Element.hasAttribute = function(element, attribute) {
if (element.hasAttribute) return element.hasAttribute(attribute);
return Element.Methods.Simulated.hasAttribute(element, attribute);
};
if (document.documentElement.hasAttribute) {
Element.hasAttribute = function(element, attribute) {
return element.hasAttribute(attribute);
};
}
else {
Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
}
/**
* Element.addMethods(methods) -> undefined
* Element.addMethods(tagName, methods) -> undefined
* - tagName (String): (Optional) The name of the HTML tag for which the
* methods should be available; if not given, all HTML elements will have
* the new methods.
* - methods (Object): A hash of methods to add.
*
* Takes a hash of methods and makes them available as methods of extended
* elements and of the `Element` object.
* `Element.addMethods` makes it possible to mix your *own* methods into the
* `Element` object and extended element instances (all of them, or only ones
* with the given HTML tag if you specify `tagName`).
*
* The second usage form is for adding methods only to specific tag names.
* You define the methods in a hash that you provide to `Element.addMethods`.
* Here's an example adding two methods:
*
* Element.addMethods({
*
* // myOwnMethod: Do something cool with the element
* myOwnMethod: function(element) {
* if (!(element = $(element))) return;
* // ...do smething with 'element'...
* return element;
* },
*
* // wrap: Wrap the element in a new element using the given tag
* wrap: function(element, tagName) {
* var wrapper;
* if (!(element = $(element))) return;
* wrapper = new Element(tagName);
* element.parentNode.replaceChild(wrapper, element);
* wrapper.appendChild(element);
* return wrapper;
* }
*
* });
*
* Once added, those can be used either via `Element`:
*
* // Wrap the element with the ID 'foo' in a div
* Element.wrap('foo', 'div');
*
* ...or as instance methods of extended elements:
*
* // Wrap the element with the ID 'foo' in a div
* $('foo').wrap('div');
*
* Note the following requirements and conventions for methods added to
* `Element`:
*
* - The first argument is *always* an element or ID, by convention this
* argument is called `element`.
* - The method passes the `element` argument through [[$]] and typically
* returns if the result is undefined.
* - Barring a good reason to return something else, the method returns the
* extended element to enable chaining.
*
* Our `myOwnMethod` method above returns the element because it doesn't have
* a good reason to return anything else. Our `wrap` method returns the
* wrapper, because that makes more sense for that method.
*
* ##### Extending only specific elements
*
* If you call `Element.addMethods` with *two* arguments, it will apply the
* methods only to elements with the given HTML tag:
*
* Element.addMethods('DIV', my_div_methods);
* // the given methods are now available on DIV elements, but not others
*
* You can also pass an *array* of tag names as the first argument:
*
* Element.addMethods(['DIV', 'SPAN'], my_additional_methods);
* // DIV and SPAN now both have the given methods
*
* (Tag names in the first argument are not case sensitive.)
*
* Note: `Element.addMethods` has built-in security which prevents you from
* overriding native element methods or properties (like `getAttribute` or
* `innerHTML`), but nothing prevents you from overriding one of Prototype's
* methods. Prototype uses a lot of its methods internally; overriding its
* methods is best avoided or at least done only with great care.
*
* ##### Example 1
*
* Our `wrap` method earlier was a complete example. For instance, given this
* paragraph:
*
* language: html
* <p id="first">Some content...</p>
*
* ...we might wrap it in a `div`:
*
* $('first').wrap('div');
*
* ...or perhaps wrap it and apply some style to the `div` as well:
*
* $('first').wrap('div').setStyle({
* backgroundImage: 'url(images/rounded-corner-top-left.png) top left'
* });
*
* ##### Example 2
*
* We can add a method to elements that makes it a bit easier to update them
* via [[Ajax.Updater]]:
*
* Element.addMethods({
* ajaxUpdate: function(element, url, options) {
* if (!(element = $(element))) return;
* element.update('<img src="/images/spinner.gif" alt="Loading...">');
* options = options || {};
* options.onFailure = options.onFailure || defaultFailureHandler.curry(element);
* new Ajax.Updater(element, url, options);
* return element;
* }
* });
*
* Now we can update an element via an Ajax call much more concisely than
* before:
*
* $('foo').ajaxUpdate('/new/content');
*
* That will use Ajax.Updater to load new content into the 'foo' element,
* showing a spinner while the call is in progress. It even applies a default
* failure handler (since we didn't supply one).
**/
Element.addMethods = function(methods) {
var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
@ -1845,8 +2255,9 @@ Element.addMethods = function(methods) {
klass = 'HTML' + tagName.capitalize() + 'Element';
if (window[klass]) return window[klass];
var element = document.createElement(tagName);
var proto = element['__proto__'] || element.constructor.prototype;
var element = document.createElement(tagName),
proto = element['__proto__'] || element.constructor.prototype;
element = null;
return proto;
}
@ -1874,8 +2285,8 @@ Element.addMethods = function(methods) {
Element.cache = { };
};
/** section: DOM
* document.viewport
/**
* document.viewport
*
* The `document.viewport` namespace contains methods that return information
* about the viewport &mdash; the rectangle that represents the portion of a web

View File

@ -25,7 +25,10 @@
* browsers.
*
* `Event` also provides a standardized list of key codes you can use with
* keyboard-related events.
* keyboard-related events, including `KEY_BACKSPACE`, `KEY_TAB`,
* `KEY_RETURN`, `KEY_ESC`, `KEY_LEFT`, `KEY_UP`, `KEY_RIGHT`, `KEY_DOWN`,
* `KEY_DELETE`, `KEY_HOME`, `KEY_END`, `KEY_PAGEUP`, `KEY_PAGEDOWN` and
* `KEY_INSERT`.
*
* The functions you're most likely to use a lot are [[Event.observe]],
* [[Event.element]] and [[Event.stop]]. If your web app uses custom events,
@ -153,10 +156,10 @@
if (Prototype.Selector.match(element, expression)) {
return Element.extend(element);
}
element = element.parentNode
element = element.parentNode;
}
}
/**
* Event.pointer(@event) -> Object
*
@ -383,12 +386,12 @@
window.addEventListener('unload', Prototype.emptyFunction, false);
var _getDOMEventName = Prototype.K;
var _getDOMEventName = Prototype.K,
translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
_getDOMEventName = function(eventName) {
var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
return eventName in translations ? translations[eventName] : eventName;
return (translations[eventName] || eventName);
};
}
@ -412,6 +415,7 @@
* * Prototype handles cleaning up the handler when leaving the page (important for MSIE memory
* leak prevention).
* * `observe` makes it possible to stop observing the event easily via [[Event.stopObserving]].
* * Adds support for `mouseenter` / `mouseleave` in all browsers.
*
* Although you can use `Event.observe` directly and there are times when that's the most
* convenient or direct way, it's more common to use its alias [[Element#observe]]. These two
@ -617,48 +621,39 @@
* ...and then to remove:
*
* $('foo').stopObserving('click', this.boundHandlerMethod); // <== Right
*
**/
function stopObserving(element, eventName, handler) {
element = $(element);
var registry = Element.retrieve(element, 'prototype_event_registry');
if (!registry) return element;
if (Object.isUndefined(registry)) return element;
if (eventName && !handler) {
// If an event name is passed without a handler, we stop observing all
// handlers of that type.
var responders = registry.get(eventName);
if (Object.isUndefined(responders)) return element;
responders.each( function(r) {
Element.stopObserving(element, eventName, r.handler);
});
return element;
} else if (!eventName) {
// If both the event name and the handler are omitted, we stop observing
// _all_ handlers on the element.
if (!eventName) {
// We stop observing all events.
// e.g.: $(element).stopObserving();
registry.each( function(pair) {
var eventName = pair.key, responders = pair.value;
responders.each( function(r) {
Element.stopObserving(element, eventName, r.handler);
});
var eventName = pair.key;
stopObserving(element, eventName);
});
return element;
}
var responders = registry.get(eventName);
if (!responders) return element;
// Fail gracefully if there are no responders assigned.
if (!responders) return;
if (!handler) {
// We stop observing all handlers for the given eventName.
// e.g.: $(element).stopObserving('click');
responders.each(function(r) {
stopObserving(element, eventName, r.handler);
});
return element;
}
var responder = responders.find( function(r) { return r.handler === handler; });
if (!responder) return element;
var actualEventName = _getDOMEventName(eventName);
if (eventName.include(':')) {
// Custom event.
if (element.removeEventListener)
@ -669,6 +664,7 @@
}
} else {
// Ordinary event.
var actualEventName = _getDOMEventName(eventName);
if (element.removeEventListener)
element.removeEventListener(actualEventName, responder, false);
else
@ -749,7 +745,7 @@
});
/** section: DOM
* document
* document
*
* Prototype extends the built-in `document` object with several convenience
* methods related to events.

View File

@ -46,7 +46,7 @@ var Form = {
* fields are included in that object or string.
*
* If you do not supply an `options` object _at all_, the options
* `{hash: false}` are used.
* `{ hash: false }` are used.
*
* If you supply an `options` object, it may have the following options:
* - `hash` ([[Boolean]]): `true` to return a plain object with keys and values
@ -248,7 +248,7 @@ Form.Methods = {
/*--------------------------------------------------------------------------*/
/** section: DOM
/**
* Form.Element
*
* Utilities for dealing with form controls in the DOM.
@ -359,7 +359,7 @@ Form.Element.Methods = {
},
/**
* Form.Element#activate(element) -> Element
* Form.Element.activate(@element) -> Element
*
* Gives focus to a form control and selects its contents if it is a text
* input.
@ -479,7 +479,7 @@ Form.Element.Serializers = {
* Abstract
**/
/** section: DOM
/**
* class Abstract.TimedObserver
*
* An abstract DOM element observer class, subclasses of which can be used to periodically
@ -528,7 +528,7 @@ Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
}
});
/** section: DOM
/**
* class Form.Element.Observer < Abstract.TimedObserver
*
* An [[Abstract.TimedObserver]] subclass that watches for changes to a form field's value.
@ -551,7 +551,7 @@ Form.Element.Observer = Class.create(Abstract.TimedObserver, {
}
});
/** section: DOM
/**
* class Form.Observer < Abstract.TimedObserver
*
* An [[Abstract.TimedObserver]] subclass that watches for changes to a form.
@ -577,7 +577,7 @@ Form.Observer = Class.create(Abstract.TimedObserver, {
/*--------------------------------------------------------------------------*/
/** section: DOM
/**
* class Abstract.EventObserver
**/
Abstract.EventObserver = Class.create({
@ -619,7 +619,7 @@ Abstract.EventObserver = Class.create({
}
});
/** section: DOM
/**
* class Form.Element.EventObserver < Abstract.EventObserver
**/
Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
@ -628,8 +628,8 @@ Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
}
});
/** section: DOM
* class Form.Element.EventObserver < Abstract.EventObserver
/**
* class Form.EventObserver < Abstract.EventObserver
**/
Form.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {

View File

@ -1,8 +1,9 @@
/** related to: Prototype.Selector
/** section: DOM, related to: Prototype.Selector
* $$(expression...) -> [Element...]
*
* Returns all elements in the document that match the provided CSS selectors.
**/
window.$$ = function() {
var expression = $A(arguments).join(', ');
return Prototype.Selector.select(expression, document);
@ -41,15 +42,25 @@ window.$$ = function() {
// Implementation provided by selector engine.
/**
* Prototype.Selector.filter(elements, expression) -> [Element...]
* Prototype.Selector.find(elements, expression[, index = 0]) -> Element
* - elements (Enumerable): a collection of DOM elements.
* - expression (String): A CSS selector.
* - index: Numeric index of the match to return, defaults to 0.
*
* Filters the given collection of elements with `expression` and returns an
* array of extended [[Element]] objects.
*
* The only nodes returned will be those that match the given CSS selector.
* Filters the given collection of elements with `expression` and returns the
* first matching element (or the `index`th matching element if `index` is
* specified).
**/
if (!Prototype.Selector.find) {
Prototype.Selector.find = function(elements, expression, index) {
if (Object.isUndefined(index)) index = 0;
var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
// Implementation provided by selector engine.
for (i = 0; i < length; i++) {
if (match(elements[i], expression) && index == matchIndex++) {
return Element.extend(elements[i]);
}
}
}
}

View File

@ -9,6 +9,17 @@
* inheritance](http://prototypejs.org/learn/class-inheritance).
**/
var Class = (function() {
// Some versions of JScript fail to enumerate over properties, names of which
// correspond to non-enumerable properties in the prototype chain
var IS_DONTENUM_BUGGY = (function(){
for (var p in { toString: 1 }) {
// check actual property name, so that it works with augmented Object.prototype
if (p === 'toString') return false;
}
return true;
})();
/**
* Class.create([superclass][, methods...]) -> Class
* - superclass (Class): The optional superclass to inherit methods from.
@ -59,7 +70,7 @@ var Class = (function() {
parent.subclasses.push(klass);
}
for (var i = 0; i < properties.length; i++)
for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
@ -135,12 +146,13 @@ var Class = (function() {
* //-> alerts "You should probably run. He looks really mad."
**/
function addMethods(source) {
var ancestor = this.superclass && this.superclass.prototype;
var properties = Object.keys(source);
var ancestor = this.superclass && this.superclass.prototype,
properties = Object.keys(source);
// IE6 doesn't enumerate toString and valueOf properties,
// Force copy if they're not coming from Object.prototype.
if (!Object.keys({ toString: true }).length) {
// IE6 doesn't enumerate `toString` and `valueOf` (among other built-in `Object.prototype`) properties,
// Force copy if they're not Object.prototype ones.
// Do not copy other Object.prototype.* for performance reasons
if (IS_DONTENUM_BUGGY) {
if (source.toString != Object.prototype.toString)
properties.push("toString");
if (source.valueOf != Object.prototype.valueOf)
@ -150,7 +162,7 @@ var Class = (function() {
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") {
value.argumentNames()[0] == "$super") {
var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };

View File

@ -217,7 +217,13 @@
function isArray(object) {
return _toString.call(object) == "[object Array]";
}
var hasNativeIsArray = (typeof Array.isArray == 'function')
&& Array.isArray([]) && !Array.isArray({});
if (hasNativeIsArray) {
isArray = Array.isArray;
}
/**
* Object.isHash(object) -> Boolean

View File

@ -42,6 +42,11 @@ Object.extend(String.prototype, (function() {
* Returns the string with every occurence of a given pattern replaced by either
* a regular string, the returned value of a function or a [[Template]] string.
* The pattern can be a string or a regular expression.
*
* <h5>Example</h5>
*
* ""hello".gsub(/([aeiou])/, '<#{1}>');
* // => "h<e>ll<o>"
**/
function gsub(pattern, replacement) {
var result = '', source = this, match;
@ -73,6 +78,11 @@ Object.extend(String.prototype, (function() {
* Returns a string with the first count occurrences of pattern replaced by either
* a regular string, the returned value of a function or a [[Template]] string.
* The pattern can be a string or a regular expression.
*
* <h5>Example</h5>
*
* "20091201".sub(/^(\d{4})(\d{2})(\d{2})$/, "#{1}-#{2}-#{3}");
* // => "2009-12-01"
**/
function sub(pattern, replacement, count) {
replacement = prepareReplacement(replacement);
@ -131,7 +141,7 @@ Object.extend(String.prototype, (function() {
*
* Note that the processing `stripTags` does is good enough for most purposes, but
* you cannot rely on it for security purposes. If you're processing end-user-supplied
* content, `stripTags` is probably _not_ sufficiently robust to ensure that the content
* content, `stripTags` is _not_ sufficiently robust to ensure that the content
* is completely devoid of HTML tags in the case of a user intentionally trying to circumvent
* tag restrictions. But then, you'll be running them through [[String#escapeHTML]] anyway,
* won't you?
@ -167,8 +177,8 @@ Object.extend(String.prototype, (function() {
* returns them as an array of strings.
**/
function extractScripts() {
var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
@ -251,8 +261,9 @@ Object.extend(String.prototype, (function() {
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];
var key = decodeURIComponent(pair.shift()),
value = pair.length > 1 ? pair.join('=') : pair[0];
if (value != undefined) value = decodeURIComponent(value);
if (key in hash) {
@ -311,17 +322,9 @@ Object.extend(String.prototype, (function() {
* // -> 'MozBinding'
**/
function camelize() {
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;
return this.replace(/-+(.)?/g, function(match, chr) {
return chr ? chr.toUpperCase() : '';
});
}
/**
@ -437,7 +440,9 @@ Object.extend(String.prototype, (function() {
* Checks if the string starts with `substring`.
**/
function startsWith(pattern) {
return this.indexOf(pattern) === 0;
// We use `lastIndexOf` instead of `indexOf` to avoid tying execution
// time to string length when string doesn't start with pattern.
return this.lastIndexOf(pattern, 0) === 0;
}
/**
@ -447,7 +452,9 @@ Object.extend(String.prototype, (function() {
**/
function endsWith(pattern) {
var d = this.length - pattern.length;
return d >= 0 && this.lastIndexOf(pattern) === d;
// We use `indexOf` instead of `lastIndexOf` to avoid tying execution
// time to string length when string doesn't end with pattern.
return d >= 0 && this.indexOf(pattern, d) === d;
}
/**
@ -486,7 +493,7 @@ Object.extend(String.prototype, (function() {
truncate: truncate,
// Firefox 3.5+ supports String.prototype.trim
// (`trim` is ~ 5x faster than `strip` in FF3.5)
strip: String.prototype.trim ? String.prototype.trim : strip,
strip: String.prototype.trim || strip,
stripTags: stripTags,
stripScripts: stripScripts,
extractScripts: extractScripts,

View File

@ -82,14 +82,14 @@
* inadequate, there's a provision for customization. `Template`'s
* constructor accepts an optional second argument that is a regular expression
* object to match the replaceable symbols in the template string. Let's put
* together a template that uses a syntax similar to the ubiquitous `<&#38;= %>`
* together a template that uses a syntax similar to the now ubiquitous `{{ }}`
* constructs:
*
* // matches symbols like '<&#38;= field %>'
* var syntax = /(^|.|\r|\n)(\<%=\s*(\w+)\s*%\>)/;
* // matches symbols like '{{ field }}'
* var syntax = /(^|.|\r|\n)(\{{\s*(\w+)\s*}})/;
*
* var t = new Template(
* '<div>Name: <b><&#38;= name %></b>, Age: <b><&#38;=age%></b></div>',
* '<div>Name: <b>{{ name }}</b>, Age: <b>{{ age }}</b></div>',
* syntax);
* t.evaluate( {name: 'John Smith', age: 26} );
* // -> <div>Name: <b>John Smith</b>, Age: <b>26</b></div>
@ -133,8 +133,9 @@ var Template = Class.create({
var before = match[1] || '';
if (before == '\\') return match[2];
var ctx = object, expr = match[3];
var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
var ctx = object, expr = match[3],
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
match = pattern.exec(expr);
if (match == null) return before;

6
src/prototype.js vendored
View File

@ -35,9 +35,9 @@ var Prototype = {
if (typeof window.HTMLDivElement !== 'undefined')
return true;
var div = document.createElement('div');
var form = document.createElement('form');
var isSupported = false;
var div = document.createElement('div'),
form = document.createElement('form'),
isSupported = false;
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
isSupported = true;

View File

@ -1,5 +1,5 @@
Prototype._original_property = window.Sizzle;
//= require "repository/sizzle"
//= require "sizzle"
Prototype.Selector = (function(engine) {
function extend(elements) {
@ -16,16 +16,11 @@ Prototype.Selector = (function(engine) {
function match(element, selector) {
return engine.matches(selector, [element]).length == 1;
}
function filter(elements, selector) {
return extend(engine.matches(selector, elements));
}
return {
engine: engine,
select: select,
match: match,
filter: filter
match: match
};
})(Sizzle);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 946 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

View File

@ -1,389 +0,0 @@
if (typeof PDoc === "undefined") window.PDoc = {};
// Poor-man's history manager. Polls for changes to the hash.
(function() {
var PREVIOUS_HASH = null;
Event.observe(window, "load", function() {
var hash = window.location.hash;
if (hash && hash !== PREVIOUS_HASH) {
document.fire("hash:changed",
{ previous: PREVIOUS_HASH, current: hash });
PREVIOUS_HASH = hash;
}
window.setTimeout(arguments.callee, 100);
});
})();
// Place a "frame" around the element described by the hash.
// Update the frame when the hash changes.
PDoc.highlightSelected = function() {
if (!window.location.hash) return;
element = $(window.location.hash.substr(1));
if (element) PDoc.highlight(element.up('li, div'));
};
document.observe("hash:changed", PDoc.highlightSelected);
PDoc.highlight = function(element) {
var self = arguments.callee;
if (!self.frame) {
self.frame = new Element('div', { 'class': 'highlighter' });
document.body.appendChild(self.frame);
}
var frame = self.frame;
element.getOffsetParent().appendChild(frame);
var offset = element.positionedOffset();
var w = parseFloat(element.getStyle('width')),
h = parseFloat(element.getStyle('height'));
frame.setStyle({
position: 'absolute',
top: (offset.top - 15) + 'px',
left: (offset.left - 12) + 'px',
width: (w + 20) + 'px',
height: (h + 30) + 'px'
});
// Defer this call because Safari hasn't yet scrolled the viewport.
(function() {
var frameOffset = frame.viewportOffset(frame);
if (frameOffset.top < 0) {
window.scrollBy(0, frameOffset.top - 10);
}
}).defer();
};
// Live API search.
var Filterer = Class.create({
initialize: function(element, options) {
this.element = $(element);
this.options = Object.extend({
interval: 0.1,
resultsElement: '.search-results'
}, options || {});
this.element.writeAttribute("autocomplete", "off");
this.element.up('form').observe("submit", Event.stop);
// // The Safari-only "search" input type is prettier
// if (Prototype.Browser.WebKit)
// this.element.type = "search";
this.menu = this.options.menu;
this.links = this.menu.select('a');
this.resultsElement = this.options.resultsElement;
this.resultsElement.setStyle({
overflowX: 'hidden'
});
this.events = {
filter: this.filter.bind(this),
keydown: this.keydown.bind(this)
};
this.menu.setStyle({ opacity: 0.9 });
this.addObservers();
this.element.value = '';
},
addObservers: function() {
this.element.observe('keyup', this.events.filter);
},
filter: function(event) {
if (this._timer) window.clearTimeout(this._timer);
// Clear the text box on ESC
if (event.keyCode && event.keyCode === Event.KEY_ESC) {
this.element.value = '';
}
if ([Event.KEY_UP, Event.KEY_DOWN, Event.KEY_RETURN].include(event.keyCode))
return;
var value = $F(this.element).strip().toLowerCase();
if (value === "") {
this.onEmpty();
return;
}
var urls = this.findURLs(value);
this.buildResults(urls);
},
keydown: function(event) {
if (![Event.KEY_UP, Event.KEY_DOWN, Event.KEY_RETURN].include(event.keyCode))
return;
// ignore if any modifier keys are present
if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey)
return;
event.stop();
var highlighted = this.resultsElement.down('.highlighted');
if (event.keyCode === Event.KEY_RETURN) {
// Follow the highlighted item.
if (!highlighted) return;
window.location.href = highlighted.down('a').href;
} else {
var direction = (Event.KEY_DOWN === event.keyCode) ? 1 : -1;
highlighted = this.moveHighlight(direction);
}
if ([Event.KEY_UP, Event.KEY_DOWN].include(event.keyCode) &&
!Prototype.Browser.WebKit) {
// If up/down key is held down, list should keep scrolling.
// Safari does this automatically because it fires the keydown
// event over and over.
this._timer = window.setTimeout(this.scrollList.bind(this, direction), 1000);
}
},
moveHighlight: function(direction) {
var highlighted = this.resultsElement.down('.highlighted');
// move the focus
if (!highlighted) {
// if there is none, highlight the first result
var highlighted = this.resultsElement.down('li').addClassName('highlighted');
} else {
var method = (direction === 1) ? 'next' : 'previous';
highlighted.removeClassName('highlighted');
var adjacent = highlighted[method]('li');
if (!adjacent) {
adjacent = method == 'next' ? this.resultsElement.down('li') :
this.resultsElement.down('li:last-of-type');
}
adjacent.addClassName('highlighted');
highlighted = adjacent;
}
// Adjust the scroll offset of the container so that the highlighted
// item is always in view.
var distanceToBottom = highlighted.offsetTop + highlighted.offsetHeight;
if (distanceToBottom > this.resultsElement.offsetHeight + this.resultsElement.scrollTop) {
// item is too low
this.resultsElement.scrollTop = distanceToBottom - this.resultsElement.offsetHeight;
} else if (highlighted.offsetTop < this.resultsElement.scrollTop) {
// item is too high
this.resultsElement.scrollTop = highlighted.offsetTop;
}
return highlighted;
},
scrollList: function(direction) {
this.moveHighlight(direction);
this._timer = window.setTimeout(this.scrollList.bind(this, direction), 100);
},
// Given a path with any number of `../`s in front of it, remove them all.
// TODO: Fix this a better way.
_fixPath: function(path) {
return path.replace('../', '');
},
buildResults: function(urls) {
this.resultsElement.update();
var ul = this.resultsElement;
urls.each( function(url) {
var a = new Element('a', {
'class': url.type.gsub(/\s/, '_'),
href: PDoc.pathPrefix + this._fixPath(url.path)
}).update(url.name);
var li = new Element('li', { 'class': 'menu-item' });
li.appendChild(a);
ul.appendChild(li);
}, this);
this.showResults();
},
findURLs: function(str) {
var results = [];
for (var i in PDoc.elements) {
if (i.toLowerCase().include(str)) results.push(PDoc.elements[i]);
}
return results;
},
onEmpty: function() {
this.hideResults();
},
showResults: function() {
this.resultsElement.show();
document.stopObserving("keydown", this.events.keydown);
document.observe("keydown", this.events.keydown);
},
hideResults: function() {
this.resultsElement.hide();
document.stopObserving("keydown", this.events.keydown);
}
});
document.observe('dom:loaded', function() {
new Filterer($('search'), {
menu: $('api_menu'),
resultsElement: $('search_results')
});
});
Event.observe(window, 'load', function() {
var menu = $('menu');
var OFFSET = menu.viewportOffset().top;
Event.observe(window, 'scroll', function() {
var sOffset = document.viewport.getScrollOffsets();
if (sOffset.top > OFFSET) {
menu.addClassName('fixed');
} else menu.removeClassName('fixed');
});
});
(function() {
function menuButtonMouseOver(event) {
var menuButton = $('api_menu_button');
var target = event.element();
if (target === menuButton || target.descendantOf(menuButton)) {
$('api_menu').show();
}
}
function menuButtonMouseOut(event) {
var menuButton = $('api_menu_button');
var menu = $('api_menu');
var target = event.element(), related = event.relatedTarget || event.toElement;
if (related && (related === menu || related.descendantOf(menu))) return;
menu.hide();
}
function menuMouseOut(event) {
var menu = $('api_menu'), related = event.relatedTarget || event.toElement;
if (related && !related.descendantOf(menu)) {
arguments.callee.timer = Element.hide.delay(0.5, menu);
} else {
window.clearTimeout(arguments.callee.timer);
}
}
function menuItemMouseOver(event) {
var element = event.element();
if (element.tagName.toLowerCase() === 'a') {
element.addClassName('highlighted');
}
}
function menuItemMouseOut(event) {
var element = event.element();
if (element.tagName.toLowerCase() === 'a') {
element.removeClassName('highlighted');
}
}
var MENU_ITEMS;
document.observe('dom:loaded', function() {
MENU_ITEMS = $$('.api-box .menu-item a');
$('api_menu_button').observe('mouseenter', menuButtonMouseOver);
$('api_menu_button').observe('mouseleave', menuButtonMouseOut );
$('api_menu').observe('mouseleave', menuMouseOut);
if (Prototype.Browser.IE) {
$('api_menu').observe('mouseover', menuItemMouseOver);
$('api_menu').observe('mouseout', menuItemMouseOut);
}
});
})();
Form.GhostedField = Class.create({
initialize: function(element, title, options) {
this.element = $(element);
this.title = title;
options = options || {};
this.isGhosted = true;
if (options.cloak) {
// Wrap the native getValue function so that it never returns the
// ghosted value. This is optional because it presumes the ghosted
// value isn't valid input for the field.
this.element.getValue = this.element.getValue.wrap(this.wrappedGetValue.bind(this));
}
this.addObservers();
this.onBlur();
},
wrappedGetValue: function($proceed) {
var value = $proceed();
return value === this.title ? "" : value;
},
addObservers: function() {
this.element.observe('focus', this.onFocus.bind(this));
this.element.observe('blur', this.onBlur.bind(this));
var form = this.element.up('form');
if (form) {
form.observe('submit', this.onSubmit.bind(this));
}
// Firefox's bfcache means that form fields need to be re-initialized
// when you hit the "back" button to return to the page.
if (Prototype.Browser.Gecko) {
window.addEventListener('pageshow', this.onBlur.bind(this), false);
}
},
onFocus: function() {
if (this.isGhosted) {
this.element.setValue('');
this.setGhosted(false);
}
},
onBlur: function() {
var value = this.element.getValue();
if (value.blank() || value == this.title) {
this.setGhosted(true);
} else {
this.setGhosted(false);
}
},
setGhosted: function(isGhosted) {
this.isGhosted = isGhosted;
this.element[isGhosted ? 'addClassName' : 'removeClassName']('ghosted');
if (isGhosted) {
this.element.setValue(this.title);
}
},
// Hook into the enclosing form's `onsubmit` event so that we clear any
// ghosted text before the form is sent.
onSubmit: function() {
if (this.isGhosted) {
this.element.setValue('');
}
}
});
document.observe("dom:loaded", function() {
new Form.GhostedField($('search'), "Search");
});

View File

@ -1,251 +0,0 @@
/* Unobtrustive Code Highlighter By Dan Webb 11/2005
Version: 0.4
Usage:
Add a script tag for this script and any stylesets you need to use
to the page in question, add correct class names to CODE elements,
define CSS styles for elements. That's it!
Known to work on:
IE 5.5+ PC
Firefox/Mozilla PC/Mac
Opera 7.23 + PC
Safari 2
Known to degrade gracefully on:
IE5.0 PC
Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors
in older browsers use expressions that use lookahead in string format when defining stylesets.
This script is inspired by star-light by entirely cunning Dean Edwards
http://dean.edwards.name/star-light/.
*/
// replace callback support for safari.
if ("a".replace(/a/, function() {return "b"}) != "b") (function(){
var default_replace = String.prototype.replace;
String.prototype.replace = function(search,replace){
// replace is not function
if(typeof replace != "function"){
return default_replace.apply(this,arguments)
}
var str = "" + this;
var callback = replace;
// search string is not RegExp
if(!(search instanceof RegExp)){
var idx = str.indexOf(search);
return (
idx == -1 ? str :
default_replace.apply(str,[search,callback(search, idx, str)])
)
}
var reg = search;
var result = [];
var lastidx = reg.lastIndex;
var re;
while((re = reg.exec(str)) != null){
var idx = re.index;
var args = re.concat(idx, str);
result.push(
str.slice(lastidx,idx),
callback.apply(null,args).toString()
);
if(!reg.global){
lastidx += RegExp.lastMatch.length;
break
}else{
lastidx = reg.lastIndex;
}
}
result.push(str.slice(lastidx));
return result.join("")
}
})();
var CodeHighlighter = { styleSets : new Array };
CodeHighlighter.addStyle = function(name, rules) {
// using push test to disallow older browsers from adding styleSets
if ([].push) this.styleSets.push({
name : name,
rules : rules,
ignoreCase : arguments[2] || false
})
function setEvent() {
// set highlighter to run on load (use LowPro if present)
if (typeof Event != 'undefined' && typeof Event.onReady == 'function')
return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter));
var old = window.onload;
if (typeof window.onload != 'function') {
window.onload = function() { CodeHighlighter.init() };
} else {
window.onload = function() {
old();
CodeHighlighter.init();
}
}
}
// only set the event when the first style is added
if (this.styleSets.length==1) setEvent();
}
CodeHighlighter.init = function() {
if (!document.getElementsByTagName) return;
if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function
// throw out older browsers
var codeEls = document.getElementsByTagName("CODE");
// collect array of all pre elements
codeEls.filter = function(f) {
var a = new Array;
for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i];
return a;
}
var rules = new Array;
rules.toString = function() {
// joins regexes into one big parallel regex
var exps = new Array;
for (var i = 0; i < this.length; i++) exps.push(this[i].exp);
return exps.join("|");
}
function addRule(className, rule) {
// add a replace rule
var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp;
// converts regex rules to strings and chops of the slashes
rules.push({
className : className,
exp : "(" + exp + ")",
length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule
replacement : rule.replacement || null
});
}
function parse(text, ignoreCase) {
// main text parsing and replacement
return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() {
var i = 0, j = 1, rule;
while (rule = rules[i++]) {
if (arguments[j]) {
// if no custom replacement defined do the simple replacement
if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>";
else {
// replace $0 with the className then do normal replaces
var str = rule.replacement.replace("$0", rule.className);
for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]);
return str;
}
} else j+= rule.length;
}
});
}
function highlightCode(styleSet) {
// clear rules array
var parsed;
rules.length = 0;
// get stylable elements by filtering out all code elements without the correct className
var stylableEls = codeEls.filter(function(item) {return (item.className.indexOf(styleSet.name)>=0)});
// add style rules to parser
for (var className in styleSet.rules) addRule(className, styleSet.rules[className]);
// replace for all elements
for (var i = 0; i < stylableEls.length; i++) {
// EVIL hack to fix IE whitespace badness if it's inside a <pre>
if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
stylableEls[i] = stylableEls[i].parentNode;
parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() {
return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>"
});
parsed = parsed.replace(/\n( *)/g, function() {
var spaces = "";
for (var i = 0; i < arguments[1].length; i++) spaces+= "&nbsp;";
return "\n" + spaces;
});
parsed = parsed.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>");
} else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase);
stylableEls[i].innerHTML = parsed;
}
}
// run highlighter on all stylesets
for (var i=0; i < this.styleSets.length; i++) {
highlightCode(this.styleSets[i]);
}
};
CodeHighlighter.addStyle("css", {
comment : {
exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
},
keywords : {
exp : /@\w[\w\s]*/
},
selectors : {
exp : "([\\w-:\\[.#][^{};>]*)(?={)"
},
properties : {
exp : "([\\w-]+)(?=\\s*:)"
},
units : {
exp : /([0-9])(em|en|px|%|pt)\b/,
replacement : "$1<span class=\"$0\">$2</span>"
},
urls : {
exp : /url\([^\)]*\)/
}
});
CodeHighlighter.addStyle("html", {
comment : {
exp: /&lt;!\s*(--([^-]|[\r\n]|-[^-])*--\s*)&gt;/
},
tag : {
exp: /(&lt;\/?)([a-zA-Z]+\s?)/,
replacement: "$1<span class=\"$0\">$2</span>"
},
string : {
exp : /'[^']*'|"[^"]*"/
},
attribute : {
exp: /\b([a-zA-Z-:]+)(=)/,
replacement: "<span class=\"$0\">$1</span>$2"
},
doctype : {
exp: /&lt;!DOCTYPE([^&]|&[^g]|&g[^t])*&gt;/
}
});
CodeHighlighter.addStyle("javascript",{
comment : {
exp : /(\/\/[^\n]*(\n|$))|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/
},
brackets : {
exp : /\(|\)/
},
regex : {
exp : /\/(.*?)[g|s|m]?\/[;|\n]/
},
string : {
exp : /'(?:\.|(\\\')|[^\''])*'|"(?:\.|(\\\")|[^\""])*"/
},
keywords : {
exp : /\b(arguments|break|case|continue|default|delete|do|else|false|for|function|if|in|instanceof|new|null|return|switch|this|true|typeof|var|void|while|with)\b/
},
global : {
exp : /\b(toString|valueOf|window|element|prototype|constructor|document|escape|unescape|parseInt|parseFloat|setTimeout|clearTimeout|setInterval|clearInterval|NaN|isNaN|Infinity|alert|prompt|confirm)\b/
}
});

View File

@ -1,963 +0,0 @@
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
// Contributors:
// Richard Livsey
// Rahul Bhargava
// Rob Wills
//
// 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/
// Autocompleter.Base handles all the autocompletion functionality
// that's independent of the data source for autocompletion. This
// includes drawing the autocompletion menu, observing keyboard
// and mouse events, and similar.
//
// Specific autocompleters need to provide, at the very least,
// a getUpdatedChoices function that will be invoked every time
// the text inside the monitored textbox changes. This method
// should get the text for which to provide autocompletion by
// invoking this.getToken(), NOT by directly accessing
// this.element.value. This is to allow incremental tokenized
// autocompletion. Specific auto-completion logic (AJAX, etc)
// belongs in getUpdatedChoices.
//
// Tokenized incremental autocompletion is enabled automatically
// when an autocompleter is instantiated with the 'tokens' option
// in the options parameter, e.g.:
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
// will incrementally autocomplete with a comma as the token.
// Additionally, ',' in the above example can be replaced with
// a token array, e.g. { tokens: [',', '\n'] } which
// enables autocompletion on multiple tokens. This is most
// useful when one of the tokens is \n (a newline), as it
// allows smart autocompletion after linebreaks.
if(typeof Effect == 'undefined')
throw("controls.js requires including script.aculo.us' effects.js library");
var Autocompleter = { }
Autocompleter.Base = Class.create({
baseInitialize: function(element, update, options) {
element = $(element)
this.element = element;
this.update = $(update);
this.hasFocus = false;
this.changed = false;
this.active = false;
this.index = 0;
this.entryCount = 0;
this.oldElementValue = this.element.value;
if(this.setOptions)
this.setOptions(options);
else
this.options = options || { };
this.options.paramName = this.options.paramName || this.element.name;
this.options.tokens = this.options.tokens || [];
this.options.frequency = this.options.frequency || 0.4;
this.options.minChars = this.options.minChars || 1;
this.options.onShow = this.options.onShow ||
function(element, update){
if(!update.style.position || update.style.position=='absolute') {
update.style.position = 'absolute';
Position.clone(element, update, {
setHeight: false,
offsetTop: element.offsetHeight
});
}
Effect.Appear(update,{duration:0.15});
};
this.options.onHide = this.options.onHide ||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
if(typeof(this.options.tokens) == 'string')
this.options.tokens = new Array(this.options.tokens);
// Force carriage returns as token delimiters anyway
if (!this.options.tokens.include('\n'))
this.options.tokens.push('\n');
this.observer = null;
this.element.setAttribute('autocomplete','off');
Element.hide(this.update);
Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
},
show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix &&
(Prototype.Browser.IE) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
this.iefix = $(this.update.id+'_iefix');
}
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
},
fixIEOverlapping: function() {
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1;
this.update.style.zIndex = 2;
Element.show(this.iefix);
},
hide: function() {
this.stopIndicator();
if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
if(this.iefix) Element.hide(this.iefix);
},
startIndicator: function() {
if(this.options.indicator) Element.show(this.options.indicator);
},
stopIndicator: function() {
if(this.options.indicator) Element.hide(this.options.indicator);
},
onKeyPress: function(event) {
if(this.active)
switch(event.keyCode) {
case Event.KEY_TAB:
case Event.KEY_RETURN:
this.selectEntry();
Event.stop(event);
case Event.KEY_ESC:
this.hide();
this.active = false;
Event.stop(event);
return;
case Event.KEY_LEFT:
case Event.KEY_RIGHT:
return;
case Event.KEY_UP:
this.markPrevious();
this.render();
Event.stop(event);
return;
case Event.KEY_DOWN:
this.markNext();
this.render();
Event.stop(event);
return;
}
else
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
this.changed = true;
this.hasFocus = true;
if(this.observer) clearTimeout(this.observer);
this.observer =
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
},
activate: function() {
this.changed = false;
this.hasFocus = true;
this.getUpdatedChoices();
},
onHover: function(event) {
var element = Event.findElement(event, 'LI');
if(this.index != element.autocompleteIndex)
{
this.index = element.autocompleteIndex;
this.render();
}
Event.stop(event);
},
onClick: function(event) {
var element = Event.findElement(event, 'LI');
this.index = element.autocompleteIndex;
this.selectEntry();
this.hide();
},
onBlur: function(event) {
// needed to make click events working
setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
this.active = false;
},
render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
this.index==i ?
Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
if(this.hasFocus) {
this.show();
this.active = true;
}
} else {
this.active = false;
this.hide();
}
},
markPrevious: function() {
if(this.index > 0) this.index--
else this.index = this.entryCount-1;
this.getEntry(this.index).scrollIntoView(true);
},
markNext: function() {
if(this.index < this.entryCount-1) this.index++
else this.index = 0;
this.getEntry(this.index).scrollIntoView(false);
},
getEntry: function(index) {
return this.update.firstChild.childNodes[index];
},
getCurrentEntry: function() {
return this.getEntry(this.index);
},
selectEntry: function() {
this.active = false;
this.updateElement(this.getCurrentEntry());
},
updateElement: function(selectedElement) {
if (this.options.updateElement) {
this.options.updateElement(selectedElement);
return;
}
var value = '';
if (this.options.select) {
var nodes = $(selectedElement).select('.' + this.options.select) || [];
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
} else
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
var bounds = this.getTokenBounds();
if (bounds[0] != -1) {
var newValue = this.element.value.substr(0, bounds[0]);
var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
if (whitespace)
newValue += whitespace[0];
this.element.value = newValue + value + this.element.value.substr(bounds[1]);
} else {
this.element.value = value;
}
this.oldElementValue = this.element.value;
this.element.focus();
if (this.options.afterUpdateElement)
this.options.afterUpdateElement(this.element, selectedElement);
},
updateChoices: function(choices) {
if(!this.changed && this.hasFocus) {
this.update.innerHTML = choices;
Element.cleanWhitespace(this.update);
Element.cleanWhitespace(this.update.down());
if(this.update.firstChild && this.update.down().childNodes) {
this.entryCount =
this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
} else {
this.entryCount = 0;
}
this.stopIndicator();
this.index = 0;
if(this.entryCount==1 && this.options.autoSelect) {
this.selectEntry();
this.hide();
} else {
this.render();
}
}
},
addObservers: function(element) {
Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
Event.observe(element, "click", this.onClick.bindAsEventListener(this));
},
onObserverEvent: function() {
this.changed = false;
this.tokenBounds = null;
if(this.getToken().length>=this.options.minChars) {
this.getUpdatedChoices();
} else {
this.active = false;
this.hide();
}
this.oldElementValue = this.element.value;
},
getToken: function() {
var bounds = this.getTokenBounds();
return this.element.value.substring(bounds[0], bounds[1]).strip();
},
getTokenBounds: function() {
if (null != this.tokenBounds) return this.tokenBounds;
var value = this.element.value;
if (value.strip().empty()) return [-1, 0];
var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
var offset = (diff == this.oldElementValue.length ? 1 : 0);
var prevTokenPos = -1, nextTokenPos = value.length;
var tp;
for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
if (tp > prevTokenPos) prevTokenPos = tp;
tp = value.indexOf(this.options.tokens[index], diff + offset);
if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
}
return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
}
});
Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
var boundary = Math.min(newS.length, oldS.length);
for (var index = 0; index < boundary; ++index)
if (newS[index] != oldS[index])
return index;
return boundary;
};
Ajax.Autocompleter = Class.create(Autocompleter.Base, {
initialize: function(element, update, url, options) {
this.baseInitialize(element, update, options);
this.options.asynchronous = true;
this.options.onComplete = this.onComplete.bind(this);
this.options.defaultParams = this.options.parameters || null;
this.url = url;
},
getUpdatedChoices: function() {
this.startIndicator();
var entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken());
this.options.parameters = this.options.callback ?
this.options.callback(this.element, entry) : entry;
if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams;
new Ajax.Request(this.url, this.options);
},
onComplete: function(request) {
this.updateChoices(request.responseText);
}
});
// The local array autocompleter. Used when you'd prefer to
// inject an array of autocompletion options into the page, rather
// than sending out Ajax queries, which can be quite slow sometimes.
//
// The constructor takes four parameters. The first two are, as usual,
// the id of the monitored textbox, and id of the autocompletion menu.
// The third is the array you want to autocomplete from, and the fourth
// is the options block.
//
// Extra local autocompletion options:
// - choices - How many autocompletion choices to offer
//
// - partialSearch - If false, the autocompleter will match entered
// text only at the beginning of strings in the
// autocomplete array. Defaults to true, which will
// match text at the beginning of any *word* in the
// strings in the autocomplete array. If you want to
// search anywhere in the string, additionally set
// the option fullSearch to true (default: off).
//
// - fullSsearch - Search anywhere in autocomplete array strings.
//
// - partialChars - How many characters to enter before triggering
// a partial match (unlike minChars, which defines
// how many characters are required to do any match
// at all). Defaults to 2.
//
// - ignoreCase - Whether to ignore case when autocompleting.
// Defaults to true.
//
// It's possible to pass in a custom function as the 'selector'
// option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless
// you support them.
Autocompleter.Local = Class.create(Autocompleter.Base, {
initialize: function(element, update, array, options) {
this.baseInitialize(element, update, options);
this.options.array = array;
},
getUpdatedChoices: function() {
this.updateChoices(this.options.selector(this));
},
setOptions: function(options) {
this.options = Object.extend({
choices: 10,
partialSearch: true,
partialChars: 2,
ignoreCase: true,
fullSearch: false,
selector: function(instance) {
var ret = []; // Beginning matches
var partial = []; // Inside matches
var entry = instance.getToken();
var count = 0;
for (var i = 0; i < instance.options.array.length &&
ret.length < instance.options.choices ; i++) {
var elem = instance.options.array[i];
var foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase()) :
elem.indexOf(entry);
while (foundPos != -1) {
if (foundPos == 0 && elem.length != entry.length) {
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
elem.substr(entry.length) + "</li>");
break;
} else if (entry.length >= instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
foundPos + entry.length) + "</li>");
break;
}
}
foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
elem.indexOf(entry, foundPos + 1);
}
}
if (partial.length)
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
return "<ul>" + ret.join('') + "</ul>";
}
}, options || { });
}
});
// AJAX in-place editor and collection editor
// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
// Use this if you notice weird scrolling problems on some browsers,
// the DOM might be a bit confused when this gets called so do this
// waits 1 ms (with setTimeout) until it does the activation
Field.scrollFreeActivate = function(field) {
setTimeout(function() {
Field.activate(field);
}, 1);
}
Ajax.InPlaceEditor = Class.create({
initialize: function(element, url, options) {
this.url = url;
this.element = element = $(element);
this.prepareOptions();
this._controls = { };
arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
Object.extend(this.options, options || { });
if (!this.options.formId && this.element.id) {
this.options.formId = this.element.id + '-inplaceeditor';
if ($(this.options.formId))
this.options.formId = '';
}
if (this.options.externalControl)
this.options.externalControl = $(this.options.externalControl);
if (!this.options.externalControl)
this.options.externalControlOnly = false;
this._originalBackground = this.element.getStyle('background-color') || 'transparent';
this.element.title = this.options.clickToEditText;
this._boundCancelHandler = this.handleFormCancellation.bind(this);
this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
this._boundFailureHandler = this.handleAJAXFailure.bind(this);
this._boundSubmitHandler = this.handleFormSubmission.bind(this);
this._boundWrapperHandler = this.wrapUp.bind(this);
this.registerListeners();
},
checkForEscapeOrReturn: function(e) {
if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
if (Event.KEY_ESC == e.keyCode)
this.handleFormCancellation(e);
else if (Event.KEY_RETURN == e.keyCode)
this.handleFormSubmission(e);
},
createControl: function(mode, handler, extraClasses) {
var control = this.options[mode + 'Control'];
var text = this.options[mode + 'Text'];
if ('button' == control) {
var btn = document.createElement('input');
btn.type = 'submit';
btn.value = text;
btn.className = 'editor_' + mode + '_button';
if ('cancel' == mode)
btn.onclick = this._boundCancelHandler;
this._form.appendChild(btn);
this._controls[mode] = btn;
} else if ('link' == control) {
var link = document.createElement('a');
link.href = '#';
link.appendChild(document.createTextNode(text));
link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
link.className = 'editor_' + mode + '_link';
if (extraClasses)
link.className += ' ' + extraClasses;
this._form.appendChild(link);
this._controls[mode] = link;
}
},
createEditField: function() {
var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
var fld;
if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
fld = document.createElement('input');
fld.type = 'text';
var size = this.options.size || this.options.cols || 0;
if (0 < size) fld.size = size;
} else {
fld = document.createElement('textarea');
fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
fld.cols = this.options.cols || 40;
}
fld.name = this.options.paramName;
fld.value = text; // No HTML breaks conversion anymore
fld.className = 'editor_field';
if (this.options.submitOnBlur)
fld.onblur = this._boundSubmitHandler;
this._controls.editor = fld;
if (this.options.loadTextURL)
this.loadExternalText();
this._form.appendChild(this._controls.editor);
},
createForm: function() {
var ipe = this;
function addText(mode, condition) {
var text = ipe.options['text' + mode + 'Controls'];
if (!text || condition === false) return;
ipe._form.appendChild(document.createTextNode(text));
};
this._form = $(document.createElement('form'));
this._form.id = this.options.formId;
this._form.addClassName(this.options.formClassName);
this._form.onsubmit = this._boundSubmitHandler;
this.createEditField();
if ('textarea' == this._controls.editor.tagName.toLowerCase())
this._form.appendChild(document.createElement('br'));
if (this.options.onFormCustomization)
this.options.onFormCustomization(this, this._form);
addText('Before', this.options.okControl || this.options.cancelControl);
this.createControl('ok', this._boundSubmitHandler);
addText('Between', this.options.okControl && this.options.cancelControl);
this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
addText('After', this.options.okControl || this.options.cancelControl);
},
destroy: function() {
if (this._oldInnerHTML)
this.element.innerHTML = this._oldInnerHTML;
this.leaveEditMode();
this.unregisterListeners();
},
enterEditMode: function(e) {
if (this._saving || this._editing) return;
this._editing = true;
this.triggerCallback('onEnterEditMode');
if (this.options.externalControl)
this.options.externalControl.hide();
this.element.hide();
this.createForm();
this.element.parentNode.insertBefore(this._form, this.element);
if (!this.options.loadTextURL)
this.postProcessEditField();
if (e) Event.stop(e);
},
enterHover: function(e) {
if (this.options.hoverClassName)
this.element.addClassName(this.options.hoverClassName);
if (this._saving) return;
this.triggerCallback('onEnterHover');
},
getText: function() {
return this.element.innerHTML;
},
handleAJAXFailure: function(transport) {
this.triggerCallback('onFailure', transport);
if (this._oldInnerHTML) {
this.element.innerHTML = this._oldInnerHTML;
this._oldInnerHTML = null;
}
},
handleFormCancellation: function(e) {
this.wrapUp();
if (e) Event.stop(e);
},
handleFormSubmission: function(e) {
var form = this._form;
var value = $F(this._controls.editor);
this.prepareSubmission();
var params = this.options.callback(form, value) || '';
if (Object.isString(params))
params = params.toQueryParams();
params.editorId = this.element.id;
if (this.options.htmlResponse) {
var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
Object.extend(options, {
parameters: params,
onComplete: this._boundWrapperHandler,
onFailure: this._boundFailureHandler
});
new Ajax.Updater({ success: this.element }, this.url, options);
} else {
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
Object.extend(options, {
parameters: params,
onComplete: this._boundWrapperHandler,
onFailure: this._boundFailureHandler
});
new Ajax.Request(this.url, options);
}
if (e) Event.stop(e);
},
leaveEditMode: function() {
this.element.removeClassName(this.options.savingClassName);
this.removeForm();
this.leaveHover();
this.element.style.backgroundColor = this._originalBackground;
this.element.show();
if (this.options.externalControl)
this.options.externalControl.show();
this._saving = false;
this._editing = false;
this._oldInnerHTML = null;
this.triggerCallback('onLeaveEditMode');
},
leaveHover: function(e) {
if (this.options.hoverClassName)
this.element.removeClassName(this.options.hoverClassName);
if (this._saving) return;
this.triggerCallback('onLeaveHover');
},
loadExternalText: function() {
this._form.addClassName(this.options.loadingClassName);
this._controls.editor.disabled = true;
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
Object.extend(options, {
parameters: 'editorId=' + encodeURIComponent(this.element.id),
onComplete: Prototype.emptyFunction,
onSuccess: function(transport) {
this._form.removeClassName(this.options.loadingClassName);
var text = transport.responseText;
if (this.options.stripLoadedTextTags)
text = text.stripTags();
this._controls.editor.value = text;
this._controls.editor.disabled = false;
this.postProcessEditField();
}.bind(this),
onFailure: this._boundFailureHandler
});
new Ajax.Request(this.options.loadTextURL, options);
},
postProcessEditField: function() {
var fpc = this.options.fieldPostCreation;
if (fpc)
$(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
},
prepareOptions: function() {
this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
[this._extraDefaultOptions].flatten().compact().each(function(defs) {
Object.extend(this.options, defs);
}.bind(this));
},
prepareSubmission: function() {
this._saving = true;
this.removeForm();
this.leaveHover();
this.showSaving();
},
registerListeners: function() {
this._listeners = { };
var listener;
$H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
listener = this[pair.value].bind(this);
this._listeners[pair.key] = listener;
if (!this.options.externalControlOnly)
this.element.observe(pair.key, listener);
if (this.options.externalControl)
this.options.externalControl.observe(pair.key, listener);
}.bind(this));
},
removeForm: function() {
if (!this._form) return;
this._form.remove();
this._form = null;
this._controls = { };
},
showSaving: function() {
this._oldInnerHTML = this.element.innerHTML;
this.element.innerHTML = this.options.savingText;
this.element.addClassName(this.options.savingClassName);
this.element.style.backgroundColor = this._originalBackground;
this.element.show();
},
triggerCallback: function(cbName, arg) {
if ('function' == typeof this.options[cbName]) {
this.options[cbName](this, arg);
}
},
unregisterListeners: function() {
$H(this._listeners).each(function(pair) {
if (!this.options.externalControlOnly)
this.element.stopObserving(pair.key, pair.value);
if (this.options.externalControl)
this.options.externalControl.stopObserving(pair.key, pair.value);
}.bind(this));
},
wrapUp: function(transport) {
this.leaveEditMode();
// Can't use triggerCallback due to backward compatibility: requires
// binding + direct element
this._boundComplete(transport, this.element);
}
});
Object.extend(Ajax.InPlaceEditor.prototype, {
dispose: Ajax.InPlaceEditor.prototype.destroy
});
Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
initialize: function($super, element, url, options) {
this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
$super(element, url, options);
},
createEditField: function() {
var list = document.createElement('select');
list.name = this.options.paramName;
list.size = 1;
this._controls.editor = list;
this._collection = this.options.collection || [];
if (this.options.loadCollectionURL)
this.loadCollection();
else
this.checkForExternalText();
this._form.appendChild(this._controls.editor);
},
loadCollection: function() {
this._form.addClassName(this.options.loadingClassName);
this.showLoadingText(this.options.loadingCollectionText);
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
Object.extend(options, {
parameters: 'editorId=' + encodeURIComponent(this.element.id),
onComplete: Prototype.emptyFunction,
onSuccess: function(transport) {
var js = transport.responseText.strip();
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
throw 'Server returned an invalid collection representation.';
this._collection = eval(js);
this.checkForExternalText();
}.bind(this),
onFailure: this.onFailure
});
new Ajax.Request(this.options.loadCollectionURL, options);
},
showLoadingText: function(text) {
this._controls.editor.disabled = true;
var tempOption = this._controls.editor.firstChild;
if (!tempOption) {
tempOption = document.createElement('option');
tempOption.value = '';
this._controls.editor.appendChild(tempOption);
tempOption.selected = true;
}
tempOption.update((text || '').stripScripts().stripTags());
},
checkForExternalText: function() {
this._text = this.getText();
if (this.options.loadTextURL)
this.loadExternalText();
else
this.buildOptionList();
},
loadExternalText: function() {
this.showLoadingText(this.options.loadingText);
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
Object.extend(options, {
parameters: 'editorId=' + encodeURIComponent(this.element.id),
onComplete: Prototype.emptyFunction,
onSuccess: function(transport) {
this._text = transport.responseText.strip();
this.buildOptionList();
}.bind(this),
onFailure: this.onFailure
});
new Ajax.Request(this.options.loadTextURL, options);
},
buildOptionList: function() {
this._form.removeClassName(this.options.loadingClassName);
this._collection = this._collection.map(function(entry) {
return 2 === entry.length ? entry : [entry, entry].flatten();
});
var marker = ('value' in this.options) ? this.options.value : this._text;
var textFound = this._collection.any(function(entry) {
return entry[0] == marker;
}.bind(this));
this._controls.editor.update('');
var option;
this._collection.each(function(entry, index) {
option = document.createElement('option');
option.value = entry[0];
option.selected = textFound ? entry[0] == marker : 0 == index;
option.appendChild(document.createTextNode(entry[1]));
this._controls.editor.appendChild(option);
}.bind(this));
this._controls.editor.disabled = false;
Field.scrollFreeActivate(this._controls.editor);
}
});
//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
//**** This only exists for a while, in order to let ****
//**** users adapt to the new API. Read up on the new ****
//**** API and convert your code to it ASAP! ****
Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
if (!options) return;
function fallback(name, expr) {
if (name in options || expr === undefined) return;
options[name] = expr;
};
fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
options.cancelLink == options.cancelButton == false ? false : undefined)));
fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
options.okLink == options.okButton == false ? false : undefined)));
fallback('highlightColor', options.highlightcolor);
fallback('highlightEndColor', options.highlightendcolor);
};
Object.extend(Ajax.InPlaceEditor, {
DefaultOptions: {
ajaxOptions: { },
autoRows: 3, // Use when multi-line w/ rows == 1
cancelControl: 'link', // 'link'|'button'|false
cancelText: 'cancel',
clickToEditText: 'Click to edit',
externalControl: null, // id|elt
externalControlOnly: false,
fieldPostCreation: 'activate', // 'activate'|'focus'|false
formClassName: 'inplaceeditor-form',
formId: null, // id|elt
highlightColor: '#ffff99',
highlightEndColor: '#ffffff',
hoverClassName: '',
htmlResponse: true,
loadingClassName: 'inplaceeditor-loading',
loadingText: 'Loading...',
okControl: 'button', // 'link'|'button'|false
okText: 'ok',
paramName: 'value',
rows: 1, // If 1 and multi-line, uses autoRows
savingClassName: 'inplaceeditor-saving',
savingText: 'Saving...',
size: 0,
stripLoadedTextTags: false,
submitOnBlur: false,
textAfterControls: '',
textBeforeControls: '',
textBetweenControls: ''
},
DefaultCallbacks: {
callback: function(form) {
return Form.serialize(form);
},
onComplete: function(transport, element) {
// For backward compatibility, this one is bound to the IPE, and passes
// the element directly. It was too often customized, so we don't break it.
new Effect.Highlight(element, {
startcolor: this.options.highlightColor, keepBackgroundImage: true });
},
onEnterEditMode: null,
onEnterHover: function(ipe) {
ipe.element.style.backgroundColor = ipe.options.highlightColor;
if (ipe._effect)
ipe._effect.cancel();
},
onFailure: function(transport, ipe) {
alert('Error communication with the server: ' + transport.responseText.stripTags());
},
onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
onLeaveEditMode: null,
onLeaveHover: function(ipe) {
ipe._effect = new Effect.Highlight(ipe.element, {
startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
restorecolor: ipe._originalBackground, keepBackgroundImage: true
});
}
},
Listeners: {
click: 'enterEditMode',
keydown: 'checkForEscapeOrReturn',
mouseover: 'enterHover',
mouseout: 'leaveHover'
}
});
Ajax.InPlaceCollectionEditor.DefaultOptions = {
loadingCollectionText: 'Loading options...'
};
// Delayed observer, like Form.Element.Observer,
// but waits for delay after last key input
// Ideal for live-search fields
Form.Element.DelayedObserver = Class.create({
initialize: function(element, delay, callback) {
this.delay = delay || 0.5;
this.element = $(element);
this.callback = callback;
this.timer = null;
this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
delayedListener: function(event) {
if(this.lastValue == $F(this.element)) return;
if(this.timer) clearTimeout(this.timer);
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
this.lastValue = $F(this.element);
},
onTimerEvent: function() {
this.timer = null;
this.callback(this.element, $F(this.element));
}
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,487 +0,0 @@
/*
* API STYLES
*/
/* tag styles */
pre {
padding: 0;
}
code {
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", monospace;
font-size: 12px;
}
/* masthead */
div#masthead {
background: url(../images/header-stripe-small.png) repeat-x top left;
height: 76px;
}
div#masthead div#masthead_content {
margin: 0 auto;
width: 835px;
position: relative;
}
div#masthead h1#logo {
background: url(../images/header-logo-small.png) no-repeat 0 1px;
width: 118px;
height: 76px;
position: relative;
left: 60px;
}
/* footer */
div#footer {
width: 960px;
margin: 0 auto;
}
div.about {
margin-top: 20px;
padding-top: 20px;
width: 835px;
margin-left: 120px;
border-top: 1px solid #aaa;
color: #aaa;
}
div.about a,
div.about a:link {
color: #aaa;
text-decoration: underline;
border: 0;
}
div.copyright,
div.credits {
width: 360px;
float: left;
}
div.copyright .cc {
width: 115px;
margin-right: 5px;
text-align: center;
float: left;
}
div.copyright .copyright-about {
width: 235px;
float: left;
}
div.credits {
margin-left: 115px;
}
.page-title span.type {
display: block;
text-transform: uppercase;
font-size: 14px;
color: #aaa;
letter-spacing: 0;
}
h2.page-title {
margin-top: 0;
line-height: 100%;
}
ul.breadcrumbs {
margin-left: 120px;
}
ul.breadcrumbs li {
float: left;
list-style-type: none;
margin-right: 10px;
margin-left: 0;
}
ul.method-list {
margin-top: 0;
}
ul.method-list li {
margin-top: 0;
float: left;
margin-right: 5px;
margin-left: 0;
list-style-type: none;
}
ul.method-list li a,
ul.method-list li a:link {
text-decoration: none;
border: 0;
}
ul.method-details-list {
margin-top: 0;
}
ul.method-details-list li.method-description {
margin-top: 0;
margin-bottom: 3.0em;
margin-left: 0;
list-style-type: none;
}
ul.method-details-list li h4 {
margin: 0 0 0.6em;
line-height: 90%;
}
ul.method-details-list li pre {
margin-top: 0;
}
ul.method-details-list li pre code {
font-size: 13px;
}
ul.method-details-list li code {
font-size: 12px;
}
h4.inherited {
padding-top: 5px;
clear: left;
font-style: italic;
font-weight: bold;
font-size: 14px;
}
.method-description h4 .method-permalink a {
color: #aaa;
text-decoration: none;
border: 0;
font-size: 14px;
}
ul.argument-list {
margin-top: -5px;
list-style-type: disc;
margin-left: 20px;
}
ul.argument-list li {
list-style-type: disc;
font-size: 90%;
margin-bottom: 0;
}
ul.argument-list li code {
font-size: 11px;
}
ul.section-list {
margin-top: 0;
}
ul.section-list li {
margin-top: 0;
margin-left: 0;
list-style-type: none;
}
ul.section-list li h4 {
margin-top: 0;
}
/* Aliases */
.alias,
.related-to {
font-style: italic;
}
.alias code,
.related-to code {
font-style: normal;
}
/* Section icons */
.page-content .section .section-title h3 {
padding-right: 24px;
background-position: right 0;
background-repeat: no-repeat;
}
.section-constructor .section-title h3 {
background-image: url(../images/constructor.png);
}
.section-method-list .section-title h3 {
background-image: url(../images/method.png);
}
.section-klass_methods .section-title h3 {
background-image: url(../images/class_method.png);
}
.section-klass_properties .section-title h3 {
background-image: url(../images/class_property.png);
}
.section-instance_methods .section-title h3 {
background-image: url(../images/instance_method.png);
}
.section-instance_properties .section-title h3 {
background-image: url(../images/instance_property.png);
}
.section-mixins .section-title h3 {
background-image: url(../images/mixin.png);
}
.section-classes .section-title h3 {
background-image: url(../images/class.png);
}
.section-namespaces .section-title h3 {
background-image: url(../images/namespace.png);
}
.section-sections .section-title h3 {
background-image: url(../images/section.png);
}
.section-utilities .section-title h3 {
background-image: url(../images/utility.png);
}
.section-description .section-title h3 {
background-image: url(../images/description.png);
}
.section-subclasses .section-title h3 {
background-image: url(../images/subclass.png);
}
.section-superclass .section-title h3 {
background-image: url(../images/superclass.png);
}
/* search box */
.search-results {
position: absolute;
background-color: #fff;
height: 200px;
width: 233px;
overflow: auto;
overflow-y: scroll;
overflow-x: hidden;
margin: 7px -11px 0;
border: 1px solid #999;
top: 28px;
}
* html .search-results {
left: 486px;
top: 30px;
}
/* search result types */
.menu-item a,
.menu-item a:link {
display: block;
padding: 3px 10px 3px 28px;
background-position: 6px 50%;
background-repeat: no-repeat;
text-align: left;
text-decoration: none;
color: #333;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
white-space: nowrap;
}
.menu-item a:hover,
.menu-item a.highlighted,
#menu .highlighted a {
border-top: 1px solid #69f;
border-bottom: 1px solid #69f;
background-color: #f0f0ff;
}
.menu-item a.section {
font-weight: bold;
background-image: url(../images/section.png);
}
.menu-item a.class_method,
.menu-item a.instance_method {
background-image: url(../images/method.png);
}
.menu-item a.class {
background-image: url(../images/class.png);
}
.menu-item a.constructor {
background-image: url(../images/constructor.png);
}
.menu-item a.class_property {
background-image: url(../images/class_property.png);
}
.menu-item a.instance_property {
background-image: url(../images/instance_property.png);
}
.menu-item a.namespace {
background-image: url(../images/namespace.png);
}
.menu-item a.utility {
background-image: url(../images/utility.png);
}
/* halo around selected method */
.highlighter {
border: 3px solid #69f;
z-index: -1;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
}
/* MENU */
div#menu {
width: 960px;
margin: 0 auto;
position: relative;
}
#menu .api-box h2 a,
#menu .search-box {
width: 213px;
height: 25px;
line-height: 25px;
padding: 5px 10px;
margin-right: 5px;
text-align: center;
float: right;
}
* html #menu .api-box h2 a,
* html #menu .search-box {
height: 30px;
line-height: 30px;
}
#menu .api-box {
}
#menu .api-box h2 a {
font-size: 14px;
font-weight: normal;
font-family: Verdana, sans-serif;
display: block;
background-color: #cde0fb;
border: 1px solid #669;
border-top: 0;
text-decoration: none;
color: #222;
}
#menu .api-box .menu-items {
position: absolute;
background-color: #fff;
height: 200px;
width: 233px;
overflow: auto;
overflow-y: scroll;
overflow-x: hidden;
top: 35px;
border: 1px solid #999;
right: 5px;
}
* html #menu .api-box .menu-items {
right: 10px;
top: 37px;
}
#menu .api-box ul,
#menu .api-box li {
margin: 0;
padding: 0;
}
#menu .api-box .menu-item a {
}
#menu .search-box {
background-color: #cee8c3;
border: 1px solid #696;
border-top: 0;
}
#menu .search-box input {
width: 150px;
padding: 3px 10px;
margin-top: 2px;
border: 1px solid #999;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
}
#menu #search.ghosted {
color: #aaa;
text-align: left;
}
/* notes */
p.note,
p.alias,
p.related-to {
font-size: 11px;
line-height: 14px;
padding: 5px 5px 5px 60px;
background-repeat: no-repeat;
background-position: 20px 50%;
border: 1px solid #000;
}
p.note {
background-color: #f0f0f4;
background-image: url(../images/information.png);
border-color: #69c;
}
p.alias {
background-color: #fff6de;
background-image: url(../images/alias.png);
border-color: #cc9;
}
p.related-to {
background-color: #f4f0f4;
background-image: url(../images/related_to.png);
border-color: #c9c;
}

View File

@ -1,415 +0,0 @@
/* The "section" class implicitly needs a clearfix; adding it here for convenience. */
.clearfix:after,
.section:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix, .section {
display: inline-block;
}
html[xmlns] .clearfix,
html[xmlns] .section {
display: block;
}
* html .clearfix,
* html .section {
height: 1%;
}
span.replaced { visibility: hidden; }
span.hidden { display: none; }
body {
font-family: Verdana, sans-serif;
font-size: 82.5%;
line-height: 1.5em;
margin: 0;
padding: 0;
}
body * {
margin: 0;
padding: 0;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
}
h4 {
font-size: 17px;
color: #555;
margin: 1.0em 0 0.6em;
}
h5 {
font-size: 15px;
color: #2a2a2a;
margin: 1.0em 0 0.6em;
}
h6 {
font-size: 14px;
color: #000;
margin: 1.0em 0 0.6em;
}
a img {
border: 0;
}
ul, li {
list-style-type: none;
}
ol, ul {
margin: 0 0 15px;
}
#page a.img,
#page a.img:link,
#page a.img:visited {
border: none;
}
/* Link bar */
div#links {
margin: 0 auto;
width: 835px;
padding: 16px 0;
height: 16px;
overflow: hidden;
}
div#links_wrapper {
background: #fff;
}
div#links li {
display: inline;
}
div#links li a {
color: #666;
}
div#links li.selected a {
color: #000;
font-weight: bold;
text-decoration: none;
}
ul#internal_links {
float: left;
}
ul#internal_links li {
margin-right: 25px;
}
ul#external_links {
float: right;
}
ul#external_links li {
margin-left: 25px;
padding-left: 21px;
}
li#scripty_link {
background: url(http://prototype.conio.net/new/images/link-logo-scripty.png) no-repeat center left;
}
li#rails_link {
background: url(http://prototype.conio.net/new/images/link-logo-rails.png) no-repeat center left;
}
p a, p a:link,
h1 a, h1 a:link,
h2 a, h2 a:link,
h3 a, h3 a:link,
h4 a, h4 a:link,
h5 a, h5 a:link,
h6 a, h6 a:link {
color: #036;
border-bottom: 1px solid #036;
text-decoration: none;
}
p a:visited {
border-bottom: 1px solid #666;
}
code {
font-family: "Panic Sans", "Bitstream Vera Sans Mono", Monaco, Consolas, Andale Mono, monospace;
font-size: 13px;
}
p code,
li code {
background-color: #f0f0f0;
border: 1px solid #ccc;
border-radius: 3px;
-webkit-border-radius: 3px;
padding: 0 3px;
}
pre code {
background-color: transparent;
border: 0;
padding: 0;
}
#page {
margin: 0 auto;
padding-bottom: 100px; /* FIXME: Temporary as pages are built */
}
/* top */
.related-links {
width: 835px;
font-size: 0.9em;
margin: 0 auto 10px;
padding: 10px 0 0;
}
.related-links a {
color: #000;
text-decoration: none;
}
.related-links ul {
list-style-type: none;
}
.related-links ul.internal {
float: left;
width: 355px;
}
.related-links ul.internal li {
text-align: center;
}
.related-links ul.external {
float: right;
width: 295px;
}
.related-links li {
float: left;
padding: 0 15px;
width: 85px;
margin-right: 5px;
}
.related-links li.last {
margin-right: 0;
}
.related-links ul.external li.scripty {
padding: 0 8px 0 22px;
background: url(../images/icon-scripty.png) no-repeat;
margin-right: 65px;
}
.related-links ul.external li.rails {
padding: 0 8px 0 22px;
background: url(../images/icon-rails.png) no-repeat;
}
.banner {
height: 152px;
padding: 1px 0;
background: url(../images/header-stripe.png) repeat-x;
}
.banner-content {
width: 835px;
margin: 0 auto;
}
.banner h1 {
width: 236px;
height: 150px;
background: url(../images/header-logo.png) no-repeat;
}
.banner h1 span {
display: none;
}
.banner-small {
height: 75px;
padding: 1px 0;
background: url(../images/header-stripe-small.png) repeat-x;
}
.banner-small h1 {
width: 118px;
height: 75px;
background: url(../images/header-logo-small.png) no-repeat;
margin-left: 60px;
}
.banner-small h1 span {
display: none;
}
/* PAGE CONTENT */
.page-content {
width: 955px;
margin: 30px auto 0;
}
.page-content .page-title {
margin-left: 120px;
margin-bottom: 15px;
font-size: 27px;
letter-spacing: -1px;
color: #444;
}
.page-content .page-introduction {
margin-left: 120px;
margin-bottom: 25px;
}
.page-content .section {
width: 955px;
margin: 10px 0 20px;
}
.page-content .section .section-title {
width: 110px;
margin-right: 10px;
padding-right: 0;
float: left;
text-align: right;
overflow: hidden;
}
.page-content .section .section-title h3 {
color: #999;
font-size: 14px;
line-height: 110%;
padding-right: 10px;
padding-bottom: 5px;
}
.page-content .section .section-content {
width: 835px;
float: left;
}
.page-content a,
.page-content a:link {
color: #036;
border-bottom: 1px solid #036;
text-decoration: none;
}
.page-content a:visited {
border-bottom: 1px solid #bbb;
}
.page-content ul,
.page-content ol {
margin: 10px 0;
}
.page-content li {
margin: 5px 0 8px 20px;
list-style-type: disc;
}
.page-content p {
margin: 0 0 0.8em;
}
.page-content pre {
color: #333;
background-color: #f0f0ff;
border: 1px solid #dde;
padding: 3px 5px;
margin: 0 0 1em;
}
.page-content .two-column {
}
.page-content .two-column-left,
.page-content .two-column-right {
width: 475px;
margin-right: 5px;
float: left;
}
.page-content .two-column-right {
margin-right: 0;
}
.page-content .two-column .section {
width: 475px;
}
.page-content .two-column .section-content {
width: 345px;
padding-right: 10px;
}
.smallcaps {
font-size: 0.85em;
text-transform: uppercase;
letter-spacing: 1px;
}
/* MASTHEAD */
div#masthead {
margin-top: 50px;
background: url(../images/header-stripe-small.png) repeat-x top left;
height: 76px;
}
div#masthead div#masthead_content {
margin: 0 auto;
width: 835px;
position: relative;
}
div#masthead h1#logo {
background: url(../images/header-logo-small.png) no-repeat 0 1px;
width: 118px;
height: 76px;
position: relative;
left: 60px;
}
div#masthead a {
text-decoration: none;
}

View File

@ -1,13 +0,0 @@
body.grid {
width: 955px;
margin: auto;
}
body.grid div#page {
overflow: hidden;
background: url(../images/grid.png);
}
body.grid div#page * {
opacity: .9;
}

View File

@ -1,116 +0,0 @@
/* See license.txt for terms of usage */
.firebugHighlight {
z-index: 2147483647;
position: absolute;
background-color: #3875d7;
}
.firebugLayoutBoxParent {
z-index: 2147483647;
position: absolute;
border-right: 1px dashed #BBBBBB;
border-bottom: 1px dashed #BBBBBB;
}
.firebugRulerH {
position: absolute;
top: -15px;
left: 0;
width: 100%;
height: 14px;
background: url(chrome://firebug/skin/rulerH.png) repeat-x;
border-top: 1px solid #BBBBBB;
border-right: 1px dashed #BBBBBB;
border-bottom: 1px solid #000000;
}
.firebugRulerV {
position: absolute;
top: 0;
left: -15px;
width: 14px;
height: 100%;
background: url(chrome://firebug/skin/rulerV.png) repeat-y;
border-left: 1px solid #BBBBBB;
border-right: 1px solid #000000;
border-bottom: 1px dashed #BBBBBB;
}
.overflowRulerX > .firebugRulerV {
left: 0;
}
.overflowRulerY > .firebugRulerH {
top: 0;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.firebugLayoutBoxOffset {
z-index: 2147483647;
position: absolute;
opacity: 0.8;
}
.firebugLayoutBoxMargin {
background-color: #EDFF64;
}
.firebugLayoutBoxBorder {
background-color: #666666;
}
.firebugLayoutBoxPadding {
background-color: SlateBlue;
}
.firebugLayoutBoxContent {
background-color: SkyBlue;
}
/*.firebugHighlightGroup .firebugLayoutBox {
background-color: transparent;
}
.firebugHighlightBox {
background-color: Blue !important;
}*/
.firebugLayoutLine {
z-index: 2147483647;
background-color: #000000;
opacity: 0.4;
}
.firebugLayoutLineLeft,
.firebugLayoutLineRight {
position: fixed;
width: 1px;
height: 100%;
}
.firebugLayoutLineTop,
.firebugLayoutLineBottom {
position: absolute;
width: 100%;
height: 1px;
}
.firebugLayoutLineTop {
margin-top: -1px;
border-top: 1px solid #999999;
}
.firebugLayoutLineRight {
border-right: 1px solid #999999;
}
.firebugLayoutLineBottom {
border-bottom: 1px solid #999999;
}
.firebugLayoutLineLeft {
margin-left: -1px;
border-left: 1px solid #999999;
}

View File

@ -1,443 +0,0 @@
/* @group Tags */
body {
font-family: Verdana, sans-serif;
}
form {
margin: 0;
padding: 0;
}
a {
color: #036;
text-decoration: none;
}
p a {
border-bottom: 1px solid #999;
padding: 0 1px;
}
p a:hover {
background-color: #036;
color: #fff;
border-bottom: 1px solid #036;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 0;
padding: 0;
}
pre {
padding: 0;
}
code {
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", monospace;
font-size: 11px;
}
/* @end */
/* @group Masthead */
div#masthead {
background: url(../images/header-stripe-small.png) repeat-x top left;
height: 76px;
}
div#masthead div#masthead_content {
margin: 0 auto;
width: 835px;
position: relative;
}
div#masthead h1#logo {
background: url(../images/header-logo-small.png) no-repeat 0 1px;
width: 118px;
height: 76px;
position: relative;
left: 60px;
}
/* @end */
/* @group Main */
#main {
width: 840px;
margin: 20px auto;
position: relative;
}
#main h2 {
color: #444;
font-size: 22px;
padding-left: 69px;
margin-top: 0;
}
#main h2 span {
color: #ccc;
display: block;
text-transform: uppercase;
font-size: 13px;
margin-bottom: -10px;
padding-left: 2px;
}
#main h2 a {
color: #444;
text-decoration: none;
}
#main h2 a:hover {
color: #222;
border-bottom: 1px solid #999;
}
#main h4, h5, h6 {
padding-left: 4px;
}
#main li h4,
#main li h5,
#main li h6 {
padding-left: 0;
}
#main h4.inherited {
color: #888 !important;
}
#main .section {
overflow: hidden;
padding-left: 65px;
padding-bottom: 0;
margin: 5px 0 0;
}
#main .section h3 {
position: absolute;
left: -85px;
width: 110px;
text-align: right;
font-size: 13px;
padding-top: 3px;
color: #999;
line-height: 100%;
min-height: 30px;
}
#main .section h4 {
font-size: 15px;
color: #444;
margin: 0 0 0.3em;
}
#main .section h4.inherited {
color: #888;
}
#main .section h4.inherited a {
color: #49B;
}
#main p {
margin: 0 0 1.1em;
}
#main pre {
background-color: #000;
color: #fff;
padding: 5px 10px;
margin: 0 0 5px;
}
#main pre.syntax {
background-color: #f5f5f5;
color: #000;
padding: 3px 5px;
}
#main .section p.purpose {
background-color: #CDE0FB;
padding: 3px 5px;
}
#main .section p {
padding: 0 5px;
}
#main ul, #main ol {
padding-left: 5px;
margin: 0 0 10px;
}
#main ul, #main ul li {
list-style-type: none;
}
#main #excerpt p {
color: #000;
border-left: 3px solid #bbb;
padding: 0;
margin-left: -10px;
font-size: 94%;
padding-left: 10px;
}
#main .meta {
position: absolute;
width: 108px;
left: -60px;
text-align: right;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: bold;
color: #888;
}
/* @end */
/* @group Method List */
ul.method-list li {
display: inline;
border-top: 1px solid #ccc;
}
ul.method-list li a {
background-color: #eee;
padding: 2px 3px;
border: 1px solid #ccc;
}
ul.method-list li a:hover {
background-color: #ddd;
}
/* @end */
/* @group Menu */
#menu {
width: 840px;
margin: 0 auto;
position: relative;
height: 25px;
}
#menu div {
width: 234px;
float: right;
margin: 0 3px;
}
#menu div.search-box {
width: 222px;
background-color: #cee8c3;
font-size: 13px;
height: 25px;
line-height: 25px;
padding: 2px 6px;
}
#menu div.search-box label {
color: #555;
}
#menu div.search-box input {
border: 1px solid #bbb;
padding: 2px;
width: 163px;
}
#menu h2 {
font-size: 13px;
font-weight: normal;
}
#menu h2 a {
height: 25px;
line-height: 25px;
display: block;
text-align: center;
background-color: #CDE0FB;
font-family: Verdana, sans-serif;
padding: 2px 6px;
}
#menu h2 a:hover {
background-color: #a4c8fb;
}
#menu #api_menu,
#menu #search_results {
border: 1px solid #ddd;
background: #fff;
position: absolute;
width: 232px;
top: 26px;
z-index: 1500;
max-height: 200px;
overflow: auto;
}
#menu #api_menu {
right: 3px;
}
#menu #search_results {
right: 243px;
}
#menu .menu-items li {
background-color: #fff;
}
#menu .menu-items li a {
display: block;
color: #333;
background-color: #fff;
padding: 2px 6px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
}
#menu .menu-items li a:hover,
#menu .menu-items li.highlighted a {
background-color: #CDE0FB;
border-top-color: #a4c8fb;
border-bottom-color: #a4c8fb;
}
#menu .menu-items ul {
margin: 0;
padding: 0;
}
#menu .menu-items li a {
background-repeat: no-repeat;
background-position: 6px 3px;
padding: 3px 5px 3px 30px;
font-size: 12px;
}
#menu .menu-items li a.class {
background-image: url(../images/class.png);
}
#menu .menu-items li a.namespace {
background-image: url(../images/namespace.png);
}
#menu .menu-items li a.mixin {
background-image: url(../images/mixin.png);
}
#menu .menu-items li a.section {
text-transform: uppercase;
color: #777;
background-image: url(../images/section.png);
}
#menu .menu-items li a.class_method,
#menu .menu-items li a.instance_method,
#menu .menu-items li a.utility {
background-image: url(../images/method.png);
}
#menu .menu-items li a.class_property,
#menu .menu-items li a.instance_property {
background-image: url(../images/property.png);
}
#menu .menu-items li a.constructor {
background-image: url(../images/constructor.png);
}
#menu .menu-items li a.constant {
background-image: url(../images/constant.png);
}
/* @end */
/* @group Section Headings (H3s) */
.section h3 {
padding-right: 25px;
background-repeat: no-repeat;
background-position: right 4px;
}
.section-superclass h3 {
background-image: url(../images/class.png);
}
.section-method-list h3,
.section-instance_methods h3,
.section-klass_methods h3 {
background-image: url(../images/method.png);
}
.section-klass_properties h3,
.section-instance_properties h3 {
background-image: url(../images/property.png);
}
.section-constructor h3 {
background-image: url(../images/constructor.png);
}
.section-constants h3 {
background-image: url(../images/constant.png);
}
.section-mixins h3 {
background-image: url(../images/mixin.png);
}
/* @end */
/* @group Method Details List */
ul.method-details-list li {
border: 2px solid #fff;
}
ul.method-details-list li.highlighted {
border: 2px solid #CDE0FB;
}
/* @end */
/* floating menu */
#menu.fixed {
position: fixed;
top: 0;
z-index: 1000;
left: 232px;
}

View File

@ -1,244 +0,0 @@
/* Masthead */
div#masthead {
background: url(http://prototype.conio.net/new/images/header-stripe.png) repeat-x top left;
height: 152px;
}
div#masthead div#masthead_content {
margin: 0 auto;
width: 835px;
position: relative;
}
div#masthead h1#logo {
background: url(http://prototype.conio.net/new/images/header-logo.png) no-repeat 0 1px;
width: 236px;
height: 152px;
}
div#masthead div#pitch {
position: absolute;
background: url(http://prototype.conio.net/new/images/header-copy.png) no-repeat 0 1px;
top: 0;
left: 300px;
width: 535px;
height: 152px;
}
div#masthead h1#logo *,
div#masthead div#pitch * {
display: none;
}
/* Buttons */
div#buttons, div#more {
overflow: hidden;
width: 840px;
margin: -1px auto 0 auto;
padding: 0 0 0 5px;
}
div#more {
margin-top: 35px;
}
div#buttons li {
display: block;
float: left;
border-top: 1px solid #929fb3;
margin: 0 5px 0 0;
width: 175px;
height: 100px;
}
div#more li {
height: 50px;
}
div#buttons li a {
display: block;
position: relative;
width: 175px;
height: 100px;
text-decoration: none;
background: #cde0fb no-repeat center 30px;
}
div#buttons li a:hover {
background-color: #a4c8fb;
}
div#buttons li a span.title {
display: none;
}
div#buttons li a span.description {
position: absolute;
display: block;
width: 175px;
top: 55px;
text-align: center;
color: #666;
}
div#more li a span.title {
position: absolute;
display: block;
width: 175px;
top: 15px;
text-align: center;
color: #666;
}
div#buttons li a:hover span.description {
color: #333;
}
div#buttons li#download_button {
width: 295px;
}
div#buttons li#download_button a,
div#buttons li#download_button a span.description {
width: 295px;
}
div#buttons li#download_button a {
background-color: #cee8c3;
background-image: url(http://prototype.conio.net/new/images/button-download.png);
}
div#buttons li#download_button a:hover {
background-color: #a4e289;
}
div#buttons li#learn_button a {
background-image: url(http://prototype.conio.net/new/images/button-learn.png);
}
div#buttons li#discuss_button a {
background-image: url(http://prototype.conio.net/new/images/button-discuss.png);
}
div#buttons li#contribute_button a {
background-image: url(http://prototype.conio.net/new/images/button-contribute.png);
}
div#more {
position: relative;
height: 400px;
margin: 15px 60px;
color: #444;
}
div#more .column {
display: block;
float: left;
margin: 0 5px 0 0;
padding-left: 5px;
min-height: 300px;
}
div#more h3 {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
letter-spacing: -1px;
font-weight: bold;
color: #444;
font-size: 18px;
margin: 0 0 5px;
}
.column {
width: 175px;
}
.wide-column {
width: 295px;
}
.medium-column {
width: 235px;
}
.main-column {
width: 530px;
}
.sidebar-column {
width: 290px;
}
div#more {
width: 840px;
margin: 25px auto 0;
}
/*#buttons_wrapper {
background-color: #0E4FAF;
}
#page {
background-color: #292929;
}
*/
div#more div.main-column p {
font-size: 16px;
margin-right: 10px;
}
div#more h3.tagline {
height: 23px;
background: url(../images/tagline.png) no-repeat top left;
width: 530px;
}
div#more h3.tagline span { display: none; }
.view-master {
text-align: center;
font-family: Verdana;
color: #ccc;
font-size: 18px;
padding: 35px 0;
margin: 10px 0;
}
.using-prototype {
border-top: 2px solid #ddd;
border-bottom: 2px solid #ddd;
margin: 25px 10px 10px 0;
padding: 5px 0;
}
.sidebar-column h4 {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: bold;
margin: 0;
}
.sidebar-column p {
margin-bottom: 15px;
}
ol, ol li {
list-style-type: decimal;
line-height: 160%;
}
ol li {
margin: 0 0 2px;
}
ol, ul {
margin: 0 0 15px;
padding-left: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

View File

@ -1,19 +0,0 @@
module PDoc
module Generators
module Html
module Helpers
module BaseHelper
end
module LinkHelper
end
module CodeHelper
end
module MenuHelper
end
end
end
end
end

View File

@ -1,24 +0,0 @@
<% @title = "Home" %>
<div class="page-introduction">
<%= @index_page_content %>
</div> <!-- .section -->
<div class="section section-sections">
<div class="section-title">
<h3>Sections</h3>
</div> <!-- .section-title -->
<div class="section-content">
<ul class="section-list">
<% @root.sections.each do |section| %>
<li>
<h4>
<a href="<%= path_to_section(section) %>"><%= section.name %></a>
</h4>
<p><%= htmlize(section.short_description) %></p>
</li>
<% end %>
</ul>
</div> <!-- .section-content -->
</div> <!-- .section clearfix -->

View File

@ -1,6 +0,0 @@
if (!window.PDoc) window.PDoc = {};
PDoc.elements = {
<%= @root.map { |e, i|
"'#{e.full_name}': { 'name': '#{e.full_name}', 'type': '#{e.type}', 'path': '#{path_to(e)}' }" }.join(",\n")
%>
};

View File

@ -1,79 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Prototype API documentation | <%= @title %></title>
<meta name="generator" content="PDoc" />
<%= javascript_include_tag "prototype", "effects", "controls" %>
<%= javascript_include_tag "application", "code_highlighter" %>
<%= javascript_include_tag "item_index" %>
<%= stylesheet_link_tag "core", "api" %>
<script type="text/javascript">PDoc.pathPrefix = '<%= path_prefix %>';</script>
</head>
<body class="">
<div id="page">
<div id="masthead">
<div id="masthead_content">
<a href="http://prototypejs.org">
<h1 id="logo"><span class="replaced">Prototype JavaScript framework</span></h1>
</a>
</div> <!-- #masthead_content -->
</div> <!-- #masthead -->
<div id="menu" class="clearfix">
<div class="api-box">
<h2><a href="#" id="api_menu_button">Menu &darr;</a></h2>
<ul id="api_menu" class="menu-items" style="display: none">
<% @root.sections.each do |section| %>
<%= menu(section) %>
<% end %>
</ul>
</div> <!-- .api-box -->
<div class="search-box">
<form>
<label><span class="hidden">Search </span><input type="text" id="search" size="20" /></label>
</form>
<ul id="search_results" class="search-results menu-items" style="display:none"></ul>
</div> <!-- .search-box -->
</div> <!-- #menu -->
<div id="main" class="page-content">
<%= @content_for_layout %>
</div> <!-- #main -->
<div id="footer">
<div class="about clearfix">
<div class="copyright clearfix">
<div class="cc">
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://creativecommons.org/images/public/somerights20.png" /></a>
</div> <!-- .cc -->
<div class="copyright-about">
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0 Unported License</a>.
</div> <!-- .copyright-about -->
</div> <!-- .copyright -->
<div class="credits">
<p>Generated by <a href="http://pdoc.org">PDoc</a>. Uses <a href="http://famfamfam.com/lab/icons/silk/" title="famfamfam.com: Silk Icons">Silk Icons</a>.</p>
</div> <!-- .credits -->
</div> <!-- .about -->
</div> <!-- #footer -->
</div> <!-- #page -->
</body>
</html>

View File

@ -1,171 +0,0 @@
<% d = @doc_instance %>
<% @title = "#{d.full_name} #{d.type}" %>
<%= include "partials/breadcrumbs", :object => d %>
<h2 class="page-title <%= class_names_for(d) %>">
<span class="type"><%= d.type %> </span><%= d.full_name %>
</h2>
<% # Does it have a description? %>
<% if d.description && !d.description.empty? %>
<div class="section section-description">
<div class="section-title">
<h3>Description</h3>
</div> <!-- .section-title -->
<div class="section-content">
<%= htmlize(d.description) %>
</div> <!-- .section-content -->
</div> <!--.section -->
<% end %>
<% # Is it a CLASS? %>
<% if d.is_a?(Documentation::Klass) %>
<% if d.superklass %>
<div class="section section-superclass">
<div class="section-title">
<h3>Superclass</h3>
</div> <!-- .section-title -->
<div class="section-content">
<p><%= auto_link_code(d.superklass, false) %></p>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% unless d.subklasses.empty? %>
<div class="section section-subclasses">
<div class="section-title">
<h3>Subclasses</h3>
</div> <!-- .section-title -->
<div class="section-content">
<p><%= d.subklasses.map { |s| auto_link_code(s, false) }.join(', ') %></p>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% end %>
<% # Does it have MIXINS? %>
<% unless d.mixins.compact.empty? %>
<div class="section section-mixins">
<div class="section-title">
<h3>Includes</h3>
</div> <!-- .section-title -->
<div class="section-content">
<p><%= d.mixins.map { |m| auto_link_code(m, false) }.join(', ') %></p>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% # Are there related utilities? %>
<% unless d.related_utilities.empty? %>
<div class="section section-utilities">
<div class="section-title">
<h3>Related utilities</h3>
</div> <!-- .section-title -->
<div class="section-content">
<p><%= d.related_utilities.map { |u| auto_link_code(u, false) }.join(', ') %></p>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% # List its methods. %>
<% unless d.all_methods.empty? && d.mixins.empty? %>
<div class="section section-method-list">
<div class="section-title">
<h3>Methods</h3>
</div> <!-- .section-title -->
<div class="section-content">
<ul class="method-list">
<% d.all_methods.each do |method| %>
<li><%= auto_link_code(method, true, :class => class_names_for(method)) %></li>
<% end %>
</ul>
<% unless d.mixins.compact.empty? %>
<% d.mixins.each do |mixin| %>
<h4 class="inherited">Inherited from <%= auto_link(mixin) %></h4>
<ul class="method-list">
<% mixin.all_methods.each do |method| %>
<li><%= auto_link_code(method, true, :class => class_names_for(method)) %></li>
<% end %>
</ul>
<% end %>
<% end %>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% if d.is_a?(Documentation::Klass) && d.constructor %>
<div class="section section-constructor">
<div class="section-title">
<h3>Constructor</h3>
</div> <!-- .section-title -->
<div class="section-content">
<pre id="<%= dom_id(d.constructor) %>" class="syntax"><code><%= d.constructor.ebnf_expressions.join("\n").strip %></code></pre>
<% unless d.constructor.arguments.empty? %>
<ul class="argument-list">
<% d.constructor.arguments.each do |arg| %>
<li>
<code><%= arg.name %></code>
<% unless arg.types.empty? %>
(<%= arg.types.map { |t| auto_link_code(t, false) }.join(' | ') %>)
<% end %>
<%= ' &ndash; ' + inline_htmlize(arg.description) unless arg.description.empty? %>
</li>
<% end %>
</ul> <!-- .argument-list -->
<% end %>
<p><%= htmlize(d.constructor.description) %></p>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<%
types = {
:constants => "Constants",
:klass_methods => "Class methods",
:klass_properties => "Class properties",
:instance_methods => "Instance methods",
:instance_properties => "Instance properties"
}
%>
<% types.each do |method, title| %>
<% methods = d.send(method) %>
<% unless methods.empty? %>
<div class="section section-<%= method.to_s %>">
<div class="section-title">
<h3><%= title %></h3>
</div> <!-- .section-title -->
<div class="section-content">
<ul class="method-details-list">
<%= include "partials/short_description", :collection => methods %>
</ul>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% end %>

View File

@ -1,6 +0,0 @@
<ul class="breadcrumbs clearfix">
<li><a href="<%= path_prefix %>index.html">Home</a> &rarr;</li>
<% unless object.is_a?(Documentation::Section) %>
<li><a href="<%= path_to(object.section) %>"><%= object.section.name %></a> &rarr;</li>
<% end %>
</ul>

View File

@ -1,48 +0,0 @@
<li class="method-description">
<h4 id="<%= dom_id(object) %>"><%= object.name %>
<span class="method-permalink"><a href="<%= path_to(object) %>">#</a></span></h4>
<% if object.signature %>
<%= method_synopsis(object) %>
<% end %>
<% if object.is_a?(Documentation::Method) %>
<% unless object.arguments.empty? %>
<ul class="argument-list">
<% object.arguments.each do |arg| %>
<li>
<code><%= arg.name %></code>
<% unless arg.types.empty? %>
(<%= arg.types.map { |t| auto_link_code(t, false) }.join(' | ') %>)
<% end %>
<%= ' &ndash; ' + inline_htmlize(arg.description) unless arg.description.empty? %>
</li>
<% end %>
</ul> <!-- .argument-list -->
<% end %>
<% end %>
<%= htmlize(object.description) %>
<% # Does it have an alias? %>
<% unless object.aliases.empty? %>
<p class="alias aliases">Aliased as: <%= object.aliases.map { |a| auto_link_code(a, false) }.join(', ') %></p>
<% end %>
<% # Is it an alias of something else? %>
<% if object.alias? %>
<p class="alias alias-of">Alias of: <%= auto_link_code(object.alias_of, false) %></p>
<% end %>
<% # Is it related to something? %>
<% if object.is_a?(Documentation::Utility) && object.related_to %>
<p class="related-to">Related to:
<%= auto_link_code(object.related_to, false) %></p>
<% end %>
<% # Is it methodized? %>
<% if object.is_a?(Documentation::Method) && object.methodized? %>
<p class="note">This method can be called <em>either</em> as an instance method <em>or</em> as a generic method. If calling as a generic, pass the instance in as the first argument.</p>
<% end %>
</li>

View File

@ -1,99 +0,0 @@
<% @title = "#{@doc_instance.full_name}" %>
<% section = @doc_instance %>
<%= include "partials/breadcrumbs", :object => section %>
<h2 class="page-title">
<span class="type">Section </span><%= section.name %>
</h2>
<div class="section section-description">
<div class="section-title">
<h3>Description</h3>
</div> <!-- .section-title -->
<div class="section-content">
<%= htmlize(section.description) %>
</div> <!-- .section-content -->
</div> <!--.section -->
<% # Iterate over the items in this section. %>
<% utilities = section.utilities %>
<% unless utilities.empty? %>
<div class="section section-utilities">
<div class="section-title">
<h3>Utilities</h3>
</div> <!-- .section-title -->
<div class="section-content">
<ul class="method-list">
<% utilities.each do |utility| %>
<li><%= auto_link_code(utility) %></li>
<% end %>
</ul>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% namespaces = section.namespaces %>
<% unless namespaces.empty? %>
<div class="section section-namespaces">
<div class="section-title">
<h3>Namespaces</h3>
</div> <!-- .section-title -->
<div class="section-content">
<ul class="method-details-list">
<% namespaces.each do |namespace| %>
<li class="method-description">
<h4>
<a href="<%= path_to(namespace) %>"><%= namespace.full_name %></a>
</h4>
<% unless namespace.short_description.nil? %>
<p><%= htmlize(namespace.short_description) %></p>
<% end %>
</li>
<% end %>
</ul>
</div> <!-- .section-content -->
</div> <!-- .section -->
<% end %>
<% klasses = section.klasses %>
<% unless klasses.empty? %>
<div class="section section-classes">
<div class="section-title">
<h3>Classes</h3>
</div> <!-- .section-title -->
<div class="section-content">
<ul class="method-details-list">
<% klasses.each do |klass| %>
<li class="method-description">
<h4>
<a href="<%= path_to(klass) %>"><%= klass.full_name %></a>
</h4>
<% unless klass.short_description.nil? %>
<p><%= htmlize(klass.short_description) %></p>
<% end %>
</li>
<% end %>
</ul>
</div> <!-- .section-content -->
</div> <!--.section -->
<% end %>

View File

@ -1,21 +0,0 @@
<% d = @doc_instance %>
<% @title = "#{@doc_instance.full_name} utility" %>
<%= include "partials/breadcrumbs", :object => d %>
<h2 class="page-title">
<span class="type">utility </span><%= @doc_instance.name %>
</h2>
<div class="section">
<div class="section-title">
<h3>Description</h3>
</div> <!-- .section-title -->
<div class="section-content">
<ul class="method-details-list">
<%= include "partials/short_description", :collection => [@doc_instance] %>
</ul>
</div> <!-- .section-content -->
</div> <!-- .section -->

View File

@ -951,6 +951,9 @@ new Test.Unit.Runner({
// height/width could always be calculated if it's set to "auto" (Firefox)
this.assertNotNull($('auto_dimensions').getStyle('height'));
this.assertNotNull($('auto_dimensions').getStyle('width'));
// assert that using getStyle on an object without a style property returns null
this.assertNull(Element.Methods.getStyle({}, 'width'));
},
testElementGetOpacity: function() {
@ -1322,6 +1325,10 @@ new Test.Unit.Runner({
this.assertEnumEqual([0,0], offset);
this.assertIdentical(0, offset.top);
this.assertIdentical(0, offset.left);
var innerEl = new Element('div'), outerEl = new Element('div');
outerEl.appendChild(innerEl);
this.assertEnumEqual([0,0], innerEl.cumulativeOffset());
},
testViewportOffset: function() {

View File

@ -184,6 +184,8 @@ new Test.Unit.Runner({
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.stopObserving("test:somethingHappened"));
this.assertEqual(span, span.stopObserving("test:somethingOtherHappened", observer));
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.stopObserving());
this.assertEqual(span, span.stopObserving()); // assert it again, after there are no observers

View File

@ -41,13 +41,10 @@ new Test.Unit.Runner({
this.assertEqual(false, Prototype.Selector.match(element, '.non_existent'));
},
testFilter: function() {
testFind: function() {
var elements = document.getElementsByTagName('*'),
filtered = Prototype.Selector.filter(elements, '.test_class');
this.assert(Object.isArray(filtered));
this.assertEqual(2, filtered.length);
this.assertEqual('test_div_parent', filtered[0].id);
this.assertEqual('test_div_child', filtered[1].id);
expression = '.test_class';
this.assertEqual('test_div_parent', Prototype.Selector.find(elements, expression).id);
this.assertEqual('test_div_child', Prototype.Selector.find(elements, expression, 1).id);
}
});

View File

@ -6,22 +6,10 @@ Prototype.Selector = (function(engine) {
return engine.select(selector, scope || document, null, Element.extend);
}
function filter(elements, selector) {
var results = [], element, i = 0;
while (element = elements[i++]) {
if (engine.match(element, selector)) {
Element.extend(element);
results.push(element);
}
}
return results;
}
return {
engine: engine,
select: select,
match: engine.match,
filter: filter
match: engine.match
};
})(NW.Dom);

2
vendor/pdoc vendored

@ -1 +1 @@
Subproject commit 147250bd65eed627e32ca5a70b57fe4f7803ab4b
Subproject commit 472a55dd0019acf034d4f72522915a5e9efd0a1a