Selectors
=========

The selector is responsible for finding the nodes on which to operate.
Selectors are executed on the client. Most of them has a single parameter.

A base class is provided for all selectors.

  >>> from kss.base.selectors import Selector

The base class cannot be instantiated in itself. We will show later,
how a plugin can subclass it to create a new selector type and 
register it.

  >>> Selector()
  Traceback (most recent call last):
  ...
  NotImplementedError

Standard selectors
------------------

In the core package you can find a few standard selectors. The most
basic selectors are the CSS and HTML id selectors.

  >>> from kss.base.selectors import css, htmlid

The selector classes have a type parameter defined on the class.

  >>> css.type
  'css'
  >>> htmlid.type
  'htmlid'

They both need a value to operate on.

  >>> selector = css('div.main a')
  >>> selector.type
  'css'
  >>> selector.value
  'div.main a'

  >>> selector = htmlid('someid')
  >>> selector.type
  'htmlid'
  >>> selector.value
  'someid'
  
There are also two somewhat different selectors. The first is special
in that it selects the same node that was used to call the server
action. Also note that it does not accept any arguments.

  >>> from kss.base.selectors import samenode
  >>> samenode.type
  'samenode'
  >>> selector = samenode()
  >>> selector.type
  'samenode'
  >>> selector.value
  ''

Another core selector is parentnode. This one can be used to use a CSS
query which only operates on nodes that are the parent (or
grandparents).

  >>> from kss.base.selectors import parentnode
  >>> parentnode.type
  'parentnode'
  >>> selector = parentnode('a')
  >>> selector.type
  'parentnode'
  >>> selector.value
  'a'

Selectors registered by plugins
-------------------------------

Suppose a plugin registers a new selector. It must overwrite type, and
__init__.  The type of the selector should always be in namespace-name
notation. Only the core selectors can do without a namespace.

  >>> from kss.base.selectors import Selector
  >>> class MyFunkySelector(Selector):
  ...     type = 'mynamespace-funky'
  ...     def __init__(self, value):
  ...         self.value = value

We will use this class to create selector instances. In real
life, the plugin would register this class now with the plugin
registry, and the commandset code would look up the class from
the registry. However, we test the registration somewhere
else, and just use the class as it is for now:

Now let's instantiate the selector:

  >>> selector = MyFunkySelector('Selector value')

The selector now has a type and value property.

  >>> selector.type
  'mynamespace-funky'

  >>> selector.value
  'Selector value'

Currently only the "value" property will be marshalled to the
client. Selectors must therefore have their parameter stored as
`value`.


String representation
---------------------

For testing purposes we have a string representation of the selectors.

  >>> print MyFunkySelector('value')
  mynamespace-funky('value')

  >>> print css('div.content')
  css('div.content')
