chosen-0.9.15/0000755000175000017500000000000012153204007012043 5ustar iliasiliaschosen-0.9.15/package.json0000644000175000017500000000115512153204007014333 0ustar iliasilias{ "author": "harvest", "name": "chosen", "version": "0.9.15", "description": "Chosen is a JavaScript plugin that makes long, unwieldy select boxes much more user-friendly. It is currently available in both jQuery and Prototype flavors.", "repository": { "type": "git", "url": "https://github.com/harvesthq/chosen" }, "engines": { "node": ">=0.4.0" }, "dependencies": {}, "devDependencies": { "coffee-script": ">= 1.6", "uglify-js": ">= 1.2.5 <2.0" }, "licenses": [ { "type": "MIT", "url": "https://github.com/harvesthq/chosen/blob/master/LICENSE.md" } ] }chosen-0.9.15/example.proto.html0000644000175000017500000023747312153204007015546 0ustar iliasilias

Chosen

Chosen is a JavaScript plugin for jQuery and Prototype that makes long, unwieldy select boxes much more user-friendly. For more information (including usage, explanation and faqs), check out the online documentation.

Standard Select

Turns This
Into This

Multiple Select

Turns This
Into This

<optgroup> Support

Single Select with Groups
Multiple Select with Groups

Selected and Disabled Support

Chosen automatically highlights selected options and removes disabled options.

Single Select
Multiple Select

Hide Search on Single Select

The disable_search_threshold option can be specified to hide the search input on single selects if there are fewer than (n) options.

New Chosen($("chzn_select_field"),{disable_search_threshold: 10});

Default Text Support

Chosen automatically sets the default field text ("Choose a country...") by reading the select element's data-placeholder value. If no data-placeholder value is present, it will default to "Select an Option" or "Select Some Options" depending on whether the select is single or multiple. You can change these elements in the plugin js file as you see fit.

<select data-placeholder="Choose a country..." style="width:350px;" multiple class="chzn-select">

Note: on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.

No Results Text Support

Setting the "No results" search text is as easy as passing an option when you create Chosen:

New Chosen($("chzn_select_field"),{no_results_text: "Oops, nothing found!"});

Single Select
Multiple Select

Limit Selected Options in Multiselect

You can easily limit how many options can user select:

new Chosen($("chzn_select_field"),{max_selected_options: 5});

If you try to select another option with limit reached liszt:maxselected event is triggered:

$("chzn_select_field").observe("liszt:maxselected", function(evt) { ... });

Allow Deselect on Single Selects

When a single select box isn't a required field, you can set allow_single_deselect: true and Chosen will add a UI element for option deselection. This will only work if the first option has blank text.

Right to Left Support

Chosen supports right to left select boxes too. just add "chzn-rtl" in addition to "chzn-select" to your select tags and you are good to go.

<select class="chzn-select chzn-rtl">

Single right to left select
Multiple right to left select

Change / Update Events

Custom Width Support

Using a custom width with Chosen is as easy as passing an option when you create Chosen:

New Chosen($("chzn_select_field"),{width: "95%"});

Single Select
Multiple Select

Labels work, too

Use labels just like you would a standard select

Setup (for Prototype)

Using Chosen is easy as can be.

  1. Download the plugin and copy the chosen files to your app.
  2. Activate the plugin by creating a new instance of Chosen: New Chosen(some_form_field,some_options);
  3. Disco.
chosen-0.9.15/example.jquery.html0000644000175000017500000023705612153204007015717 0ustar iliasilias

Chosen

Chosen is a JavaScript plugin for Prototype and jQuery that makes long, unwieldy select boxes much more user-friendly. For more information (including usage, explanation and faqs), check out the online documentation.

Standard Select

Turns This
Into This

Multiple Select

Turns This
Into This

<optgroup> Support

Single Select with Groups
Multiple Select with Groups

Selected and Disabled Support

Chosen automatically highlights selected options and removes disabled options.

Single Select
Multiple Select

Hide Search on Single Select

The disable_search_threshold option can be specified to hide the search input on single selects if there are fewer than (n) options.

$(".chzn-select").chosen({disable_search_threshold: 10});

Default Text Support

Chosen automatically sets the default field text ("Choose a country...") by reading the select element's data-placeholder value. If no data-placeholder value is present, it will default to "Select an Option" or "Select Some Options" depending on whether the select is single or multiple. You can change these elements in the plugin js file as you see fit.

<select data-placeholder="Choose a country..." style="width:350px;" multiple class="chzn-select">

Note: on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.

No Results Text Support

Setting the "No results" search text is as easy as passing an option when you create Chosen:

$(".chzn-select").chosen({no_results_text: "Oops, nothing found!"});

Single Select
Multiple Select

Limit Selected Options in Multiselect

You can easily limit how many options can user select:

$(".chzn-select").chosen({max_selected_options: 5});

If you try to select another option with limit reached liszt:maxselected event is triggered:

$(".chzn-select").bind("liszt:maxselected", function () { ... });

Allow Deselect on Single Selects

When a single select box isn't a required field, you can set allow_single_deselect: true and Chosen will add a UI element for option deselection. This will only work if the first option has blank text.

Right to Left Support

Chosen supports right to left select boxes too. just add "chzn-rtl" in addition to "chzn-select" to your select tags and you are good to go.

<select class="chzn-select chzn-rtl">

Single right to left select
Multiple right to left select

Change / Update Events

  • Form Field Change

    When working with form fields, you often want to perform some behavior after a value has been selected or deselected. Whenever a user selects a field in Chosen, it triggers a "change" event* on the original form field. That let's you do something like this:

    $("#form_field").chosen().change( … );

    Note: Prototype doesn't offer support for triggering standard browser events. Event.simulate is required to trigger the change event when using the Prototype version.

  • Updating Chosen Dynamically

    If you need to update the options in your select field and want Chosen to pick up the changes, you'll need to trigger the "liszt:updated" event on the field. Chosen will re-build itself based on the updated content.

    • jQuery Version: $("#form_field").trigger("liszt:updated");
    • Prototype Version: Event.fire($("form_field"), "liszt:updated");

Custom Width Support

Using a custom width with Chosen is as easy as passing an option when you create Chosen:

$(".chzn-select").chosen({width: "95%"});

Single Select
Multiple Select

Labels work, too

Use labels just like you would a standard select

Setup (for jQuery)

Using Chosen is easy as can be.

  1. Download the plugin and copy the chosen files to your app.
  2. Activate the plugin on the select boxes of your choice: $(".chzn-select").chosen()
  3. Disco.
chosen-0.9.15/contributing.md0000644000175000017500000001611012153204007015073 0ustar iliasilias# Contributing to this project Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved. Following these guidelines will help us get back to you more quickly, and will show that you care about making Chosen better just like we do. In return, we'll do our best to respond to your issue or pull request as soon as possible with the same respect. _**Please Note:** These guidelines are adapted from [@necolas](https://github.com/necolas)'s [issue-guidelines](https://github.com/necolas/issue-guidelines) and serve as an excellent starting point for contributing to any open source project._ ## Using the issue tracker The [issue tracker](https://github.com/harvesthq/chosen/issues) is the preferred channel for [bug reports](#bugs), [features requests](#features) and [submitting pull requests](#pull-requests), but please respect the following restrictions: * Please **do not** use the issue tracker for personal support requests (use [Stack Overflow](http://stackoverflow.com)). * Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. ## Bug reports A bug is a _demonstrable problem_ that is caused by the code in the repository. Good bug reports are extremely helpful — thank you! Guidelines for bug reports: 1. **Use the [GitHub issue search](https://github.com/harvesthq/chosen/search?type=Issues)** — check if the issue has already been reported. 2. **Check if the bug has already been fixed** — try to reproduce it using the repository's latest `master` changes. 3. **Isolate the problem** — ideally create a [reduced test case](http://css-tricks.com/6263-reduced-test-cases/) and a live example (perhaps a [fiddle](http://jsfiddle.net)). A good bug report shouldn't leave others needing to contact you for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What browser(s) and OS experience the problem? What outcome did you expect, and how did it differ from what you actually saw? All these details will help people to fix any potential bugs. Example: > Short and descriptive example bug report title > > A summary of the issue and the browser/OS environment in which it occurs. If > suitable, include the steps required to reproduce the bug. > > 1. This is the first step > 2. This is the second step > 3. Further steps, etc. > > `` - a link to the reduced test case > > Any other information you want to share that is relevant to the issue being > reported. This might include the lines of code that you have identified as > causing the bug, and potential solutions (and your opinions on their > merits). ## Feature requests Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible. Building something great means choosing features carefully especially because it is much, much easier to add features than it is to take them away. Additions to Chosen will be evaluated on a combination of scope (how well it fits into the project), maintenance burden and general usefulness. Creating something great often means saying no to seemingly good ideas. Don't dispair if your feature request isn't accepted, take action! Fork the repository, build your idea and share it with others. We released Chosen under the MIT License for this purpose precisely. Open source works best when smart and dedicated people riff off of each others' ideas to make even greater things. ## Pull requests Good pull requests - patches, improvements, new features — are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. **Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code, porting to a different language), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. You can solicit feedback and opinions in an open feature request thread or create a new one. Please use the [git flow for pull requesets](#git-flow) and follow Chosen's [code conventions](#code-conventions) before submitting your work. Adhering to these guidelines is the best way to get your work included in Chosen. #### Git Flow for pull requests 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes: ```bash # Clone your fork of the repo into the current directory git clone git@github.com:/chosen.git # Navigate to the newly cloned directory cd chosen # Assign the original repo to a remote called "upstream" git remote add upstream https://github.com/harvesthq/chosen ``` 2. If you cloned a while ago, get the latest changes from upstream: ```bash git checkout master git pull upstream master ``` 3. Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: ```bash git checkout -b ``` 4. Commit your changes in logical chunks. Please adhere to these [git commit message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) or your code is unlikely be merged into the main project. Use Git's [interactive rebase](https://help.github.com/articles/interactive-rebase) feature to tidy up your commits before making them public. 5. Locally merge (or rebase) the upstream development branch into your topic branch: ```bash git pull [--rebase] upstream master ``` 6. Push your topic branch up to your fork: ```bash git push origin ``` 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description. **IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the [MIT License](http://en.wikipedia.org/wiki/MIT_License). #### Chosen Code Conventions 1. Make all changes in CoffeeScript files, **not** JavaScript files. 2. Use [cake](#cake) to build the JavaScript files. 3. For feature changes, update both jQuery *and* Prototype versions 4. Don't touch the `VERSION` file #### Using CoffeeScript and Cake First, make sure you have the proper CoffeeScript / Cake setup in place. We have added a package.json that makes this easy: ``` npm install -d ``` This will install `coffee-script` and `uglifyjs`. Once you're configured, building the JavaScript from the command line is easy: cake build # build Chosen from source cake watch # watch coffee/ for changes and build Chosen If you're interested, you can find the recipes in [Cakefile](https://github.com/harvesthq/chosen/blob/master/Cakefile). chosen-0.9.15/coffee/0000755000175000017500000000000012153204007013272 5ustar iliasiliaschosen-0.9.15/coffee/lib/0000755000175000017500000000000012153204007014040 5ustar iliasiliaschosen-0.9.15/coffee/lib/select-parser.coffee0000644000175000017500000000273012153204007017764 0ustar iliasiliasclass SelectParser constructor: -> @options_index = 0 @parsed = [] add_node: (child) -> if child.nodeName.toUpperCase() is "OPTGROUP" this.add_group child else this.add_option child add_group: (group) -> group_position = @parsed.length @parsed.push array_index: group_position group: true label: group.label children: 0 disabled: group.disabled this.add_option( option, group_position, group.disabled ) for option in group.childNodes add_option: (option, group_position, group_disabled) -> if option.nodeName.toUpperCase() is "OPTION" if option.text != "" if group_position? @parsed[group_position].children += 1 @parsed.push array_index: @parsed.length options_index: @options_index value: option.value text: option.text html: option.innerHTML selected: option.selected disabled: if group_disabled is true then group_disabled else option.disabled group_array_index: group_position classes: option.className style: option.style.cssText else @parsed.push array_index: @parsed.length options_index: @options_index empty: true @options_index += 1 SelectParser.select_to_array = (select) -> parser = new SelectParser() parser.add_node( child ) for child in select.childNodes parser.parsed this.SelectParser = SelectParser chosen-0.9.15/coffee/lib/abstract-chosen.coffee0000644000175000017500000001213012153204007020266 0ustar iliasilias### Chosen source: generate output using 'cake build' Copyright (c) 2011 by Harvest ### root = this class AbstractChosen constructor: (@form_field, @options={}) -> return unless AbstractChosen.browser_is_supported() @is_multiple = @form_field.multiple this.set_default_text() this.set_default_values() this.setup() this.set_up_html() this.register_observers() this.finish_setup() set_default_values: -> @click_test_action = (evt) => this.test_active_click(evt) @activate_action = (evt) => this.activate_field(evt) @active_field = false @mouse_on_container = false @results_showing = false @result_highlighted = null @result_single_selected = null @allow_single_deselect = if @options.allow_single_deselect? and @form_field.options[0]? and @form_field.options[0].text is "" then @options.allow_single_deselect else false @disable_search_threshold = @options.disable_search_threshold || 0 @disable_search = @options.disable_search || false @enable_split_word_search = if @options.enable_split_word_search? then @options.enable_split_word_search else true @search_contains = @options.search_contains || false @single_backstroke_delete = @options.single_backstroke_delete || false @max_selected_options = @options.max_selected_options || Infinity @inherit_select_classes = @options.inherit_select_classes || false set_default_text: -> if @form_field.getAttribute("data-placeholder") @default_text = @form_field.getAttribute("data-placeholder") else if @is_multiple @default_text = @options.placeholder_text_multiple || @options.placeholder_text || AbstractChosen.default_multiple_text else @default_text = @options.placeholder_text_single || @options.placeholder_text || AbstractChosen.default_single_text @results_none_found = @form_field.getAttribute("data-no_results_text") || @options.no_results_text || AbstractChosen.default_no_result_text mouse_enter: -> @mouse_on_container = true mouse_leave: -> @mouse_on_container = false input_focus: (evt) -> if @is_multiple setTimeout (=> this.container_mousedown()), 50 unless @active_field else @activate_field() unless @active_field input_blur: (evt) -> if not @mouse_on_container @active_field = false setTimeout (=> this.blur_test()), 100 result_add_option: (option) -> if not option.disabled option.dom_id = @container_id + "_o_" + option.array_index classes = if option.selected and @is_multiple then [] else ["active-result"] classes.push "result-selected" if option.selected classes.push "group-option" if option.group_array_index? classes.push option.classes if option.classes != "" style = if option.style.cssText != "" then " style=\"#{option.style}\"" else "" '
  • ' + option.html + '
  • ' else "" results_update_field: -> this.set_default_text() this.results_reset_cleanup() if not @is_multiple this.result_clear_highlight() @result_single_selected = null this.results_build() results_toggle: -> if @results_showing this.results_hide() else this.results_show() results_search: (evt) -> if @results_showing this.winnow_results() else this.results_show() choices_count: -> return @selected_option_count if @selected_option_count? @selected_option_count = 0 for option in @form_field.options @selected_option_count += 1 if option.selected return @selected_option_count choices_click: (evt) -> evt.preventDefault() this.results_show() unless @results_showing keyup_checker: (evt) -> stroke = evt.which ? evt.keyCode this.search_field_scale() switch stroke when 8 if @is_multiple and @backstroke_length < 1 and this.choices_count() > 0 this.keydown_backstroke() else if not @pending_backstroke this.result_clear_highlight() this.results_search() when 13 evt.preventDefault() this.result_select(evt) if this.results_showing when 27 this.results_hide() if @results_showing return true when 9, 38, 40, 16, 91, 17 # don't do anything on these keys else this.results_search() generate_field_id: -> new_id = this.generate_random_id() @form_field.id = new_id new_id generate_random_char: -> chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" rand = Math.floor(Math.random() * chars.length) newchar = chars.substring rand, rand+1 container_width: -> return if @options.width? then @options.width else "#{@form_field.offsetWidth}px" # class methods and variables ============================================================ @browser_is_supported: -> if window.navigator.appName == "Microsoft Internet Explorer" return null isnt document.documentMode >= 8 return true @default_multiple_text: "Select Some Options" @default_single_text: "Select an Option" @default_no_result_text: "No results match" root.AbstractChosen = AbstractChosen chosen-0.9.15/coffee/chosen.proto.coffee0000644000175000017500000004722112153204007017072 0ustar iliasilias### Chosen source: generate output using 'cake build' Copyright (c) 2011 by Harvest ### root = this class Chosen extends AbstractChosen setup: -> @current_selectedIndex = @form_field.selectedIndex @is_rtl = @form_field.hasClassName "chzn-rtl" finish_setup: -> @form_field.addClassName "chzn-done" set_default_values: -> super() # HTML Templates @single_temp = new Template('#{default}
      ') @multi_temp = new Template('
        ') @no_results_temp = new Template('
      • ' + @results_none_found + ' "#{terms}"
      • ') set_up_html: -> @container_id = @form_field.identify().replace(/[^\w]/g, '_') + "_chzn" container_classes = ["chzn-container"] container_classes.push "chzn-container-" + (if @is_multiple then "multi" else "single") container_classes.push @form_field.className if @inherit_select_classes && @form_field.className container_classes.push "chzn-rtl" if @is_rtl container_props = 'id': @container_id 'class': container_classes.join ' ' 'style': "width: #{this.container_width()};" 'title': @form_field.title @container = if @is_multiple then new Element('div', container_props).update( @multi_temp.evaluate({ "default": @default_text}) ) else new Element('div', container_props).update( @single_temp.evaluate({ "default":@default_text }) ) @form_field.hide().insert({ after: @container }) @dropdown = @container.down('div.chzn-drop') @search_field = @container.down('input') @search_results = @container.down('ul.chzn-results') this.search_field_scale() @search_no_results = @container.down('li.no-results') if @is_multiple @search_choices = @container.down('ul.chzn-choices') @search_container = @container.down('li.search-field') else @search_container = @container.down('div.chzn-search') @selected_item = @container.down('.chzn-single') this.results_build() this.set_tab_index() this.set_label_behavior() @form_field.fire("liszt:ready", {chosen: this}) register_observers: -> @container.observe "mousedown", (evt) => this.container_mousedown(evt) @container.observe "mouseup", (evt) => this.container_mouseup(evt) @container.observe "mouseenter", (evt) => this.mouse_enter(evt) @container.observe "mouseleave", (evt) => this.mouse_leave(evt) @search_results.observe "mouseup", (evt) => this.search_results_mouseup(evt) @search_results.observe "mouseover", (evt) => this.search_results_mouseover(evt) @search_results.observe "mouseout", (evt) => this.search_results_mouseout(evt) @search_results.observe "mousewheel", (evt) => this.search_results_mousewheel(evt) @search_results.observe "DOMMouseScroll", (evt) => this.search_results_mousewheel(evt) @form_field.observe "liszt:updated", (evt) => this.results_update_field(evt) @form_field.observe "liszt:activate", (evt) => this.activate_field(evt) @form_field.observe "liszt:open", (evt) => this.container_mousedown(evt) @search_field.observe "blur", (evt) => this.input_blur(evt) @search_field.observe "keyup", (evt) => this.keyup_checker(evt) @search_field.observe "keydown", (evt) => this.keydown_checker(evt) @search_field.observe "focus", (evt) => this.input_focus(evt) if @is_multiple @search_choices.observe "click", (evt) => this.choices_click(evt) else @container.observe "click", (evt) => evt.preventDefault() # gobble click of anchor search_field_disabled: -> @is_disabled = @form_field.disabled if(@is_disabled) @container.addClassName 'chzn-disabled' @search_field.disabled = true @selected_item.stopObserving "focus", @activate_action if !@is_multiple this.close_field() else @container.removeClassName 'chzn-disabled' @search_field.disabled = false @selected_item.observe "focus", @activate_action if !@is_multiple container_mousedown: (evt) -> if !@is_disabled if evt and evt.type is "mousedown" and not @results_showing evt.stop() if not (evt? and evt.target.hasClassName "search-choice-close") if not @active_field @search_field.clear() if @is_multiple document.observe "click", @click_test_action this.results_show() else if not @is_multiple and evt and (evt.target is @selected_item || evt.target.up("a.chzn-single")) this.results_toggle() this.activate_field() container_mouseup: (evt) -> this.results_reset(evt) if evt.target.nodeName is "ABBR" and not @is_disabled search_results_mousewheel: (evt) -> delta = -evt.wheelDelta or evt.detail if delta? evt.preventDefault() delta = delta * 40 if evt.type is 'DOMMouseScroll' @search_results.scrollTop = delta + @search_results.scrollTop blur_test: (evt) -> this.close_field() if not @active_field and @container.hasClassName("chzn-container-active") close_field: -> document.stopObserving "click", @click_test_action @active_field = false this.results_hide() @container.removeClassName "chzn-container-active" this.winnow_results_clear() this.clear_backstroke() this.show_search_field_default() this.search_field_scale() activate_field: -> @container.addClassName "chzn-container-active" @active_field = true @search_field.value = @search_field.value @search_field.focus() test_active_click: (evt) -> if evt.target.up('#' + @container_id) @active_field = true else this.close_field() results_build: -> @parsing = true @selected_option_count = null @results_data = root.SelectParser.select_to_array @form_field if @is_multiple and this.choices_count() > 0 @search_choices.select("li.search-choice").invoke("remove") else if not @is_multiple @selected_item.addClassName("chzn-default").down("span").update(@default_text) if @disable_search or @form_field.options.length <= @disable_search_threshold @container.addClassName "chzn-container-single-nosearch" else @container.removeClassName "chzn-container-single-nosearch" content = '' for data in @results_data if data.group content += this.result_add_group data else if !data.empty content += this.result_add_option data if data.selected and @is_multiple this.choice_build data else if data.selected and not @is_multiple @selected_item.removeClassName("chzn-default").down("span").update( data.html ) this.single_deselect_control_build() if @allow_single_deselect this.search_field_disabled() this.show_search_field_default() this.search_field_scale() @search_results.update content @parsing = false result_add_group: (group) -> if not group.disabled group.dom_id = @container_id + "_g_" + group.array_index '
      • ' + group.label.escapeHTML() + '
      • ' else "" result_do_highlight: (el) -> this.result_clear_highlight() @result_highlight = el @result_highlight.addClassName "highlighted" maxHeight = parseInt @search_results.getStyle('maxHeight'), 10 visible_top = @search_results.scrollTop visible_bottom = maxHeight + visible_top high_top = @result_highlight.positionedOffset().top + @search_results.scrollTop high_bottom = high_top + @result_highlight.getHeight() if high_bottom >= visible_bottom @search_results.scrollTop = if (high_bottom - maxHeight) > 0 then (high_bottom - maxHeight) else 0 else if high_top < visible_top @search_results.scrollTop = high_top result_clear_highlight: -> @result_highlight.removeClassName('highlighted') if @result_highlight @result_highlight = null results_show: -> if @result_single_selected? this.result_do_highlight @result_single_selected else if @is_multiple and @max_selected_options <= this.choices_count() @form_field.fire("liszt:maxselected", {chosen: this}) return false @container.addClassName "chzn-with-drop" @form_field.fire("liszt:showing_dropdown", {chosen: this}) @results_showing = true @search_field.focus() @search_field.value = @search_field.value this.winnow_results() results_hide: -> this.result_clear_highlight() @container.removeClassName "chzn-with-drop" @form_field.fire("liszt:hiding_dropdown", {chosen: this}) @results_showing = false set_tab_index: (el) -> if @form_field.tabIndex ti = @form_field.tabIndex @form_field.tabIndex = -1 @search_field.tabIndex = ti set_label_behavior: -> @form_field_label = @form_field.up("label") # first check for a parent label if not @form_field_label? @form_field_label = $$("label[for='#{@form_field.id}']").first() #next check for a for=#{id} if @form_field_label? @form_field_label.observe "click", (evt) => if @is_multiple then this.container_mousedown(evt) else this.activate_field() show_search_field_default: -> if @is_multiple and this.choices_count() < 1 and not @active_field @search_field.value = @default_text @search_field.addClassName "default" else @search_field.value = "" @search_field.removeClassName "default" search_results_mouseup: (evt) -> target = if evt.target.hasClassName("active-result") then evt.target else evt.target.up(".active-result") if target @result_highlight = target this.result_select(evt) @search_field.focus() search_results_mouseover: (evt) -> target = if evt.target.hasClassName("active-result") then evt.target else evt.target.up(".active-result") this.result_do_highlight( target ) if target search_results_mouseout: (evt) -> this.result_clear_highlight() if evt.target.hasClassName('active-result') or evt.target.up('.active-result') choice_build: (item) -> choice = new Element('li', { class: "search-choice" }).update("#{item.html}") if item.disabled choice.addClassName 'search-choice-disabled' else close_link = new Element('a', { href: '#', class: 'search-choice-close', rel: item.array_index }) close_link.observe "click", (evt) => this.choice_destroy_link_click(evt) choice.insert close_link @search_container.insert { before: choice } choice_destroy_link_click: (evt) -> evt.preventDefault() evt.stopPropagation() this.choice_destroy evt.target unless @is_disabled choice_destroy: (link) -> if this.result_deselect link.readAttribute("rel") this.show_search_field_default() this.results_hide() if @is_multiple and this.choices_count() > 0 and @search_field.value.length < 1 link.up('li').remove() this.search_field_scale() results_reset: -> @form_field.options[0].selected = true @selected_option_count = null @selected_item.down("span").update(@default_text) @selected_item.addClassName("chzn-default") if not @is_multiple this.show_search_field_default() this.results_reset_cleanup() @form_field.simulate("change") if typeof Event.simulate is 'function' this.results_hide() if @active_field results_reset_cleanup: -> @current_selectedIndex = @form_field.selectedIndex deselect_trigger = @selected_item.down("abbr") deselect_trigger.remove() if(deselect_trigger) result_select: (evt) -> if @result_highlight high = @result_highlight this.result_clear_highlight() if @is_multiple and @max_selected_options <= this.choices_count() @form_field.fire("liszt:maxselected", {chosen: this}) return false if @is_multiple this.result_deactivate high else @search_results.descendants(".result-selected").invoke "removeClassName", "result-selected" @selected_item.removeClassName("chzn-default") @result_single_selected = high high.addClassName("result-selected") position = high.id.substr(high.id.lastIndexOf("_") + 1 ) item = @results_data[position] item.selected = true @form_field.options[item.options_index].selected = true @selected_option_count = null if @is_multiple this.choice_build item else @selected_item.down("span").update(item.html) this.single_deselect_control_build() if @allow_single_deselect this.results_hide() unless (evt.metaKey or evt.ctrlKey) and @is_multiple @search_field.value = "" @form_field.simulate("change") if typeof Event.simulate is 'function' && (@is_multiple || @form_field.selectedIndex != @current_selectedIndex) @current_selectedIndex = @form_field.selectedIndex this.search_field_scale() result_activate: (el) -> el.addClassName("active-result") result_deactivate: (el) -> el.removeClassName("active-result") result_deselect: (pos) -> result_data = @results_data[pos] if not @form_field.options[result_data.options_index].disabled result_data.selected = false @form_field.options[result_data.options_index].selected = false @selected_option_count = null result = $(@container_id + "_o_" + pos) result.removeClassName("result-selected").addClassName("active-result").show() this.result_clear_highlight() this.winnow_results() @form_field.simulate("change") if typeof Event.simulate is 'function' this.search_field_scale() return true else return false single_deselect_control_build: -> @selected_item.down("span").insert { after: "" } if @allow_single_deselect and not @selected_item.down("abbr") winnow_results: -> this.no_results_clear() results = 0 searchText = if @search_field.value is @default_text then "" else @search_field.value.strip().escapeHTML() regexAnchor = if @search_contains then "" else "^" regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') for option in @results_data if not option.disabled and not option.empty if option.group $(option.dom_id).hide() else if not (@is_multiple and option.selected) found = false result_id = option.dom_id if regex.test option.html found = true results += 1 else if @enable_split_word_search and (option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0) #TODO: replace this substitution of /\[\]/ with a list of characters to skip. parts = option.html.replace(/\[|\]/g, "").split(" ") if parts.length for part in parts if regex.test part found = true results += 1 if found if searchText.length startpos = option.html.search zregex text = option.html.substr(0, startpos + searchText.length) + '' + option.html.substr(startpos + searchText.length) text = text.substr(0, startpos) + '' + text.substr(startpos) else text = option.html $(result_id).update text if $(result_id).innerHTML != text this.result_activate $(result_id) $(@results_data[option.group_array_index].dom_id).setStyle({display: 'list-item'}) if option.group_array_index? else this.result_clear_highlight() if $(result_id) is @result_highlight this.result_deactivate $(result_id) if results < 1 and searchText.length this.no_results(searchText) else this.winnow_results_set_highlight() winnow_results_clear: -> @search_field.clear() lis = @search_results.select("li") for li in lis if li.hasClassName("group-result") li.show() else if not @is_multiple or not li.hasClassName("result-selected") this.result_activate li winnow_results_set_highlight: -> if not @result_highlight if not @is_multiple do_high = @search_results.down(".result-selected.active-result") if not do_high? do_high = @search_results.down(".active-result") this.result_do_highlight do_high if do_high? no_results: (terms) -> @search_results.insert @no_results_temp.evaluate( terms: terms ) no_results_clear: -> nr = null nr.remove() while nr = @search_results.down(".no-results") keydown_arrow: -> actives = @search_results.select("li.active-result") if actives.length if not @result_highlight this.result_do_highlight actives.first() else if @results_showing sibs = @result_highlight.nextSiblings() nexts = sibs.intersect(actives) this.result_do_highlight nexts.first() if nexts.length this.results_show() if not @results_showing keyup_arrow: -> if not @results_showing and not @is_multiple this.results_show() else if @result_highlight sibs = @result_highlight.previousSiblings() actives = @search_results.select("li.active-result") prevs = sibs.intersect(actives) if prevs.length this.result_do_highlight prevs.first() else this.results_hide() if this.choices_count() > 0 this.result_clear_highlight() keydown_backstroke: -> if @pending_backstroke this.choice_destroy @pending_backstroke.down("a") this.clear_backstroke() else next_available_destroy = @search_container.siblings().last() if next_available_destroy and next_available_destroy.hasClassName("search-choice") and not next_available_destroy.hasClassName("search-choice-disabled") @pending_backstroke = next_available_destroy @pending_backstroke.addClassName("search-choice-focus") if @pending_backstroke if @single_backstroke_delete @keydown_backstroke() else @pending_backstroke.addClassName("search-choice-focus") clear_backstroke: -> @pending_backstroke.removeClassName("search-choice-focus") if @pending_backstroke @pending_backstroke = null keydown_checker: (evt) -> stroke = evt.which ? evt.keyCode this.search_field_scale() this.clear_backstroke() if stroke != 8 and this.pending_backstroke switch stroke when 8 @backstroke_length = this.search_field.value.length break when 9 this.result_select(evt) if this.results_showing and not @is_multiple @mouse_on_container = false break when 13 evt.preventDefault() break when 38 evt.preventDefault() this.keyup_arrow() break when 40 this.keydown_arrow() break search_field_scale: -> if @is_multiple h = 0 w = 0 style_block = "position:absolute; left: -1000px; top: -1000px; display:none;" styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing'] for style in styles style_block += style + ":" + @search_field.getStyle(style) + ";" div = new Element('div', { 'style' : style_block }).update(@search_field.value.escapeHTML()) document.body.appendChild(div) w = Element.measure(div, 'width') + 25 div.remove() @f_width = @container.getWidth() unless @f_width if( w > @f_width-10 ) w = @f_width - 10 @search_field.setStyle({'width': w + 'px'}) root.Chosen = Chosen chosen-0.9.15/coffee/chosen.jquery.coffee0000644000175000017500000005010212153204007017236 0ustar iliasilias### Chosen source: generate output using 'cake build' Copyright (c) 2011 by Harvest ### root = this $ = jQuery $.fn.extend({ chosen: (options) -> # Do no harm and return as soon as possible for unsupported browsers, namely IE6 and IE7 # Continue on if running IE document type but in compatibility mode return this unless AbstractChosen.browser_is_supported() this.each((input_field) -> $this = $ this $this.data('chosen', new Chosen(this, options)) unless $this.hasClass "chzn-done" ) }) class Chosen extends AbstractChosen setup: -> @form_field_jq = $ @form_field @current_selectedIndex = @form_field.selectedIndex @is_rtl = @form_field_jq.hasClass "chzn-rtl" finish_setup: -> @form_field_jq.addClass "chzn-done" set_up_html: -> @container_id = if @form_field.id.length then @form_field.id.replace(/[^\w]/g, '_') else this.generate_field_id() @container_id += "_chzn" container_classes = ["chzn-container"] container_classes.push "chzn-container-" + (if @is_multiple then "multi" else "single") container_classes.push @form_field.className if @inherit_select_classes && @form_field.className container_classes.push "chzn-rtl" if @is_rtl container_props = 'id': @container_id 'class': container_classes.join ' ' 'style': "width: #{this.container_width()};" 'title': @form_field.title @container = ($ "
        ", container_props) if @is_multiple @container.html '
          ' else @container.html '' + @default_text + '
            ' @form_field_jq.hide().after @container @dropdown = @container.find('div.chzn-drop').first() @search_field = @container.find('input').first() @search_results = @container.find('ul.chzn-results').first() this.search_field_scale() @search_no_results = @container.find('li.no-results').first() if @is_multiple @search_choices = @container.find('ul.chzn-choices').first() @search_container = @container.find('li.search-field').first() else @search_container = @container.find('div.chzn-search').first() @selected_item = @container.find('.chzn-single').first() this.results_build() this.set_tab_index() this.set_label_behavior() @form_field_jq.trigger("liszt:ready", {chosen: this}) register_observers: -> @container.mousedown (evt) => this.container_mousedown(evt); return @container.mouseup (evt) => this.container_mouseup(evt); return @container.mouseenter (evt) => this.mouse_enter(evt); return @container.mouseleave (evt) => this.mouse_leave(evt); return @search_results.mouseup (evt) => this.search_results_mouseup(evt); return @search_results.mouseover (evt) => this.search_results_mouseover(evt); return @search_results.mouseout (evt) => this.search_results_mouseout(evt); return @search_results.bind 'mousewheel DOMMouseScroll', (evt) => this.search_results_mousewheel(evt); return @form_field_jq.bind "liszt:updated", (evt) => this.results_update_field(evt); return @form_field_jq.bind "liszt:activate", (evt) => this.activate_field(evt); return @form_field_jq.bind "liszt:open", (evt) => this.container_mousedown(evt); return @search_field.blur (evt) => this.input_blur(evt); return @search_field.keyup (evt) => this.keyup_checker(evt); return @search_field.keydown (evt) => this.keydown_checker(evt); return @search_field.focus (evt) => this.input_focus(evt); return if @is_multiple @search_choices.click (evt) => this.choices_click(evt); return else @container.click (evt) => evt.preventDefault(); return # gobble click of anchor search_field_disabled: -> @is_disabled = @form_field_jq[0].disabled if(@is_disabled) @container.addClass 'chzn-disabled' @search_field[0].disabled = true @selected_item.unbind "focus", @activate_action if !@is_multiple this.close_field() else @container.removeClass 'chzn-disabled' @search_field[0].disabled = false @selected_item.bind "focus", @activate_action if !@is_multiple container_mousedown: (evt) -> if !@is_disabled if evt and evt.type is "mousedown" and not @results_showing evt.preventDefault() if not (evt? and ($ evt.target).hasClass "search-choice-close") if not @active_field @search_field.val "" if @is_multiple $(document).click @click_test_action this.results_show() else if not @is_multiple and evt and (($(evt.target)[0] == @selected_item[0]) || $(evt.target).parents("a.chzn-single").length) evt.preventDefault() this.results_toggle() this.activate_field() container_mouseup: (evt) -> this.results_reset(evt) if evt.target.nodeName is "ABBR" and not @is_disabled search_results_mousewheel: (evt) -> delta = -evt.originalEvent?.wheelDelta or evt.originialEvent?.detail if delta? evt.preventDefault() delta = delta * 40 if evt.type is 'DOMMouseScroll' @search_results.scrollTop(delta + @search_results.scrollTop()) blur_test: (evt) -> this.close_field() if not @active_field and @container.hasClass "chzn-container-active" close_field: -> $(document).unbind "click", @click_test_action @active_field = false this.results_hide() @container.removeClass "chzn-container-active" this.winnow_results_clear() this.clear_backstroke() this.show_search_field_default() this.search_field_scale() activate_field: -> @container.addClass "chzn-container-active" @active_field = true @search_field.val(@search_field.val()) @search_field.focus() test_active_click: (evt) -> if $(evt.target).parents('#' + @container_id).length @active_field = true else this.close_field() results_build: -> @parsing = true @selected_option_count = null @results_data = root.SelectParser.select_to_array @form_field if @is_multiple and this.choices_count() > 0 @search_choices.find("li.search-choice").remove() else if not @is_multiple @selected_item.addClass("chzn-default").find("span").text(@default_text) if @disable_search or @form_field.options.length <= @disable_search_threshold @container.addClass "chzn-container-single-nosearch" else @container.removeClass "chzn-container-single-nosearch" content = '' for data in @results_data if data.group content += this.result_add_group data else if !data.empty content += this.result_add_option data if data.selected and @is_multiple this.choice_build data else if data.selected and not @is_multiple @selected_item.removeClass("chzn-default").find("span").text data.text this.single_deselect_control_build() if @allow_single_deselect this.search_field_disabled() this.show_search_field_default() this.search_field_scale() @search_results.html content @parsing = false result_add_group: (group) -> if not group.disabled group.dom_id = @container_id + "_g_" + group.array_index '
          • ' + $("
            ").text(group.label).html() + '
          • ' else "" result_do_highlight: (el) -> if el.length this.result_clear_highlight() @result_highlight = el @result_highlight.addClass "highlighted" maxHeight = parseInt @search_results.css("maxHeight"), 10 visible_top = @search_results.scrollTop() visible_bottom = maxHeight + visible_top high_top = @result_highlight.position().top + @search_results.scrollTop() high_bottom = high_top + @result_highlight.outerHeight() if high_bottom >= visible_bottom @search_results.scrollTop if (high_bottom - maxHeight) > 0 then (high_bottom - maxHeight) else 0 else if high_top < visible_top @search_results.scrollTop high_top result_clear_highlight: -> @result_highlight.removeClass "highlighted" if @result_highlight @result_highlight = null results_show: -> if @result_single_selected? this.result_do_highlight @result_single_selected else if @is_multiple and @max_selected_options <= this.choices_count() @form_field_jq.trigger("liszt:maxselected", {chosen: this}) return false @container.addClass "chzn-with-drop" @form_field_jq.trigger("liszt:showing_dropdown", {chosen: this}) @results_showing = true @search_field.focus() @search_field.val @search_field.val() this.winnow_results() results_hide: -> this.result_clear_highlight() @container.removeClass "chzn-with-drop" @form_field_jq.trigger("liszt:hiding_dropdown", {chosen: this}) @results_showing = false set_tab_index: (el) -> if @form_field_jq.attr "tabindex" ti = @form_field_jq.attr "tabindex" @form_field_jq.attr "tabindex", -1 @search_field.attr "tabindex", ti set_label_behavior: -> @form_field_label = @form_field_jq.parents("label") # first check for a parent label if not @form_field_label.length and @form_field.id.length @form_field_label = $("label[for='#{@form_field.id}']") #next check for a for=#{id} if @form_field_label.length > 0 @form_field_label.click (evt) => if @is_multiple then this.container_mousedown(evt) else this.activate_field() show_search_field_default: -> if @is_multiple and this.choices_count() < 1 and not @active_field @search_field.val(@default_text) @search_field.addClass "default" else @search_field.val("") @search_field.removeClass "default" search_results_mouseup: (evt) -> target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first() if target.length @result_highlight = target this.result_select(evt) @search_field.focus() search_results_mouseover: (evt) -> target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first() this.result_do_highlight( target ) if target search_results_mouseout: (evt) -> this.result_clear_highlight() if $(evt.target).hasClass "active-result" or $(evt.target).parents('.active-result').first() choice_build: (item) -> choice = $('
          • ', { class: "search-choice" }).html("#{item.html}") if item.disabled choice.addClass 'search-choice-disabled' else close_link = $('', { href: '#', class: 'search-choice-close', rel: item.array_index }) close_link.click (evt) => this.choice_destroy_link_click(evt) choice.append close_link @search_container.before choice choice_destroy_link_click: (evt) -> evt.preventDefault() evt.stopPropagation() this.choice_destroy $(evt.target) unless @is_disabled choice_destroy: (link) -> if this.result_deselect (link.attr "rel") this.show_search_field_default() this.results_hide() if @is_multiple and this.choices_count() > 0 and @search_field.val().length < 1 link.parents('li').first().remove() this.search_field_scale() results_reset: -> @form_field.options[0].selected = true @selected_option_count = null @selected_item.find("span").text @default_text @selected_item.addClass("chzn-default") if not @is_multiple this.show_search_field_default() this.results_reset_cleanup() @form_field_jq.trigger "change" this.results_hide() if @active_field results_reset_cleanup: -> @current_selectedIndex = @form_field.selectedIndex @selected_item.find("abbr").remove() result_select: (evt) -> if @result_highlight high = @result_highlight high_id = high.attr "id" this.result_clear_highlight() if @is_multiple and @max_selected_options <= this.choices_count() @form_field_jq.trigger("liszt:maxselected", {chosen: this}) return false if @is_multiple this.result_deactivate high else @search_results.find(".result-selected").removeClass "result-selected" @result_single_selected = high @selected_item.removeClass("chzn-default") high.addClass "result-selected" position = high_id.substr(high_id.lastIndexOf("_") + 1 ) item = @results_data[position] item.selected = true @form_field.options[item.options_index].selected = true @selected_option_count = null if @is_multiple this.choice_build item else @selected_item.find("span").first().text item.text this.single_deselect_control_build() if @allow_single_deselect this.results_hide() unless (evt.metaKey or evt.ctrlKey) and @is_multiple @search_field.val "" @form_field_jq.trigger "change", {'selected': @form_field.options[item.options_index].value} if @is_multiple || @form_field.selectedIndex != @current_selectedIndex @current_selectedIndex = @form_field.selectedIndex this.search_field_scale() result_activate: (el) -> el.addClass("active-result") result_deactivate: (el) -> el.removeClass("active-result") result_deselect: (pos) -> result_data = @results_data[pos] if not @form_field.options[result_data.options_index].disabled result_data.selected = false @form_field.options[result_data.options_index].selected = false @selected_option_count = null result = $("#" + @container_id + "_o_" + pos) result.removeClass("result-selected").addClass("active-result").show() this.result_clear_highlight() this.winnow_results() @form_field_jq.trigger "change", {deselected: @form_field.options[result_data.options_index].value} this.search_field_scale() return true else return false single_deselect_control_build: -> @selected_item.find("span").first().after "" if @allow_single_deselect and @selected_item.find("abbr").length < 1 winnow_results: -> this.no_results_clear() results = 0 searchText = if @search_field.val() is @default_text then "" else $('
            ').text($.trim(@search_field.val())).html() regexAnchor = if @search_contains then "" else "^" regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i') for option in @results_data if not option.disabled and not option.empty if option.group $('#' + option.dom_id).css('display', 'none') else if not (@is_multiple and option.selected) found = false result_id = option.dom_id result = $("#" + result_id) if regex.test option.html found = true results += 1 else if @enable_split_word_search and (option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0) #TODO: replace this substitution of /\[\]/ with a list of characters to skip. parts = option.html.replace(/\[|\]/g, "").split(" ") if parts.length for part in parts if regex.test part found = true results += 1 if found if searchText.length startpos = option.html.search zregex text = option.html.substr(0, startpos + searchText.length) + '' + option.html.substr(startpos + searchText.length) text = text.substr(0, startpos) + '' + text.substr(startpos) else text = option.html result.html(text) this.result_activate result $("#" + @results_data[option.group_array_index].dom_id).css('display', 'list-item') if option.group_array_index? else this.result_clear_highlight() if @result_highlight and result_id is @result_highlight.attr 'id' this.result_deactivate result if results < 1 and searchText.length this.no_results searchText else this.winnow_results_set_highlight() winnow_results_clear: -> @search_field.val "" lis = @search_results.find("li") for li in lis li = $(li) if li.hasClass "group-result" li.css('display', 'auto') else if not @is_multiple or not li.hasClass "result-selected" this.result_activate li winnow_results_set_highlight: -> if not @result_highlight selected_results = if not @is_multiple then @search_results.find(".result-selected.active-result") else [] do_high = if selected_results.length then selected_results.first() else @search_results.find(".active-result").first() this.result_do_highlight do_high if do_high? no_results: (terms) -> no_results_html = $('
          • ' + @results_none_found + ' ""
          • ') no_results_html.find("span").first().html(terms) @search_results.append no_results_html no_results_clear: -> @search_results.find(".no-results").remove() keydown_arrow: -> if not @result_highlight first_active = @search_results.find("li.active-result").first() this.result_do_highlight $(first_active) if first_active else if @results_showing next_sib = @result_highlight.nextAll("li.active-result").first() this.result_do_highlight next_sib if next_sib this.results_show() if not @results_showing keyup_arrow: -> if not @results_showing and not @is_multiple this.results_show() else if @result_highlight prev_sibs = @result_highlight.prevAll("li.active-result") if prev_sibs.length this.result_do_highlight prev_sibs.first() else this.results_hide() if this.choices_count() > 0 this.result_clear_highlight() keydown_backstroke: -> if @pending_backstroke this.choice_destroy @pending_backstroke.find("a").first() this.clear_backstroke() else next_available_destroy = @search_container.siblings("li.search-choice").last() if next_available_destroy.length and not next_available_destroy.hasClass("search-choice-disabled") @pending_backstroke = next_available_destroy if @single_backstroke_delete @keydown_backstroke() else @pending_backstroke.addClass "search-choice-focus" clear_backstroke: -> @pending_backstroke.removeClass "search-choice-focus" if @pending_backstroke @pending_backstroke = null keydown_checker: (evt) -> stroke = evt.which ? evt.keyCode this.search_field_scale() this.clear_backstroke() if stroke != 8 and this.pending_backstroke switch stroke when 8 @backstroke_length = this.search_field.val().length break when 9 this.result_select(evt) if this.results_showing and not @is_multiple @mouse_on_container = false break when 13 evt.preventDefault() break when 38 evt.preventDefault() this.keyup_arrow() break when 40 this.keydown_arrow() break search_field_scale: -> if @is_multiple h = 0 w = 0 style_block = "position:absolute; left: -1000px; top: -1000px; display:none;" styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing'] for style in styles style_block += style + ":" + @search_field.css(style) + ";" div = $('
            ', { 'style' : style_block }) div.text @search_field.val() $('body').append div w = div.width() + 25 div.remove() @f_width = @container.outerWidth() unless @f_width if( w > @f_width-10 ) w = @f_width - 10 @search_field.css({'width': w + 'px'}) generate_random_id: -> string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char() while $("#" + string).length > 0 string += this.generate_random_char() string root.Chosen = Chosen chosen-0.9.15/chosen/0000755000175000017500000000000013024735377013343 5ustar iliasiliaschosen-0.9.15/chosen/chosen.css0000644000175000017500000003652112153204007015322 0ustar iliasilias/* @group Base */ .chzn-container { font-size: 13px; position: relative; display: inline-block; vertical-align: middle; zoom: 1; *display: inline; } .chzn-container .chzn-drop { background: #fff; border: 1px solid #aaa; border-top: 0; position: absolute; top: 100%; left: -9999px; -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15); -moz-box-shadow : 0 4px 5px rgba(0,0,0,.15); box-shadow : 0 4px 5px rgba(0,0,0,.15); z-index: 1010; width: 100%; -moz-box-sizing : border-box; -ms-box-sizing : border-box; -webkit-box-sizing: border-box; -khtml-box-sizing : border-box; box-sizing : border-box; } .chzn-container.chzn-with-drop .chzn-drop { left: 0; } /* @end */ /* @group Single Chosen */ .chzn-container-single .chzn-single { background-color: #ffffff; filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0 ); background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4)); background-image: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); background-image: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); background-image: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); background-image: linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%); -webkit-border-radius: 5px; -moz-border-radius : 5px; border-radius : 5px; -moz-background-clip : padding; -webkit-background-clip: padding-box; background-clip : padding-box; border: 1px solid #aaaaaa; -webkit-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1); -moz-box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1); box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1); display: block; overflow: hidden; white-space: nowrap; position: relative; height: 23px; line-height: 24px; padding: 0 0 0 8px; color: #444444; text-decoration: none; } .chzn-container-single .chzn-default { color: #999; } .chzn-container-single .chzn-single span { margin-right: 26px; display: block; overflow: hidden; white-space: nowrap; -o-text-overflow: ellipsis; -ms-text-overflow: ellipsis; text-overflow: ellipsis; } .chzn-container-single .chzn-single abbr { display: block; position: absolute; right: 26px; top: 6px; width: 12px; height: 12px; font-size: 1px; background: url('chosen-sprite.png') -42px 1px no-repeat; } .chzn-container-single .chzn-single abbr:hover { background-position: -42px -10px; } .chzn-container-single.chzn-disabled .chzn-single abbr:hover { background-position: -42px -10px; } .chzn-container-single .chzn-single div { position: absolute; right: 0; top: 0; display: block; height: 100%; width: 18px; } .chzn-container-single .chzn-single div b { background: url('chosen-sprite.png') no-repeat 0px 2px; display: block; width: 100%; height: 100%; } .chzn-container-single .chzn-search { padding: 3px 4px; position: relative; margin: 0; white-space: nowrap; z-index: 1010; } .chzn-container-single .chzn-search input { background: #fff url('chosen-sprite.png') no-repeat 100% -20px; background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%); margin: 1px 0; padding: 4px 20px 4px 5px; outline: 0; border: 1px solid #aaa; font-family: sans-serif; font-size: 1em; width: 100%; -moz-box-sizing : border-box; -ms-box-sizing : border-box; -webkit-box-sizing: border-box; -khtml-box-sizing : border-box; box-sizing : border-box; } .chzn-container-single .chzn-drop { margin-top: -1px; -webkit-border-radius: 0 0 4px 4px; -moz-border-radius : 0 0 4px 4px; border-radius : 0 0 4px 4px; -moz-background-clip : padding; -webkit-background-clip: padding-box; background-clip : padding-box; } .chzn-container-single-nosearch .chzn-search { position: absolute; left: -9999px; } /* @end */ /* @group Multi Chosen */ .chzn-container-multi .chzn-choices { background-color: #fff; background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background-image: linear-gradient(#eeeeee 1%, #ffffff 15%); border: 1px solid #aaa; margin: 0; padding: 0; cursor: text; overflow: hidden; height: auto !important; height: 1%; position: relative; width: 100%; -moz-box-sizing : border-box; -ms-box-sizing : border-box; -webkit-box-sizing: border-box; -khtml-box-sizing : border-box; box-sizing : border-box; } .chzn-container-multi .chzn-choices li { float: left; list-style: none; } .chzn-container-multi .chzn-choices .search-field { white-space: nowrap; margin: 0; padding: 0; } .chzn-container-multi .chzn-choices .search-field input { color: #666; background: transparent !important; border: 0 !important; font-family: sans-serif; font-size: 100%; height: 15px; padding: 5px; margin: 1px 0; outline: 0; -webkit-box-shadow: none; -moz-box-shadow : none; box-shadow : none; } .chzn-container-multi .chzn-choices .search-field .default { color: #999; } .chzn-container-multi .chzn-choices .search-choice { -webkit-border-radius: 3px; -moz-border-radius : 3px; border-radius : 3px; -moz-background-clip : padding; -webkit-background-clip: padding-box; background-clip : padding-box; background-color: #e4e4e4; filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 ); background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); -moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05); color: #333; border: 1px solid #aaaaaa; line-height: 13px; padding: 3px 20px 3px 5px; margin: 3px 0 3px 5px; position: relative; cursor: default; } .chzn-container-multi .chzn-choices .search-choice.search-choice-disabled { background-color: #e4e4e4; filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 ); background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee)); background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%); color: #666; border: 1px solid #cccccc; padding-right: 5px; } .chzn-container-multi .chzn-choices .search-choice-focus { background: #d4d4d4; } .chzn-container-multi .chzn-choices .search-choice .search-choice-close { display: block; position: absolute; right: 3px; top: 4px; width: 12px; height: 12px; font-size: 1px; background: url('chosen-sprite.png') -42px 1px no-repeat; } .chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { background-position: -42px -10px; } .chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close { background-position: -42px -10px; } /* @end */ /* @group Results */ .chzn-container .chzn-results { margin: 0 4px 4px 0; max-height: 240px; padding: 0 0 0 4px; position: relative; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; } .chzn-container-multi .chzn-results { margin: 0; padding: 0; } .chzn-container .chzn-results li { display: none; line-height: 15px; padding: 5px 6px; margin: 0; list-style: none; } .chzn-container .chzn-results .active-result { cursor: pointer; display: list-item; } .chzn-container .chzn-results .highlighted { background-color: #3875d7; filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3875d7', endColorstr='#2a62bc', GradientType=0 ); background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc)); background-image: -webkit-linear-gradient(top, #3875d7 20%, #2a62bc 90%); background-image: -moz-linear-gradient(top, #3875d7 20%, #2a62bc 90%); background-image: -o-linear-gradient(top, #3875d7 20%, #2a62bc 90%); background-image: linear-gradient(#3875d7 20%, #2a62bc 90%); color: #fff; } .chzn-container .chzn-results li em { background: #feffde; font-style: normal; } .chzn-container .chzn-results .highlighted em { background: transparent; } .chzn-container .chzn-results .no-results { background: #f4f4f4; display: list-item; } .chzn-container .chzn-results .group-result { cursor: default; color: #999; font-weight: bold; } .chzn-container .chzn-results .group-option { padding-left: 15px; } .chzn-container-multi .chzn-drop .result-selected { display: none; } .chzn-container .chzn-results-scroll { background: white; margin: 0 4px; position: absolute; text-align: center; width: 321px; /* This should by dynamic with js */ z-index: 1; } .chzn-container .chzn-results-scroll span { display: inline-block; height: 17px; text-indent: -5000px; width: 9px; } .chzn-container .chzn-results-scroll-down { bottom: 0; } .chzn-container .chzn-results-scroll-down span { background: url('chosen-sprite.png') no-repeat -4px -3px; } .chzn-container .chzn-results-scroll-up span { background: url('chosen-sprite.png') no-repeat -22px -3px; } /* @end */ /* @group Active */ .chzn-container-active .chzn-single { -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); box-shadow : 0 0 5px rgba(0,0,0,.3); border: 1px solid #5897fb; } .chzn-container-active.chzn-with-drop .chzn-single { border: 1px solid #aaa; -webkit-box-shadow: 0 1px 0 #fff inset; -moz-box-shadow : 0 1px 0 #fff inset; box-shadow : 0 1px 0 #fff inset; background-color: #eee; filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0 ); background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff)); background-image: -webkit-linear-gradient(top, #eeeeee 20%, #ffffff 80%); background-image: -moz-linear-gradient(top, #eeeeee 20%, #ffffff 80%); background-image: -o-linear-gradient(top, #eeeeee 20%, #ffffff 80%); background-image: linear-gradient(#eeeeee 20%, #ffffff 80%); -webkit-border-bottom-left-radius : 0; -webkit-border-bottom-right-radius: 0; -moz-border-radius-bottomleft : 0; -moz-border-radius-bottomright: 0; border-bottom-left-radius : 0; border-bottom-right-radius: 0; } .chzn-container-active.chzn-with-drop .chzn-single div { background: transparent; border-left: none; } .chzn-container-active.chzn-with-drop .chzn-single div b { background-position: -18px 2px; } .chzn-container-active .chzn-choices { -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); box-shadow : 0 0 5px rgba(0,0,0,.3); border: 1px solid #5897fb; } .chzn-container-active .chzn-choices .search-field input { color: #111 !important; } /* @end */ /* @group Disabled Support */ .chzn-disabled { cursor: default; opacity:0.5 !important; } .chzn-disabled .chzn-single { cursor: default; } .chzn-disabled .chzn-choices .search-choice .search-choice-close { cursor: default; } /* @group Right to Left */ .chzn-rtl { text-align: right; } .chzn-rtl .chzn-single { padding: 0 8px 0 0; overflow: visible; } .chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; direction: rtl; } .chzn-rtl .chzn-single div { left: 3px; right: auto; } .chzn-rtl .chzn-single abbr { left: 26px; right: auto; } .chzn-rtl .chzn-choices .search-field input { direction: rtl; } .chzn-rtl .chzn-choices li { float: right; } .chzn-rtl .chzn-choices .search-choice { padding: 3px 5px 3px 19px; margin: 3px 5px 3px 0; } .chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 4px; right: auto; } .chzn-rtl .chzn-search { left: 9999px; } .chzn-rtl.chzn-with-drop .chzn-search { left: 0px; } .chzn-rtl .chzn-drop { left: 9999px; } .chzn-rtl.chzn-container-single .chzn-results { margin: 0 0 4px 4px; padding: 0 4px 0 0; } .chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 15px; } .chzn-rtl.chzn-container-active.chzn-with-drop .chzn-single div { border-right: none; } .chzn-rtl .chzn-search input { background: #fff url('chosen-sprite.png') no-repeat -30px -20px; background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url('chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url('chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url('chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%); padding: 4px 5px 4px 20px; direction: rtl; } .chzn-container-single.chzn-rtl .chzn-single div b { background-position: 6px 2px; } .chzn-container-single.chzn-rtl.chzn-with-drop .chzn-single div b { background-position: -12px 2px; } /* @end */ /* @group Retina compatibility */ @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) { .chzn-rtl .chzn-search input, .chzn-container-single .chzn-single abbr, .chzn-container-single .chzn-single div b, .chzn-container-single .chzn-search input, .chzn-container-multi .chzn-choices .search-choice .search-choice-close, .chzn-container .chzn-results-scroll-down span, .chzn-container .chzn-results-scroll-up span { background-image: url('chosen-sprite@2x.png') !important; background-repeat: no-repeat !important; background-size: 52px 37px !important; } } /* @end */ chosen-0.9.15/chosen/chosen-sprite@2x.png0000644000175000017500000000155012153204007017166 0ustar iliasiliasPNG  IHDRhJ`PLTEFFFFFFFFFFFFtttUUUFFF2ϠBtRNS00``Pp @ϰ`Eݐܖ !) fߋDJ~p IDATx^n0ab[S6{;E¹Wb48#Q #U/F&5Óz)vG{= 8`>:Dv"X)8`Bg@aL`#*UK f6낶[ TZv@6e~&f9pÇ͢);tPTWZm=--2m@vnAW21a]7szر^z8V8 j/%H/L\'N+LLua7 Re=:>BN:TDVE6U ~ΘйHX:A\|x㽨d,(7*ghzt#brT';т$}kъJ J_ނ XWwuʻp]^"AOn.ťu|݈s ݷ?~U󖪊1>HoeN"A!8  "CA"BA"CJu<a+IENDB`chosen-0.9.15/chosen/chosen-sprite.png0000644000175000017500000000120612153204007016612 0ustar iliasiliasPNG  IHDR4% MIDATxֿkqSB TO"@VȒI` EE%b~"n:8A@ PAqqJ$p(zO +k }wᾹ$SLdEQYoA}"UcA[*LԆ"t1 !wAjL^3+':iP;GŒlLuD6^}ʠ, z&# 1Fȥ zAoA&1F]/(C{)$ARAއE !Fyف2h; O0@6i>*걠bA80Q&f?}ZX#M&kP;dc"#Qނz&#x ʠ71B",xgAYcfyZW5A#Q{v{]lCg[=wUXr86nZW1 PmOAo-7A, 71Uz~S.a Ɩ ]^7?w3-4Ч&%\i#~APvQ5(L?\zO\IENDB`chosen-0.9.15/chosen.jquery.json0000644000175000017500000000156012153204007015535 0ustar iliasilias{ "name": "chosen", "title": "Chosen", "description": "Chosen is a JavaScript plugin that makes long, unwieldy select boxes much more user-friendly. It is currently available in both jQuery and Prototype flavors.", "keywords": [ "select", "multiselect", "dropdown" ], "version": "0.9.15", "author": { "name": "harvest", "url": "http://getharvest.com" }, "maintainers": [ { "name": "Patrick Filler" }, { "name": "Christophe Coevoet" }, { "name": "Ken Earley" } ], "licenses": [ { "type": "MIT", "url": "https://github.com/harvesthq/chosen/blob/master/LICENSE.md" } ], "homepage": "https://github.com/harvesthq/chosen", "docs": "https://github.com/harvesthq/chosen", "bugs": "https://github.com/harvesthq/chosen/issues", "dependencies": { "jquery": ">=1.4.4" } }chosen-0.9.15/VERSION0000644000175000017500000000000712153204007013110 0ustar iliasilias0.9.15 chosen-0.9.15/README.md0000644000175000017500000000237312153204007013327 0ustar iliasilias# Chosen Chosen is a library for making long, unwieldy select boxes more user friendly. - jQuery support: 1.4+ - Prototype support: 1.7+ For documentation, usage, and examples, see: http://harvesthq.github.io/chosen/ ### Contributing to this project We welcome all to participate in making Chosen the best software it can be. The repository is maintained by only a few people, but has accepted contributions from over 50 authors after reviewing hundreds of pull requests related to thousands of issues. You can help reduce the maintainers' workload (and increase your chance of having an accepted contribution to Chosen) by following the [guidelines for contributing](contributing.md). * [Bug reports](contributing.md#bugs) * [Feature requests](contributing.md#features) * [Pull requests](contributing.md#pull-requests) ### Chosen Credits - Concept and development by [Patrick Filler](http://patrickfiller.com) for [Harvest](http://getharvest.com/). - Design and CSS by [Matthew Lettini](http://matthewlettini.com/) - Repository maintained by [@pfiller](http://github.com/pfiller), [@kenearley](http://github.com/kenearley) and [@stof](http://github.com/stof). - Chosen includes [contributions by many fine folks](https://github.com/harvesthq/chosen/contributors). chosen-0.9.15/LICENSE.md0000644000175000017500000000227712153204007013457 0ustar iliasilias#### Chosen - by Patrick Filler for [Harvest](http://getharvest.com) - Copyright (c) 2011-2013 by Harvest Available for use under the [MIT License](http://en.wikipedia.org/wiki/MIT_License) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. chosen-0.9.15/Cakefile0000644000175000017500000001260612153204007013476 0ustar iliasilias# Building Chosen requires coffee-script and uglify-js. For # help installing, try: # # `npm -g install coffee-script uglify-js` # fs = require 'fs' path = require 'path' {spawn, exec} = require 'child_process' CoffeeScript = require 'coffee-script' {parser, uglify} = require 'uglify-js' javascripts = { 'chosen/chosen.jquery.js': [ 'coffee/lib/select-parser.coffee' 'coffee/lib/abstract-chosen.coffee' 'coffee/chosen.jquery.coffee' ] 'chosen/chosen.proto.js': [ 'coffee/lib/select-parser.coffee' 'coffee/lib/abstract-chosen.coffee' 'coffee/chosen.proto.coffee' ] } Array::unique = -> output = {} output[@[key]] = @[key] for key in [0...@length] value for key, value of output # Gather a list of unique source files. # source_files = -> all_sources = [] for javascript, sources of javascripts for source in sources all_sources.push source all_sources.unique() # Get the version number # version = -> "#{fs.readFileSync('VERSION')}".replace /[^0-9a-zA-Z.]*/gm, '' version_tag = -> "v#{version()}" # Write chosen files with a header # write_chosen_javascript = (filename, body, trailing='') -> fs.writeFileSync filename, """ // Chosen, a Select Box Enhancer for jQuery and Prototype // by Patrick Filler for Harvest, http://getharvest.com // // Version #{version()} // Full source at https://github.com/harvesthq/chosen // Copyright (c) 2011 Harvest http://getharvest.com // MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md // This file is generated by `cake build`, do not edit it by hand. #{body}#{trailing} """ console.log "Wrote #{filename}" # Build Chosen. # task 'build', 'build Chosen from source', build = (cb) -> file_name = null; file_contents = null try for javascript, sources of javascripts code = '' for source in sources file_name = source file_contents = "#{fs.readFileSync source}" code += CoffeeScript.compile file_contents write_chosen_javascript javascript, code unless process.env.MINIFY is 'false' write_chosen_javascript javascript.replace(/\.js$/,'.min.js'), ( uglify.gen_code uglify.ast_squeeze uglify.ast_mangle parser.parse code ), ';' package_npm () -> package_jquery () -> cb() if typeof cb is 'function' catch e print_error e, file_name, file_contents task 'watch', 'watch coffee/ for changes and build Chosen', -> console.log "Watching for changes in coffee/" for file in source_files() # Coffeescript wasn't scoping file correctly- # without this closure the file name displayed # is incorrect. ((file) -> fs.watchFile file, (curr, prev) -> if +curr.mtime isnt +prev.mtime console.log "Saw change in #{file}" invoke 'build' )(file) task 'package_npm', 'generate the package.json file for npm', package_npm = (cb) -> try package_file = 'package.json' package_obj = JSON.parse("#{fs.readFileSync package_file}") package_obj['version'] = version() fs.writeFileSync package_file, JSON.stringify(package_obj, null, 2) console.log "Wrote #{package_file}" cb() if typeof cb is 'function' catch e print_error e, package_file task 'package_jquery', 'generate the chosen.jquery.json file for the jQuery plugin website', package_jquery = (cb) -> try package_file = 'chosen.jquery.json' package_obj = JSON.parse("#{fs.readFileSync package_file}") package_obj['version'] = version() fs.writeFileSync package_file, JSON.stringify(package_obj, null, 2) console.log "Wrote #{package_file}" cb() if typeof cb is 'function' catch e print_error e, package_file run = (cmd, args, cb, err_cb) -> exec "#{cmd} #{args.join(' ')}", (err, stdout, stderr) -> if err isnt null console.error stderr if typeof err_cb is 'function' err_cb() else throw "Failed command execution (#{err})." else cb(stdout) if typeof cb is 'function' with_clean_repo = (cb) -> run 'git', ['diff', '--exit-code'], cb, -> throw 'There are files that need to be committed first.' without_existing_tag = (cb) -> run 'git', ['tag'], (stdout) -> if stdout.split("\n").indexOf( version_tag() ) >= 0 throw 'This tag has already been committed to the repo.' else cb() tag_release = (cb, cb_err) -> run 'git', ['tag', '-a', '-m', "\"Version #{version()}\"", version_tag()], cb, cb_err untag_release = (e) -> console.log "Failure to tag caught: #{e}" console.log "Removing tag #{version_tag()}" run 'git', ['tag', '-d', version_tag()] push_repo = (args=[], cb, cb_err) -> run 'git', ['push'].concat(args), cb, cb_err print_error = (error, file_name, file_contents) -> if error.location console.log CoffeeScript.helpers.prettyErrorMessage(error, file_name, file_contents, true) else console.log """ Error compiling #{file_name}: #{error.message} """ task 'release', 'build, tag the current release, and push', -> console.log "Trying to tag #{version_tag()}..." with_clean_repo -> without_existing_tag -> build -> tag_release -> push_repo [], -> push_repo ['--tags'], -> console.log "Successfully tagged #{version_tag()}: https://github.com/harvesthq/chosen/tree/#{version_tag()}" , untag_release ('push repo with tags') , untag_release ('push repo') , untag_release ('tag release') chosen-0.9.15/.gitignore0000644000175000017500000000004012153204007014025 0ustar iliasilias.DS_Store node_modules .project