# GvaScript.protoExtensions

Extensions to prototype.js

### Table of contents

NAME
SYNOPSIS
DESCRIPTION
METHODS
Events delegation
Prototype.getJSON
Hash utilities
Hash.expand
Hash.flatten
String extensions
chomp
Element extensions
flash
hasAnyClass
getElementsByClassNames
navigateDom
autoScroll
outerHTML
Form.Element extensions
setValue
Event extensions
detailedStop
stopAll
Class extensions
checkOptions
ASSERT
CSSPREFIX

## NAME

GvaScript.protoExtensions - Extensions to prototype.js

## SYNOPSIS

      Element.hasAnyClass(elem, ["class1", "class2", ...]);
      Element.getElementsByClassNames(elem, ["class1", "class2", ...]);

      var stop_condition = function(elem) { return elem.tagName == "SPAN"};
      Element.navigateDom(elem, "nextSibling", ["class1", "class2", ...],
                           stop_condition);

      this.options = Class.checkOptions(defaultOptions, receivedOptions);

      Element.register(elem, 'input.active', 'mouseover', function(e) {
        e._target.addClassName('hover');
      });
      Element.unregister(elem, 'input.active', 'mouseover');

      Element.store(elem, key, value);
      Element.retrieve(elem, key, default);

## DESCRIPTION

Some extensions to the basic abstractions supplied by prototype.js.

## METHODS

### Events delegation

      Will be a part of prototype's core distribution starting version 1.7
      as discussed here
      [https://prototype.lighthouseapp.com/projects/8886/tickets/435-eventdelegate-and-elementmethodsdelegate]

### Prototype.getJSON

      Prototype.getJSON(url, callback)

based on: getJSON function by Juriy Zaytsev http://github.com/kangax/protolicious/tree/master/get_json.js

A method to temporarily load JSON data (ideally hosted on a different domain and accessible via JSONP service) and send it over to callback method when ready.

### Hash utilities

#### Hash.expand

      var tree = Hash.expand(flat_hash);

Transforms a flat structure of key-value pairs into a nested tree structure, by splitting keys on dots. The idea and algorithm come from CGI::Expand/expand_hash.

      Hash.expand({a: '...', b.0.x: '...', b.0.y: '...', b.1.x: '...', b.1.y: '...'}) =>
      {a: '...', b: [{x: '...', y: '...'}, {x: '...', y: '...'}]}

#### Hash.flatten

The exact opposite of Hash.expand

Transforms a nested tree structure into a flat hash of key-value pairs where nested keys are joined by a dot.

### String extensions

#### chomp

Strips any trailing line breaks (\r\n) from a String.

### Element extensions

#### flash

only applied to ['SPAN', 'DIV', 'INPUT', 'BUTTON', 'TEXTAREA', 'A'] elements.

used to set a classname to the element for a brief moment of time.

      Element.flash(elem, {duration: I<time_mes>, classname: I<classname_to_set>});

#### hasAnyClass

      if (Element.hasAnyClass(elem, ["class1", "class2", ...]) {...}

      if (Element.hasAnyClass(elem, "class1") {...}

Returns true if the supplied element has any of the given classes. For convenience, also accepts a single string instead of an array when testing for a single class.

#### getElementsByClassNames

      var subElements
         = Element.getElementsByClassNames(rootElement, ["class1", "class2", ...]);

Returns an array of children of `rootElement` that have any of the given class names.

#### navigateDom

      var wantedClasses = ["class1", "class2", ...];

      // which direction to navigate (could be "parentNode", etc.)
      var direction     = "nextSibling";

      // some criteria for stopping navigation (can be anything, here a stupid
      // example)
      var stopCondition = function(elem) {return elem.innerHTML.length > 10}

      var nextElement
        = Element.navigateDom(startElement, direction, wantedClasses,
                              stopCondition);

Walks through the DOM in the given direction, until finding an element that has one of the given classnames, or finding a stop condition (in which case `null` is returned).

#### autoScroll

      Element.autoScroll(elem, percentage)

Makes sure that `elem` is visible in the central area of its offset parent; if not, the parent is scrolled. `percentage` is the ratio between the parent height and the margin at which scrolling must occur, i.e. if `percentage = 20` (the default), then scrolling occurs if the element is in the higher than the top 20% or lower than the bottom 20% of the viewport.

#### outerHTML

      Element.outerHTML(elem)

Returns a string representation of the DOM element, including tags and attributes. Implemented through the native `outerHTML` property, if present; otherwise constructs a string from tag name, attributes and innerHTML property.

### Form.Element extensions

#### setValue

Form.Element.setValue method is wrapped to fire a 'value:change' custom event with oldvalue and newvalue properties set in the event.memo

### Event extensions

#### detailedStop

      Event.detailedStop(event, toStop);

Browser-independent method to control fine details of event stopping within event handlers. The `toStop` argument is an object which may contain the following properties:

- stopPropagation

  if true, the event will not be passed to further handlers up the bubbling hierarchy.

- preventDefault

  if true, the default behaviour of the browser for that event will be cancelled

#### stopAll

Just a convenience object, having both properties above set to true. So

      Event.detailedStop(event, Event.stopAll);

is equivalent to calling prototype's `Event.stop(event)`.

### Class extensions

#### checkOptions

      this.options = Class.checkOptions(defaultOptions, ctorOptions)

Utility for constructor methods. The first argument is an object containing a collection of default options (keys and values). The second argument is a similar object, containing options given to the constructor.

If one of the keys in `ctorOptions` has no corresponding key in `defaultOptions`, an error is generated (because the constructor does not expect such a key). Otherwise, the concatenation of both objects is returned (i.e. values in `ctorOptions` take precedence over values in `defaultOptions`).

### ASSERT

      ASSERT (cond, msg);

Checks if `cond` is true, and if not, generates an error with message `msg`.

### CSSPREFIX

      CSSPREFIX ();

Returns value of `CSS_PREFIX` global variable if found. If not, default to 'gva'.

This value is used to prefix css classnames of html elements that are derived in some GvaScript classes.