Compare commits

..

No commits in common. "master" and "sizzle" have entirely different histories.

80 changed files with 9975 additions and 2974 deletions

8
.gitmodules vendored
View File

@ -11,10 +11,6 @@
path = vendor/sprockets
url = git://github.com/sstephenson/sprockets.git
[submodule "vendor/nwmatcher/repository"]
path = vendor/nwmatcher/repository
url = git://github.com/dperini/nwmatcher.git
[submodule "vendor/sizzle/repository"]
path = vendor/sizzle/repository
[submodule "vendor/sizzle"]
path = vendor/sizzle
url = git://github.com/jeresig/sizzle.git

View File

@ -1,21 +1,3 @@
* 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

@ -9,13 +9,13 @@ module PrototypeHelper
DOC_DIR = File.join(ROOT_DIR, 'doc')
TEMPLATES_DIR = File.join(ROOT_DIR, 'templates')
PKG_DIR = File.join(ROOT_DIR, 'pkg')
SIZZLE_DIR = File.join(ROOT_DIR, 'vendor', 'sizzle')
TEST_DIR = File.join(ROOT_DIR, 'test')
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|
%w[sprockets pdoc unittest_js caja_builder sizzle].each do |name|
$:.unshift File.join(PrototypeHelper::ROOT_DIR, 'vendor', name, 'lib')
end
@ -37,48 +37,31 @@ module PrototypeHelper
exit
end
def self.sprocketize(options = {})
options = {
:destination => File.join(DIST_DIR, options[:source]),
:strip_comments => true
}.merge(options)
def self.sprocketize(path, source, destination = nil, strip_comments = true)
require_sprockets
load_path = [SRC_DIR]
if selector_path = get_selector_engine(options[:selector_engine])
load_path << selector_path
end
require_sizzle
secretary = Sprockets::Secretary.new(
:root => File.join(ROOT_DIR, options[:path]),
:load_path => load_path,
:source_files => [options[:source]],
:strip_comments => options[:strip_comments]
:root => File.join(ROOT_DIR, path),
:load_path => [SRC_DIR, SIZZLE_DIR],
:source_files => [source],
:strip_comments => strip_comments
)
secretary.concatenation.save_to(options[:destination])
destination = File.join(DIST_DIR, source) unless destination
secretary.concatenation.save_to(destination)
end
def self.build_doc_for(file)
mkdir_p TMP_DIR
temp_path = File.join(TMP_DIR, "prototype.temp.js")
sprocketize(
:path => 'src',
:source => file,
:destination => temp_path,
:selector_engine => ENV['SELECTOR_ENGINE'] || DEFAULT_SELECTOR_ENGINE,
:strip_comments => false
)
sprocketize('src', file, temp_path, false)
rm_rf DOC_DIR
PDoc.run({
:source_files => [temp_path],
:destination => DOC_DIR,
:index_page => 'README.markdown',
:syntax_highlighter => :pygments,
:markdown_parser => :bluecloth
})
PDoc::Runner.new(temp_path, {
:output => DOC_DIR,
:templates => File.join(TEMPLATES_DIR, "html"),
:index_page => 'README.markdown'
}).run
rm_rf temp_path
end
@ -99,15 +82,9 @@ module PrototypeHelper
require_submodule('CajaBuilder', 'caja_builder')
end
def self.get_selector_engine(name)
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
def self.require_sizzle
if !File.exists?(File.join(SIZZLE_DIR, 'sizzle.js'))
exit unless get_submodule("Sizzle", "sizzle")
end
end
@ -117,6 +94,7 @@ module PrototypeHelper
Kernel.system("git submodule init")
return true if Kernel.system("git submodule update vendor/#{path}")
# If we got this far, something went wrong.
puts "\nLooks like it didn't work. Try it manually:\n\n"
puts " $ git submodule init"
@ -150,11 +128,7 @@ task :default => [:dist, :dist_helper, :package, :clean_package_source]
desc "Builds the distribution."
task :dist do
PrototypeHelper.sprocketize(
:path => 'src',
:source => 'prototype.js',
:selector_engine => ENV['SELECTOR_ENGINE'] || PrototypeHelper::DEFAULT_SELECTOR_ENGINE
)
PrototypeHelper.sprocketize("src", "prototype.js")
end
namespace :doc do
@ -172,7 +146,7 @@ task :doc => ['doc:build']
desc "Builds the updating helper."
task :dist_helper do
PrototypeHelper.sprocketize(:path => 'ext/update_helper', :source => 'prototype_update_helper.js')
PrototypeHelper.sprocketize("ext/update_helper", "prototype_update_helper.js")
end
Rake::PackageTask.new('prototype', PrototypeHelper::VERSION) do |package|

View File

@ -81,12 +81,7 @@
new Test.Unit.Runner({
testGetStack: function() {
var stack = prototypeUpdateHelper.getStack();
if (stack === '') {
this.info('UpdaterHelper#getStack is currently not supported on this browser.')
} else {
this.assertMatch(/prototype_update_helper\.html:\d+\n$/, prototypeUpdateHelper.getStack());
}
this.assertMatch(/prototype_update_helper\.html:\d+\n$/, prototypeUpdateHelper.getStack());
},
testDisplay: function() {
@ -285,38 +280,6 @@
this.assertNotNotified();
},
testSelectorInstanceMethods: function() {
var selector = new Selector('div');
this.assertWarnNotified('The Selector class has been deprecated. Please use the new Prototype.Selector API instead.');
selector.findElements(document);
this.assertWarnNotified('Selector#findElements has been deprecated. Please use the new Prototype.Selector API instead.');
selector.match(document.documentElement);
this.assertWarnNotified('Selector#match has been deprecated. Please use the new Prototype.Selector API instead.');
selector.toString();
this.assertWarnNotified('Selector#toString has been deprecated. Please use the new Prototype.Selector API instead.');
selector.inspect();
this.assertWarnNotified('Selector#inspect has been deprecated. Please use the new Prototype.Selector API instead.');
},
testSelectorMatchElements: function() {
Selector.matchElements([], 'div');
this.assertWarnNotified('Selector.matchElements has been deprecated. Please use the new Prototype.Selector API instead.');
},
testSelectorFindElement: function() {
Selector.findElement([], 'div');
this.assertWarnNotified('Selector.findElement has been deprecated. Please use the new Prototype.Selector API instead.');
},
testSelectorFindChildElements: function() {
Selector.findChildElements(document, 'div');
this.assertWarnNotified('Selector.findChildElements has been deprecated. Please use the new Prototype.Selector API instead.');
},
testLogDeprecationOption: function() {
prototypeUpdateHelper.logLevel = UpdateHelper.Warn;
var h = $H({ foo: 2 });

View File

@ -1,6 +1,6 @@
//= require "update_helper"
/* UpdateHelper for Prototype <%= PROTOTYPE_VERSION %> (c) 2008-2009 Tobie Langel
/* UpdateHelper for Prototype <%= PROTOTYPE_VERSION %> (c) 2008 Tobie Langel
*
* UpdateHelper for Prototype is freely distributable under the same
* terms as Prototype (MIT-style license).
@ -17,7 +17,7 @@
*
* This, for example, will prevent deprecation messages from being logged.
*
* THIS SCRIPT DOES NOT WORK IN INTERNET EXPLORER
* THIS SCRIPT WORKS IN FIREFOX ONLY
*--------------------------------------------------------------------------*/
var prototypeUpdateHelper = new UpdateHelper([
@ -275,62 +275,6 @@ var prototypeUpdateHelper = new UpdateHelper([
message: 'The class API has been fully revised and now allows for mixins and inheritance.\n' +
'You can find more about it here: http://prototypejs.org/learn/class-inheritance',
condition: function() { return !arguments.length }
},
{
methodName: 'initialize',
namespace: Selector.prototype,
message: 'The Selector class has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
},
{
methodName: 'findElements',
namespace: Selector.prototype,
message: 'Selector#findElements has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
},
{
methodName: 'match',
namespace: Selector.prototype,
message: 'Selector#match has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
},
{
methodName: 'toString',
namespace: Selector.prototype,
message: 'Selector#toString has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
},
{
methodName: 'inspect',
namespace: Selector.prototype,
message: 'Selector#inspect has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
},
{
methodName: 'matchElements',
namespace: Selector,
message: 'Selector.matchElements has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
},
{
methodName: 'findElement',
namespace: Selector,
message: 'Selector.findElement has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
},
{
methodName: 'findChildElements',
namespace: Selector,
message: 'Selector.findChildElements has been deprecated. Please use the new Prototype.Selector API instead.',
type: 'warn'
}
]);

View File

@ -1,4 +1,4 @@
/* Update Helper (c) 2008-2009 Tobie Langel
/* Update Helper (c) 2008 Tobie Langel
*
* Requires Prototype >= 1.6.0
*
@ -54,12 +54,9 @@ var UpdateHelper = Class.create({
try {
throw new Error("stack");
} catch(e) {
var match = (e.stack || '').match(this.Regexp);
if (match) {
return match.reject(function(path) {
return (/(prototype|unittest|update_helper)\.js/).test(path);
}).join("\n");
} else { return ''; }
return (e.stack || '').match(this.Regexp).reject(function(path) {
return /(prototype|unittest|update_helper)\.js/.test(path);
}).join("\n");
}
},

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

@ -184,95 +184,3 @@ Element.ClassNames.prototype = {
Object.extend(Element.ClassNames.prototype, Enumerable);
/*--------------------------------------------------------------------------*/
/** deprecated, section: DOM
* class Selector
*
* A class that queries the document for elements that match a given CSS
* selector.
**/
(function() {
window.Selector = Class.create({
/** deprecated
* new Selector(expression)
* - expression (String): A CSS selector.
*
* Creates a `Selector` with the given CSS selector.
**/
initialize: function(expression) {
this.expression = expression.strip();
},
/** deprecated
* Selector#findElements(root) -> [Element...]
* - root (Element | document): A "scope" to search within. All results will
* be descendants of this node.
*
* Searches the document for elements that match the instance's CSS
* selector.
**/
findElements: function(rootElement) {
return Prototype.Selector.select(this.expression, rootElement);
},
/** deprecated
* Selector#match(element) -> Boolean
*
* Tests whether a `element` matches the instance's CSS selector.
**/
match: function(element) {
return Prototype.Selector.match(element, this.expression);
},
toString: function() {
return this.expression;
},
inspect: function() {
return "#<Selector: " + this.expression + ">";
}
});
Object.extend(Selector, {
/** deprecated
* Selector.matchElements(elements, expression) -> [Element...]
*
* Filters the given collection of elements with `expression`.
*
* The only nodes returned will be those that match the given CSS selector.
**/
matchElements: Prototype.Selector.filter,
/** deprecated
* Selector.findElement(elements, expression[, index = 0]) -> Element
* Selector.findElement(elements[, index = 0]) -> Element
*
* Returns the `index`th element in the collection that matches
* `expression`.
*
* Returns the `index`th element overall if `expression` is not given.
**/
findElement: function(elements, expression, index) {
index = index || 0;
var matchIndex = 0, element;
// Match each element individually, since Sizzle.matches does not preserve order
for (var i = 0, length = elements.length; i < length; i++) {
element = elements[i];
if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
return Element.extend(element);
}
}
},
/** deprecated
* Selector.findChildElements(element, expressions) -> [Element...]
*
* Searches beneath `element` for any elements that match the selector
* (or selectors) specified in `expressions`.
**/
findChildElements: function(element, expressions) {
var selector = expressions.toArray().join(', ');
return Prototype.Selector.select(selector, element || document);
}
});
})();

View File

@ -19,15 +19,8 @@
*
**/
/** section: DOM
* Prototype
*
* The Prototype namespace.
*
**/
//= require "dom/dom"
//= require <selector_engine>
//= require "dom/selector"
//= require "dom/form"
//= require "dom/event"

File diff suppressed because it is too large Load Diff

View File

@ -25,10 +25,7 @@
* browsers.
*
* `Event` also provides a standardized list of key codes you can use with
* 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`.
* keyboard-related events.
*
* 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,
@ -152,14 +149,10 @@
function findElement(event, expression) {
var element = Event.element(event);
if (!expression) return element;
while (element) {
if (Prototype.Selector.match(element, expression)) {
return Element.extend(element);
}
element = element.parentNode;
}
var elements = [element].concat(element.ancestors());
return Selector.findElement(elements, expression, 0);
}
/**
* Event.pointer(@event) -> Object
*
@ -386,12 +379,12 @@
window.addEventListener('unload', Prototype.emptyFunction, false);
var _getDOMEventName = Prototype.K,
translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
var _getDOMEventName = Prototype.K;
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
_getDOMEventName = function(eventName) {
return (translations[eventName] || eventName);
var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
return eventName in translations ? translations[eventName] : eventName;
};
}
@ -415,7 +408,6 @@
* * 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
@ -621,39 +613,48 @@
* ...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 (!eventName) {
// We stop observing all events.
// e.g.: $(element).stopObserving();
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.
registry.each( function(pair) {
var eventName = pair.key;
stopObserving(element, eventName);
var eventName = pair.key, responders = pair.value;
responders.each( function(r) {
Element.stopObserving(element, eventName, r.handler);
});
});
return element;
}
var responders = registry.get(eventName);
if (!responders) return element;
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;
}
// Fail gracefully if there are no responders assigned.
if (!responders) return;
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)
@ -664,7 +665,6 @@
}
} else {
// Ordinary event.
var actualEventName = _getDOMEventName(eventName);
if (element.removeEventListener)
element.removeEventListener(actualEventName, responder, false);
else
@ -745,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, {
}
});
/**
* class Form.EventObserver < Abstract.EventObserver
/** section: DOM
* class Form.Element.EventObserver < Abstract.EventObserver
**/
Form.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {

View File

@ -1,66 +1,111 @@
/** section: DOM, related to: Prototype.Selector
* $$(expression...) -> [Element...]
//= require <sizzle>
/** section: DOM
* class Selector
*
* Returns all elements in the document that match the provided CSS selectors.
* A class that queries the document for elements that match a given CSS
* selector.
**/
window.$$ = function() {
var expression = $A(arguments).join(', ');
return Prototype.Selector.select(expression, document);
};
/**
* Prototype.Selector
*
* A namespace that acts as a wrapper around
* the choosen selector engine (Sizzle by default).
*
**/
// Implementation provided by selector engine.
/**
* Prototype.Selector.select(expression[, root = document]) -> [Element...]
* - expression (String): A CSS selector.
* - root (Element | document): A "scope" to search within. All results will
* be descendants of this node.
*
* Searches `root` for elements that match the provided CSS selector and returns an
* array of extended [[Element]] objects.
**/
// Implementation provided by selector engine.
/**
* Prototype.Selector.match(element, expression) -> Boolean
* - element (Element): a DOM element.
* - expression (String): A CSS selector.
*
* Tests whether `element` matches the CSS selector.
**/
// Implementation provided by selector engine.
/**
* 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 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;
for (i = 0; i < length; i++) {
if (match(elements[i], expression) && index == matchIndex++) {
return Element.extend(elements[i]);
}
}
(function() {
function extend(elements) {
for (var i = 0, length = elements.length; i < length; i++)
elements[i] = Element.extend(elements[i]);
return elements;
}
}
window.Selector = Class.create({
/**
* new Selector(expression)
* - expression (String): A CSS selector.
*
* Creates a `Selector` with the given CSS selector.
**/
initialize: function(expression) {
this.expression = expression.strip();
},
/**
* Selector#findElements(root) -> [Element...]
* - root (Element || document): A "scope" to search within. All results will
* be descendants of this node.
*
* Searches the document for elements that match the instance's CSS
* selector.
**/
findElements: function(rootElement) {
return extend(Sizzle(this.expression, rootElement || document));
},
/**
* Selector#match(element) -> Boolean
*
* Tests whether a `element` matches the instance's CSS selector.
**/
match: function(element) {
return Sizzle.matches(this.expression, [element]).length == 1;
},
toString: function() {
return this.expression;
},
inspect: function() {
return "#<Selector: " + this.expression + ">";
}
});
Object.extend(Selector, {
/**
* Selector.matchElements(elements, expression) -> [Element...]
*
* Filters the given collection of elements with `expression`.
*
* The only nodes returned will be those that match the given CSS selector.
**/
matchElements: function(elements, expression) {
return extend(Sizzle.matches(expression, elements));
},
/**
* Selector.findElement(elements, expression[, index = 0]) -> Element
* Selector.findElement(elements[, index = 0]) -> Element
*
* Returns the `index`th element in the collection that matches
* `expression`.
*
* Returns the `index`th element overall if `expression` is not given.
**/
findElement: function(elements, expression, index) {
if (Object.isUndefined(index)) index = 0;
var selector = new Selector(expression), length = elements.length, matchIndex = 0, i;
// Match each element individually, since Sizzle.matches does not preserve order
for (i = 0; i < length; i++) {
if (selector.match(elements[i]) && index == matchIndex++) {
return Element.extend(elements[i]);
}
}
},
/**
* Selector.findChildElements(element, expressions) -> [Element...]
*
* Searches beneath `element` for any elements that match the selector
* (or selectors) specified in `expressions`.
**/
findChildElements: function(element, expressions) {
var results = [], exprs = expressions.toArray();
while (exprs.length) Sizzle(exprs.shift(), element || document, results);
return extend(results);
}
});
/** related to: Selector
* $$(expression...) -> [Element...]
*
* Returns all elements in the document that match the provided CSS selectors.
**/
window.$$ = function() {
return Selector.findChildElements(document, $A(arguments));
}
})();

View File

@ -9,17 +9,6 @@
* 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.
@ -70,7 +59,7 @@ var Class = (function() {
parent.subclasses.push(klass);
}
for (var i = 0, length = properties.length; i < length; i++)
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
@ -146,13 +135,12 @@ var Class = (function() {
* //-> alerts "You should probably run. He looks really mad."
**/
function addMethods(source) {
var ancestor = this.superclass && this.superclass.prototype,
properties = Object.keys(source);
var ancestor = this.superclass && this.superclass.prototype;
var properties = Object.keys(source);
// 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) {
// IE6 doesn't enumerate toString and valueOf properties,
// Force copy if they're not coming from Object.prototype.
if (!Object.keys({ toString: true }).length) {
if (source.toString != Object.prototype.toString)
properties.push("toString");
if (source.valueOf != Object.prototype.valueOf)
@ -162,7 +150,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()[0] == "$super") {
value.argumentNames().first() == "$super") {
var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };

View File

@ -217,13 +217,7 @@
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,11 +42,6 @@ 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;
@ -78,11 +73,6 @@ 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);
@ -141,7 +131,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 _not_ sufficiently robust to ensure that the content
* content, `stripTags` is probably _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?
@ -177,8 +167,8 @@ Object.extend(String.prototype, (function() {
* returns them as an array of strings.
**/
function extractScripts() {
var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
matchOne = new RegExp(Prototype.ScriptFragment, 'im');
var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
@ -261,9 +251,8 @@ Object.extend(String.prototype, (function() {
return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
var key = decodeURIComponent(pair.shift()),
value = pair.length > 1 ? pair.join('=') : pair[0];
var key = decodeURIComponent(pair.shift());
var value = pair.length > 1 ? pair.join('=') : pair[0];
if (value != undefined) value = decodeURIComponent(value);
if (key in hash) {
@ -322,9 +311,17 @@ Object.extend(String.prototype, (function() {
* // -> 'MozBinding'
**/
function camelize() {
return this.replace(/-+(.)?/g, function(match, chr) {
return chr ? chr.toUpperCase() : '';
});
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;
}
/**
@ -440,9 +437,7 @@ Object.extend(String.prototype, (function() {
* Checks if the string starts with `substring`.
**/
function startsWith(pattern) {
// 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;
return this.indexOf(pattern) === 0;
}
/**
@ -452,9 +447,7 @@ Object.extend(String.prototype, (function() {
**/
function endsWith(pattern) {
var d = this.length - pattern.length;
// 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;
return d >= 0 && this.lastIndexOf(pattern) === d;
}
/**
@ -493,7 +486,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 || strip,
strip: String.prototype.trim ? 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 now ubiquitous `{{ }}`
* together a template that uses a syntax similar to the ubiquitous `<&#38;= %>`
* constructs:
*
* // matches symbols like '{{ field }}'
* var syntax = /(^|.|\r|\n)(\{{\s*(\w+)\s*}})/;
* // matches symbols like '<&#38;= field %>'
* var syntax = /(^|.|\r|\n)(\<%=\s*(\w+)\s*%\>)/;
*
* var t = new Template(
* '<div>Name: <b>{{ name }}</b>, Age: <b>{{ age }}</b></div>',
* '<div>Name: <b><&#38;= name %></b>, Age: <b><&#38;=age%></b></div>',
* syntax);
* t.evaluate( {name: 'John Smith', age: 26} );
* // -> <div>Name: <b>John Smith</b>, Age: <b>26</b></div>
@ -133,9 +133,8 @@ var Template = Class.create({
var before = match[1] || '';
if (before == '\\') return match[2];
var ctx = object, expr = match[3],
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
var ctx = object, expr = match[3];
var 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'),
form = document.createElement('form'),
isSupported = false;
var div = document.createElement('div');
var form = document.createElement('form');
var isSupported = false;
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
isSupported = true;

View File

@ -1,29 +0,0 @@
Prototype._original_property = window.Sizzle;
//= require "sizzle"
Prototype.Selector = (function(engine) {
function extend(elements) {
for (var i = 0, length = elements.length; i < length; i++) {
Element.extend(elements[i]);
}
return elements;
}
function select(selector, scope) {
return extend(engine(selector, scope || document));
}
function match(element, selector) {
return engine.matches(selector, [element]).length == 1;
}
return {
engine: engine,
select: select,
match: match
};
})(Sizzle);
// Restore globals.
window.Sizzle = Prototype._original_property;
delete Prototype._original_property;

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

View File

@ -0,0 +1,389 @@
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

@ -0,0 +1,251 @@
/* 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

@ -0,0 +1,963 @@
// 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

@ -0,0 +1,487 @@
/*
* 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

@ -0,0 +1,415 @@
/* 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

@ -0,0 +1,13 @@
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

@ -0,0 +1,116 @@
/* 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

@ -0,0 +1,443 @@
/* @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

@ -0,0 +1,244 @@
/* 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;
}

19
templates/html/helpers.rb Normal file
View File

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

24
templates/html/index.erb Normal file
View File

@ -0,0 +1,24 @@
<% @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

@ -0,0 +1,6 @@
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")
%>
};

79
templates/html/layout.erb Normal file
View File

@ -0,0 +1,79 @@
<!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

@ -0,0 +1,171 @@
<% 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

@ -0,0 +1,6 @@
<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

@ -0,0 +1,48 @@
<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

@ -0,0 +1,99 @@
<% @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

@ -0,0 +1,21 @@
<% 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,9 +951,6 @@ 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() {
@ -1325,10 +1322,6 @@ 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,8 +184,6 @@ 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

@ -1,4 +0,0 @@
<div id="test_div_parent" class="test_class">
<div id="test_div_child" class="test_class">
</div>
</div>

View File

@ -1,50 +0,0 @@
/*
<div id="test_div_parent" class="test_class">
<div id="test_div_child" class="test_class">
</div>
</div>
*/
new Test.Unit.Runner({
testEngine: function() {
this.assert(Prototype.Selector.engine);
},
testSelect: function() {
var elements = Prototype.Selector.select('.test_class');
this.assert(Object.isArray(elements));
this.assertEqual(2, elements.length);
this.assertEqual('test_div_parent', elements[0].id);
this.assertEqual('test_div_child', elements[1].id);
},
testSelectWithContext: function() {
var elements = Prototype.Selector.select('.test_class', $('test_div_parent'));
this.assert(Object.isArray(elements));
this.assertEqual(1, elements.length);
this.assertEqual('test_div_child', elements[0].id);
},
testSelectWithEmptyResult: function() {
var elements = Prototype.Selector.select('.non_existent');
this.assert(Object.isArray(elements));
this.assertEqual(0, elements.length);
},
testMatch: function() {
var element = $('test_div_parent');
this.assertEqual(true, Prototype.Selector.match(element, '.test_class'));
this.assertEqual(false, Prototype.Selector.match(element, '.non_existent'));
},
testFind: function() {
var elements = document.getElementsByTagName('*'),
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

@ -1,803 +0,0 @@
/* Portions of the Prototype.LegacySelector class are derived from Jack Slocum's DomQuery,
* part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
* license. Please see http://www.yui-ext.com/ for more information. */
Prototype.LegacySelector = Class.create({
initialize: function(expression) {
this.expression = expression.strip();
if (this.shouldUseSelectorsAPI()) {
this.mode = 'selectorsAPI';
} else if (this.shouldUseXPath()) {
this.mode = 'xpath';
this.compileXPathMatcher();
} else {
this.mode = "normal";
this.compileMatcher();
}
},
shouldUseXPath: (function() {
// Some versions of Opera 9.x produce incorrect results when using XPath
// with descendant combinators.
// see: http://opera.remcol.ath.cx/bugs/index.php?action=bug&id=652
var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
var isBuggy = false;
if (document.evaluate && window.XPathResult) {
var el = document.createElement('div');
el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
"//*[local-name()='li' or local-name()='LI']";
var result = document.evaluate(xpath, el, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
isBuggy = (result.snapshotLength !== 2);
el = null;
}
return isBuggy;
})();
return function() {
if (!Prototype.BrowserFeatures.XPath) return false;
var e = this.expression;
// Safari 3 chokes on :*-of-type and :empty
if (Prototype.Browser.WebKit &&
(e.include("-of-type") || e.include(":empty")))
return false;
// XPath can't do namespaced attributes, nor can it read
// the "checked" property from DOM nodes
if ((/(\[[\w-]*?:|:checked)/).test(e))
return false;
if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
return true;
}
})(),
shouldUseSelectorsAPI: function() {
if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
if (Prototype.LegacySelector.CASE_INSENSITIVE_CLASS_NAMES) return false;
if (!Prototype.LegacySelector._div) Prototype.LegacySelector._div = new Element('div');
// Make sure the browser treats the selector as valid. Test on an
// isolated element to minimize cost of this check.
try {
Prototype.LegacySelector._div.querySelector(this.expression);
} catch(e) {
return false;
}
return true;
},
compileMatcher: function() {
var e = this.expression, ps = Prototype.LegacySelector.patterns, h = Prototype.LegacySelector.handlers,
c = Prototype.LegacySelector.criteria, le, p, m, len = ps.length, name;
if (Prototype.LegacySelector._cache[e]) {
this.matcher = Prototype.LegacySelector._cache[e];
return;
}
this.matcher = ["this.matcher = function(root) {",
"var r = root, h = Prototype.LegacySelector.handlers, c = false, n;"];
while (e && le != e && (/\S/).test(e)) {
le = e;
for (var i = 0; i<len; i++) {
p = ps[i].re;
name = ps[i].name;
if (m = e.match(p)) {
this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
new Template(c[name]).evaluate(m));
e = e.replace(m[0], '');
break;
}
}
}
this.matcher.push("return h.unique(n);\n}");
eval(this.matcher.join('\n'));
Prototype.LegacySelector._cache[this.expression] = this.matcher;
},
compileXPathMatcher: function() {
var e = this.expression, ps = Prototype.LegacySelector.patterns,
x = Prototype.LegacySelector.xpath, le, m, len = ps.length, name;
if (Prototype.LegacySelector._cache[e]) {
this.xpath = Prototype.LegacySelector._cache[e]; return;
}
this.matcher = ['.//*'];
while (e && le != e && (/\S/).test(e)) {
le = e;
for (var i = 0; i<len; i++) {
name = ps[i].name;
if (m = e.match(ps[i].re)) {
this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
new Template(x[name]).evaluate(m));
e = e.replace(m[0], '');
break;
}
}
}
this.xpath = this.matcher.join('');
Prototype.LegacySelector._cache[this.expression] = this.xpath;
},
findElements: function(root) {
root = root || document;
var e = this.expression, results;
switch (this.mode) {
case 'selectorsAPI':
// querySelectorAll queries document-wide, then filters to descendants
// of the context element. That's not what we want.
// Add an explicit context to the selector if necessary.
if (root !== document) {
var oldId = root.id, id = $(root).identify();
// Escape special characters in the ID.
id = id.replace(/([\.:])/g, "\\$1");
e = "#" + id + " " + e;
}
results = $A(root.querySelectorAll(e)).map(Element.extend);
root.id = oldId;
return results;
case 'xpath':
return document._getElementsByXPath(this.xpath, root);
default:
return this.matcher(root);
}
},
match: function(element) {
this.tokens = [];
var e = this.expression, ps = Prototype.LegacySelector.patterns, as = Prototype.LegacySelector.assertions;
var le, p, m, len = ps.length, name;
while (e && le !== e && (/\S/).test(e)) {
le = e;
for (var i = 0; i<len; i++) {
p = ps[i].re;
name = ps[i].name;
if (m = e.match(p)) {
// use the Prototype.LegacySelector.assertions methods unless the selector
// is too complex.
if (as[name]) {
this.tokens.push([name, Object.clone(m)]);
e = e.replace(m[0], '');
} else {
// reluctantly do a document-wide search
// and look for a match in the array
return this.findElements(document).include(element);
}
}
}
}
var match = true, name, matches;
for (var i = 0, token; token = this.tokens[i]; i++) {
name = token[0], matches = token[1];
if (!Prototype.LegacySelector.assertions[name](element, matches)) {
match = false; break;
}
}
return match;
},
toString: function() {
return this.expression;
},
inspect: function() {
return "#<Prototype.LegacySelector:" + this.expression.inspect() + ">";
}
});
if (Prototype.BrowserFeatures.SelectorsAPI &&
document.compatMode === 'BackCompat') {
// Versions of Safari 3 before 3.1.2 treat class names case-insensitively in
// quirks mode. If we detect this behavior, we should use a different
// approach.
Prototype.LegacySelector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
var div = document.createElement('div'),
span = document.createElement('span');
div.id = "prototype_test_id";
span.className = 'Test';
div.appendChild(span);
var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
div = span = null;
return isIgnored;
})();
}
Object.extend(Prototype.LegacySelector, {
_cache: { },
xpath: {
descendant: "//*",
child: "/*",
adjacent: "/following-sibling::*[1]",
laterSibling: '/following-sibling::*',
tagName: function(m) {
if (m[1] == '*') return '';
return "[local-name()='" + m[1].toLowerCase() +
"' or local-name()='" + m[1].toUpperCase() + "']";
},
className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
id: "[@id='#{1}']",
attrPresence: function(m) {
m[1] = m[1].toLowerCase();
return new Template("[@#{1}]").evaluate(m);
},
attr: function(m) {
m[1] = m[1].toLowerCase();
m[3] = m[5] || m[6];
return new Template(Prototype.LegacySelector.xpath.operators[m[2]]).evaluate(m);
},
pseudo: function(m) {
var h = Prototype.LegacySelector.xpath.pseudos[m[1]];
if (!h) return '';
if (Object.isFunction(h)) return h(m);
return new Template(Prototype.LegacySelector.xpath.pseudos[m[1]]).evaluate(m);
},
operators: {
'=': "[@#{1}='#{3}']",
'!=': "[@#{1}!='#{3}']",
'^=': "[starts-with(@#{1}, '#{3}')]",
'$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
'*=': "[contains(@#{1}, '#{3}')]",
'~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
'|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
},
pseudos: {
'first-child': '[not(preceding-sibling::*)]',
'last-child': '[not(following-sibling::*)]',
'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
'empty': "[count(*) = 0 and (count(text()) = 0)]",
'checked': "[@checked]",
'disabled': "[(@disabled) and (@type!='hidden')]",
'enabled': "[not(@disabled) and (@type!='hidden')]",
'not': function(m) {
var e = m[6], p = Prototype.LegacySelector.patterns,
x = Prototype.LegacySelector.xpath, le, v, len = p.length, name;
var exclusion = [];
while (e && le != e && (/\S/).test(e)) {
le = e;
for (var i = 0; i<len; i++) {
name = p[i].name;
if (m = e.match(p[i].re)) {
v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
exclusion.push("(" + v.substring(1, v.length - 1) + ")");
e = e.replace(m[0], '');
break;
}
}
}
return "[not(" + exclusion.join(" and ") + ")]";
},
'nth-child': function(m) {
return Prototype.LegacySelector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
},
'nth-last-child': function(m) {
return Prototype.LegacySelector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
},
'nth-of-type': function(m) {
return Prototype.LegacySelector.xpath.pseudos.nth("position() ", m);
},
'nth-last-of-type': function(m) {
return Prototype.LegacySelector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
},
'first-of-type': function(m) {
m[6] = "1"; return Prototype.LegacySelector.xpath.pseudos['nth-of-type'](m);
},
'last-of-type': function(m) {
m[6] = "1"; return Prototype.LegacySelector.xpath.pseudos['nth-last-of-type'](m);
},
'only-of-type': function(m) {
var p = Prototype.LegacySelector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
},
nth: function(fragment, m) {
var mm, formula = m[6], predicate;
if (formula == 'even') formula = '2n+0';
if (formula == 'odd') formula = '2n+1';
if (mm = formula.match(/^(\d+)$/)) // digit only
return '[' + fragment + "= " + mm[1] + ']';
if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
if (mm[1] == "-") mm[1] = -1;
var a = mm[1] ? Number(mm[1]) : 1;
var b = mm[2] ? Number(mm[2]) : 0;
predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
"((#{fragment} - #{b}) div #{a} >= 0)]";
return new Template(predicate).evaluate({
fragment: fragment, a: a, b: b });
}
}
}
},
criteria: {
tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
className: 'n = h.className(n, r, "#{1}", c); c = false;',
id: 'n = h.id(n, r, "#{1}", c); c = false;',
attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
attr: function(m) {
m[3] = (m[5] || m[6]);
return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
},
pseudo: function(m) {
if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
},
descendant: 'c = "descendant";',
child: 'c = "child";',
adjacent: 'c = "adjacent";',
laterSibling: 'c = "laterSibling";'
},
patterns: [
// combinators must be listed first
// (and descendant needs to be last combinator)
{ name: 'laterSibling', re: /^\s*~\s*/ },
{ name: 'child', re: /^\s*>\s*/ },
{ name: 'adjacent', re: /^\s*\+\s*/ },
{ name: 'descendant', re: /^\s/ },
// selectors follow
{ name: 'tagName', re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
{ name: 'id', re: /^#([\w\-\*]+)(\b|$)/ },
{ name: 'className', re: /^\.([\w\-\*]+)(\b|$)/ },
{ name: 'pseudo', re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
{ name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
{ name: 'attr', re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
],
// for Prototype.LegacySelector.match and Element#match
assertions: {
tagName: function(element, matches) {
return matches[1].toUpperCase() == element.tagName.toUpperCase();
},
className: function(element, matches) {
return Element.hasClassName(element, matches[1]);
},
id: function(element, matches) {
return element.id === matches[1];
},
attrPresence: function(element, matches) {
return Element.hasAttribute(element, matches[1]);
},
attr: function(element, matches) {
var nodeValue = Element.readAttribute(element, matches[1]);
return nodeValue && Prototype.LegacySelector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
}
},
handlers: {
// UTILITY FUNCTIONS
// joins two collections
concat: function(a, b) {
for (var i = 0, node; node = b[i]; i++)
a.push(node);
return a;
},
// marks an array of nodes for counting
mark: function(nodes) {
var _true = Prototype.emptyFunction;
for (var i = 0, node; node = nodes[i]; i++)
node._countedByPrototype = _true;
return nodes;
},
unmark: (function(){
// IE improperly serializes _countedByPrototype in (inner|outer)HTML
// due to node properties being mapped directly to attributes
var PROPERTIES_ATTRIBUTES_MAP = (function(){
var el = document.createElement('div'),
isBuggy = false,
propName = '_countedByPrototype',
value = 'x';
el[propName] = value;
isBuggy = (el.getAttribute(propName) === value);
el = null;
return isBuggy;
})();
return PROPERTIES_ATTRIBUTES_MAP ?
function(nodes) {
for (var i = 0, node; node = nodes[i]; i++)
node.removeAttribute('_countedByPrototype');
return nodes;
} :
function(nodes) {
for (var i = 0, node; node = nodes[i]; i++)
node._countedByPrototype = void 0;
return nodes;
}
})(),
// mark each child node with its position (for nth calls)
// "ofType" flag indicates whether we're indexing for nth-of-type
// rather than nth-child
index: function(parentNode, reverse, ofType) {
parentNode._countedByPrototype = Prototype.emptyFunction;
if (reverse) {
for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
var node = nodes[i];
if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
}
} else {
for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
}
},
// filters out duplicates and extends all nodes
unique: function(nodes) {
if (nodes.length == 0) return nodes;
var results = [], n;
for (var i = 0, l = nodes.length; i < l; i++)
// use `typeof` operator to prevent errors
if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
n._countedByPrototype = Prototype.emptyFunction;
results.push(Element.extend(n));
}
return Prototype.LegacySelector.handlers.unmark(results);
},
// COMBINATOR FUNCTIONS
descendant: function(nodes) {
var h = Prototype.LegacySelector.handlers;
for (var i = 0, results = [], node; node = nodes[i]; i++)
h.concat(results, node.getElementsByTagName('*'));
return results;
},
child: function(nodes) {
var h = Prototype.LegacySelector.handlers;
for (var i = 0, results = [], node; node = nodes[i]; i++) {
for (var j = 0, child; child = node.childNodes[j]; j++)
if (child.nodeType == 1 && child.tagName != '!') results.push(child);
}
return results;
},
adjacent: function(nodes) {
for (var i = 0, results = [], node; node = nodes[i]; i++) {
var next = this.nextElementSibling(node);
if (next) results.push(next);
}
return results;
},
laterSibling: function(nodes) {
var h = Prototype.LegacySelector.handlers;
for (var i = 0, results = [], node; node = nodes[i]; i++)
h.concat(results, Element.nextSiblings(node));
return results;
},
nextElementSibling: function(node) {
while (node = node.nextSibling)
if (node.nodeType == 1) return node;
return null;
},
previousElementSibling: function(node) {
while (node = node.previousSibling)
if (node.nodeType == 1) return node;
return null;
},
// TOKEN FUNCTIONS
tagName: function(nodes, root, tagName, combinator) {
var uTagName = tagName.toUpperCase();
var results = [], h = Prototype.LegacySelector.handlers;
if (nodes) {
if (combinator) {
// fastlane for ordinary descendant combinators
if (combinator == "descendant") {
for (var i = 0, node; node = nodes[i]; i++)
h.concat(results, node.getElementsByTagName(tagName));
return results;
} else nodes = this[combinator](nodes);
if (tagName == "*") return nodes;
}
for (var i = 0, node; node = nodes[i]; i++)
if (node.tagName.toUpperCase() === uTagName) results.push(node);
return results;
} else return root.getElementsByTagName(tagName);
},
id: function(nodes, root, id, combinator) {
var targetNode = $(id), h = Prototype.LegacySelector.handlers;
if (root == document) {
// We don't have to deal with orphan nodes. Easy.
if (!targetNode) return [];
if (!nodes) return [targetNode];
} else {
// In IE, we can check sourceIndex to see if root is attached
// to the document. If not (or if sourceIndex is not present),
// we do it the hard way.
if (!root.sourceIndex || root.sourceIndex < 1) {
var nodes = root.getElementsByTagName('*');
for (var j = 0, node; node = nodes[j]; j++) {
if (node.id === id) return [node];
}
}
}
if (nodes) {
if (combinator) {
if (combinator == 'child') {
for (var i = 0, node; node = nodes[i]; i++)
if (targetNode.parentNode == node) return [targetNode];
} else if (combinator == 'descendant') {
for (var i = 0, node; node = nodes[i]; i++)
if (Element.descendantOf(targetNode, node)) return [targetNode];
} else if (combinator == 'adjacent') {
for (var i = 0, node; node = nodes[i]; i++)
if (Prototype.LegacySelector.handlers.previousElementSibling(targetNode) == node)
return [targetNode];
} else nodes = h[combinator](nodes);
}
for (var i = 0, node; node = nodes[i]; i++)
if (node == targetNode) return [targetNode];
return [];
}
return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
},
className: function(nodes, root, className, combinator) {
if (nodes && combinator) nodes = this[combinator](nodes);
return Prototype.LegacySelector.handlers.byClassName(nodes, root, className);
},
byClassName: function(nodes, root, className) {
if (!nodes) nodes = Prototype.LegacySelector.handlers.descendant([root]);
var needle = ' ' + className + ' ';
for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
nodeClassName = node.className;
if (nodeClassName.length == 0) continue;
if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
results.push(node);
}
return results;
},
attrPresence: function(nodes, root, attr, combinator) {
if (!nodes) nodes = root.getElementsByTagName("*");
if (nodes && combinator) nodes = this[combinator](nodes);
var results = [];
for (var i = 0, node; node = nodes[i]; i++)
if (Element.hasAttribute(node, attr)) results.push(node);
return results;
},
attr: function(nodes, root, attr, value, operator, combinator) {
if (!nodes) nodes = root.getElementsByTagName("*");
if (nodes && combinator) nodes = this[combinator](nodes);
var handler = Prototype.LegacySelector.operators[operator], results = [];
for (var i = 0, node; node = nodes[i]; i++) {
var nodeValue = Element.readAttribute(node, attr);
if (nodeValue === null) continue;
if (handler(nodeValue, value)) results.push(node);
}
return results;
},
pseudo: function(nodes, name, value, root, combinator) {
if (nodes && combinator) nodes = this[combinator](nodes);
if (!nodes) nodes = root.getElementsByTagName("*");
return Prototype.LegacySelector.pseudos[name](nodes, value, root);
}
},
pseudos: {
'first-child': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++) {
if (Prototype.LegacySelector.handlers.previousElementSibling(node)) continue;
results.push(node);
}
return results;
},
'last-child': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++) {
if (Prototype.LegacySelector.handlers.nextElementSibling(node)) continue;
results.push(node);
}
return results;
},
'only-child': function(nodes, value, root) {
var h = Prototype.LegacySelector.handlers;
for (var i = 0, results = [], node; node = nodes[i]; i++)
if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
results.push(node);
return results;
},
'nth-child': function(nodes, formula, root) {
return Prototype.LegacySelector.pseudos.nth(nodes, formula, root);
},
'nth-last-child': function(nodes, formula, root) {
return Prototype.LegacySelector.pseudos.nth(nodes, formula, root, true);
},
'nth-of-type': function(nodes, formula, root) {
return Prototype.LegacySelector.pseudos.nth(nodes, formula, root, false, true);
},
'nth-last-of-type': function(nodes, formula, root) {
return Prototype.LegacySelector.pseudos.nth(nodes, formula, root, true, true);
},
'first-of-type': function(nodes, formula, root) {
return Prototype.LegacySelector.pseudos.nth(nodes, "1", root, false, true);
},
'last-of-type': function(nodes, formula, root) {
return Prototype.LegacySelector.pseudos.nth(nodes, "1", root, true, true);
},
'only-of-type': function(nodes, formula, root) {
var p = Prototype.LegacySelector.pseudos;
return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
},
// handles the an+b logic
getIndices: function(a, b, total) {
if (a == 0) return b > 0 ? [b] : [];
return $R(1, total).inject([], function(memo, i) {
if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
return memo;
});
},
// handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
nth: function(nodes, formula, root, reverse, ofType) {
if (nodes.length == 0) return [];
if (formula == 'even') formula = '2n+0';
if (formula == 'odd') formula = '2n+1';
var h = Prototype.LegacySelector.handlers, results = [], indexed = [], m;
h.mark(nodes);
for (var i = 0, node; node = nodes[i]; i++) {
if (!node.parentNode._countedByPrototype) {
h.index(node.parentNode, reverse, ofType);
indexed.push(node.parentNode);
}
}
if (formula.match(/^\d+$/)) { // just a number
formula = Number(formula);
for (var i = 0, node; node = nodes[i]; i++)
if (node.nodeIndex == formula) results.push(node);
} else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
if (m[1] == "-") m[1] = -1;
var a = m[1] ? Number(m[1]) : 1;
var b = m[2] ? Number(m[2]) : 0;
var indices = Prototype.LegacySelector.pseudos.getIndices(a, b, nodes.length);
for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
for (var j = 0; j < l; j++)
if (node.nodeIndex == indices[j]) results.push(node);
}
}
h.unmark(nodes);
h.unmark(indexed);
return results;
},
'empty': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++) {
// IE treats comments as element nodes
if (node.tagName == '!' || node.firstChild) continue;
results.push(node);
}
return results;
},
'not': function(nodes, selector, root) {
var h = Prototype.LegacySelector.handlers, selectorType, m;
var exclusions = new Prototype.LegacySelector(selector).findElements(root);
h.mark(exclusions);
for (var i = 0, results = [], node; node = nodes[i]; i++)
if (!node._countedByPrototype) results.push(node);
h.unmark(exclusions);
return results;
},
'enabled': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++)
if (!node.disabled && (!node.type || node.type !== 'hidden'))
results.push(node);
return results;
},
'disabled': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++)
if (node.disabled) results.push(node);
return results;
},
'checked': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++)
if (node.checked) results.push(node);
return results;
}
},
operators: {
'=': function(nv, v) { return nv == v; },
'!=': function(nv, v) { return nv != v; },
'^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
'$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
'*=': function(nv, v) { return nv == v || nv && nv.include(v); },
'~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
'|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
'-').include('-' + (v || "").toUpperCase() + '-'); }
},
split: function(expression) {
var expressions = [];
expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
expressions.push(m[1].strip());
});
return expressions;
},
matchElements: function(elements, expression) {
var matches = $$(expression), h = Prototype.LegacySelector.handlers;
h.mark(matches);
for (var i = 0, results = [], element; element = elements[i]; i++)
if (element._countedByPrototype) results.push(element);
h.unmark(matches);
return results;
},
findElement: function(elements, expression, index) {
if (Object.isNumber(expression)) {
index = expression; expression = false;
}
return Prototype.LegacySelector.matchElements(elements, expression || '*')[index || 0];
},
findChildElements: function(element, expressions) {
expressions = Prototype.LegacySelector.split(expressions.join(','));
var results = [], h = Prototype.LegacySelector.handlers;
for (var i = 0, l = expressions.length, selector; i < l; i++) {
selector = new Prototype.LegacySelector(expressions[i].strip());
h.concat(results, selector.findElements(element));
}
return (l > 1) ? h.unique(results) : results;
}
});
if (Prototype.Browser.IE) {
Object.extend(Prototype.LegacySelector.handlers, {
// IE returns comment nodes on getElementsByTagName("*").
// Filter them out.
concat: function(a, b) {
for (var i = 0, node; node = b[i]; i++)
if (node.tagName !== "!") a.push(node);
return a;
}
});
}

View File

@ -1,18 +0,0 @@
//= require "repository/legacy_selector"
Prototype.Selector = (function(engine) {
function select(selector, scope) {
return engine.findChildElements(scope || document, [selector]);
}
function match(element, selector) {
return !!engine.findElement([element], selector);
}
return {
engine: engine,
select: select,
match: match,
filter: engine.matchElements
};
})(Prototype.LegacySelector);

@ -1 +0,0 @@
Subproject commit c9f5d5d4fc4ca294477f803bb8d688a8d45de664

View File

@ -1,18 +0,0 @@
Prototype._original_property = window.NW;
//= require "repository/src/nwmatcher"
Prototype.Selector = (function(engine) {
function select(selector, scope) {
return engine.select(selector, scope || document, null, Element.extend);
}
return {
engine: engine,
select: select,
match: engine.match
};
})(NW.Dom);
// Restore globals.
window.NW = Prototype._original_property;
delete Prototype._original_property;

2
vendor/pdoc vendored

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

1
vendor/sizzle vendored Submodule

@ -0,0 +1 @@
Subproject commit e0f5cbc75d12aa78f3ef30930414b2f88da7b2b8

@ -1 +0,0 @@
Subproject commit 415e466f70e5a53f589161b1f2944e5485007409

View File

@ -1,34 +0,0 @@
Prototype._original_property = window.Sizzle;
//= require "repository/sizzle"
Prototype.Selector = (function(engine) {
function extend(elements) {
for (var i = 0, length = elements.length; i < length; i++) {
Element.extend(elements[i]);
}
return elements;
}
function select(selector, scope) {
return extend(engine(selector, scope || document));
}
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
};
})(Sizzle);
// Restore globals.
window.Sizzle = Prototype._original_property;
delete Prototype._original_property;