diff --git a/app/assets/javascripts/locomotive/views/current_site/edit_view.js.coffee b/app/assets/javascripts/locomotive/views/current_site/edit_view.js.coffee index cbc90e2e..fa6a6ec8 100644 --- a/app/assets/javascripts/locomotive/views/current_site/edit_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/current_site/edit_view.js.coffee @@ -7,9 +7,14 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form el: '#content' + events: + 'click .memberships a.remove': 'remove_membership' + initialize: -> @model = new Locomotive.Models.CurrentSite(@options.site) + Backbone.ModelBinding.bind @ + window.foo = @model render: -> @@ -19,6 +24,8 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form @enable_liquid_editing() + @enable_ui_effects() + render_domain_entries: -> @domains_view = new Locomotive.Views.Site.DomainsView model: @model, errors: @options.errors @@ -35,5 +42,12 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form theme: 'default' onChange: (editor) => @model.set(robots_txt: editor.getValue()) + enable_ui_effects: -> + @$('#site_domains_input .domain input[type=text]').editableField() + @$('.memberships .entry .role select').editableField() + remove_membership: (event) -> + event.stopPropagation() & event.preventDefault() + entry = $(event.target).parents('.entry').hide() + entry.find('input[type=hidden]').val(1) diff --git a/app/assets/javascripts/locomotive/views/sites/domain_entry_view.js.coffee b/app/assets/javascripts/locomotive/views/sites/domain_entry_view.js.coffee index fdd4902e..69d8ee41 100644 --- a/app/assets/javascripts/locomotive/views/sites/domain_entry_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/sites/domain_entry_view.js.coffee @@ -21,5 +21,6 @@ class Locomotive.Views.Site.DomainEntryView extends Backbone.View remove: (event) -> event.stopPropagation() & event.preventDefault() + @$('input[type=text]').editableField('destroy') @options.parent_view.remove_entry(@model) super() \ No newline at end of file diff --git a/app/assets/javascripts/locomotive/views/sites/domains_view.js.coffee b/app/assets/javascripts/locomotive/views/sites/domains_view.js.coffee index 7849af75..3a665c0b 100644 --- a/app/assets/javascripts/locomotive/views/sites/domains_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/sites/domains_view.js.coffee @@ -10,6 +10,7 @@ class Locomotive.Views.Site.DomainsView extends Backbone.View events: 'click .new-entry a.add': 'add_entry' + 'keypress .new-entry input[type=text]': 'add_on_entry_from_enter' render: -> $(@el).html(ich.domains_list(@model.toJSON())) @@ -30,21 +31,32 @@ class Locomotive.Views.Site.DomainsView extends Backbone.View @_insert_entry(domain) + @$('ul li.domain:last input[type=text]').editableField() + @$('.empty').hide() + input.val('') # reset for further entries + add_on_entry_from_enter: (event) -> + return if event.keyCode != 13 + @add_entry(event) + change_entry: (domain, value) -> domain.set name: value remove_entry: (domain) -> list = _.reject @model.get('domains'), (_domain) => _domain == domain @model.set domains: list + @$('.empty').show() if @model.get('domains').length == 0 render_entries: -> - _.each @model.get('domains'), (domain) => - _.each @options.errors.domain || [], (message) => - domain.error = message if message.test /^#{domain.get('name')} / + if @model.get('domains').length == 0 + @$('.empty').show() + else + _.each @model.get('domains'), (domain) => + _.each @options.errors.domain || [], (message) => + domain.error = message if message.test /^#{domain.get('name')} / - @_insert_entry(domain) + @_insert_entry(domain) _insert_entry: (domain) -> view = new Locomotive.Views.Site.DomainEntryView model: domain, parent_view: @ @@ -55,3 +67,5 @@ class Locomotive.Views.Site.DomainsView extends Backbone.View + + diff --git a/app/assets/stylesheets/locomotive/_buttons.scss b/app/assets/stylesheets/locomotive/_buttons.scss index 61197f1d..0693f386 100644 --- a/app/assets/stylesheets/locomotive/_buttons.scss +++ b/app/assets/stylesheets/locomotive/_buttons.scss @@ -75,6 +75,7 @@ color: #8b8d9a; text-decoration: none; + @include text-shadow(rgba(255, 255, 255, 0.8) 0px 1px 0px); font-size: 11px; margin-left: 10px; diff --git a/app/assets/stylesheets/locomotive/_helpers.scss b/app/assets/stylesheets/locomotive/_helpers.scss index 7c4f21be..75679908 100644 --- a/app/assets/stylesheets/locomotive/_helpers.scss +++ b/app/assets/stylesheets/locomotive/_helpers.scss @@ -26,4 +26,32 @@ border: 1px solid #b5b7c4; @include background-image(linear-gradient(top, #f0f0f0, #f9f9f9 25%, #f9f9f9 25%, #ffffff 50%, #ffffff)); -} \ No newline at end of file +} + +@mixin path-input-style { + background: transparent; + outline: none; + + margin: 0 5px; + + width: 30%; + + border: none; + border-bottom: 1px solid #B5B7C4; + + color: #787A89; + font-size: 14px; +} + +@mixin editable { + padding: 2px 25px 2px 6px; + color: #1e1f26; + outline: none; + cursor: pointer; + + &:hover { + text-decoration: none; + background: #fffbe5 image-url("locomotive/form/pen.png") no-repeat right 5px; + border-bottom: 1px dotted #efe4a5; + } +} diff --git a/app/assets/stylesheets/locomotive/formtastic_changes.scss b/app/assets/stylesheets/locomotive/formtastic_changes.scss index e83bc044..3f9a27e5 100644 --- a/app/assets/stylesheets/locomotive/formtastic_changes.scss +++ b/app/assets/stylesheets/locomotive/formtastic_changes.scss @@ -3,6 +3,7 @@ @import "compass/css3/images"; @import "compass/css3/text-shadow"; @import "helpers"; +@import "buttons"; form.formtastic { @@ -56,6 +57,93 @@ form.formtastic { } } // .foldable + .list { + .empty { + text-align: left; + } + + li, .entry, .new-entry { + position: relative; + margin-bottom: 10px; + height: 30px; + line-height: 30px; + + padding: 0 10px; + + background: #fff; + @include border-radius(16px); + @include box-shadow(rgba(0, 0, 0, 0.2) 0px 1px 0px 0px); + + em { + color: #757575; + font-size: 11px; + font-weight: normal; + } + + strong { + color: #17171D; + font-size: 14px; + font-weight: bold; + } + + .editable { + @include editable; + padding-right: 6px; + + &:hover { + background-image: none; + } + } + + span.actions { + position: absolute; + top: 0px; + right: 10px; + + a.add { + @include gray-button; + + padding-left: 10px; + } + + a.remove { + display: inline-block; + width: 16px; + height: 16px; + + position: relative; + top: 4px; + + outline: none; + + background: transparent image-url("locomotive/list/icons/trash_off.png") repeat 0 0; + + text-indent: -9999px; + + &:hover { + background-image: image-url("locomotive/list/icons/trash.png"); + } + } + } + + &:last-child { + margin-bottom: 0px; + } + } // li + + > hr { + margin: 10px 0px; + height: 1px; + line-height: 1px; + border: 0px; + border-top: 1px solid rgba(0, 0, 0, 0.2); + background: transparent; + } + + .new-entry { + } + } // div.list + ol { margin-bottom: 0px; padding: 0px; @@ -106,6 +194,10 @@ form.formtastic { } } // p.inline-hints + div.list { + margin-left: 160px; + } + div.inline-errors { margin: 2px 0 0 160px; padding: 8px 0 0 0; @@ -125,12 +217,12 @@ form.formtastic { } } // div.inline-errors - &.string { + &.string, &.password { label { padding-top: 2px; } - input[type=text] { + input[type=text], input[type=password] { @include default-input-style; width: 700px; @@ -189,11 +281,89 @@ form.formtastic { background: transparent image-url("locomotive/icons/asset_add.png") no-repeat left 1px; } } - } // li.code + } + } // li.code - } + &.subdomain { + + em { + color: #222; + } + + input[type=text] { + @include path-input-style; + } + + } // li.subdomain + + &.empty { + + .list { + + em.editable { + font-size: 14px; + color: #17171D; + font-weight: bold; + } + + input[type=text].path { + @include path-input-style; + } + } + + } // li.empty + + &.no-label { + padding-top: 6px; + + .list { + margin-left: 0; + + .entry { + margin-top: 10px; + margin-bottom: 0px; + } + + &.memberships { + em.email { + margin-left: 10px; + } + + .role { + position: absolute; + top: 0px; + right: 30px; + width: 170px; + + line-height: 30px; + + em { + padding-left: 17px; + margin-left: 0px; + background-repeat: no-repeat; + + color: #757575; + font-size: 13px; + font-weight: normal; + + &.locked { + background-image: image-url("locomotive/icons/membership_lock.png"); + background-position: 1px 0px; + } + + &.editable { + background-image: image-url("locomotive//icons/membership_edit.png"); + background-position: 0px 3px; + } + } + } + } // li.no-label .list.memberships + } + + } // li.no-label } // > li + } //ol } // fieldset } diff --git a/app/assets/stylesheets/locomotive/layout.scss b/app/assets/stylesheets/locomotive/layout.scss index f3dac722..3eba66b8 100644 --- a/app/assets/stylesheets/locomotive/layout.scss +++ b/app/assets/stylesheets/locomotive/layout.scss @@ -115,15 +115,7 @@ body { color: #1e1f26; a.editable { - padding: 2px 25px 2px 6px; - color: #1e1f26; - outline: none; - - &:hover { - text-decoration: none; - background: #fffbe5 image-url("locomotive/form/pen.png") no-repeat right 5px; - border-bottom: 1px dotted #efe4a5; - } + @include editable; } // h2 a.editable } // > div.inner h2 diff --git a/app/controllers/locomotive/base_controller.rb b/app/controllers/locomotive/base_controller.rb index 008c3eeb..b1841d9a 100644 --- a/app/controllers/locomotive/base_controller.rb +++ b/app/controllers/locomotive/base_controller.rb @@ -17,7 +17,7 @@ module Locomotive before_filter :set_current_thread_variables - helper_method :sections, :current_site_url, :site_url, :public_page_url, :current_ability + helper_method :sections, :current_site_public_url, :site_url, :public_page_url, :current_ability # https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in helper Locomotive::BaseHelper, Locomotive::ContentTypesHelper #, Locomotive::BoxHelper @@ -78,7 +78,7 @@ module Locomotive # ___ site/page urls builder ___ - def current_site_url + def current_site_public_url request.protocol + request.host_with_port end @@ -95,9 +95,9 @@ module Locomotive def public_page_url(page, options = {}) if content = options.delete(:content) - File.join(current_site_url, page.fullpath.gsub('content_type_template', ''), content._slug) + File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug) else - File.join(current_site_url, page.fullpath) + File.join(current_site_public_url, page.fullpath) end end diff --git a/app/controllers/locomotive/current_site_controller.rb b/app/controllers/locomotive/current_site_controller.rb index 19493099..25481ae3 100644 --- a/app/controllers/locomotive/current_site_controller.rb +++ b/app/controllers/locomotive/current_site_controller.rb @@ -7,6 +7,8 @@ module Locomotive load_and_authorize_resource :class => 'Site' + before_filter :filter_attributes + respond_to :json, :only => :update def edit @@ -18,13 +20,16 @@ module Locomotive @site = current_site @site.update_attributes(params[:site]) respond_with @site, :location => edit_current_site_url(new_host_if_subdomain_changed) - # respond_with @site do |format| - # format.html { redirect_to edit_current_site_url(new_host_if_subdomain_changed) } - # end end protected + def filter_attributes + unless can?(:manage, Locomotive::Membership) + params[:site].delete(:memberships_attributes) + end + end + def new_host_if_subdomain_changed if !Locomotive.config.manage_subdomain? || @site.domains.include?(request.host) {} diff --git a/app/helpers/locomotive/base_helper.rb b/app/helpers/locomotive/base_helper.rb index bed5c567..95598cb6 100644 --- a/app/helpers/locomotive/base_helper.rb +++ b/app/helpers/locomotive/base_helper.rb @@ -100,9 +100,9 @@ module Locomotive::BaseHelper def public_page_url(page, options = {}) if content = options.delete(:content) - File.join(current_site_url, page.fullpath.gsub('content_type_template', ''), content._slug) + File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug) else - File.join(current_site_url, page.fullpath) + File.join(current_site_public_url, page.fullpath) end end diff --git a/app/inputs/locomotive/code_input.rb b/app/inputs/locomotive/code_input.rb index 7d5c970a..6fad2c2f 100644 --- a/app/inputs/locomotive/code_input.rb +++ b/app/inputs/locomotive/code_input.rb @@ -2,7 +2,6 @@ module Locomotive class CodeInput < Formtastic::Inputs::TextInput def input_wrapping(&block) - Rails.logger.debug hint_html.inspect template.content_tag(:li, [template.capture(&block), error_html, image_picker_html, hint_html].join("\n").html_safe, wrapper_html_options @@ -10,9 +9,7 @@ module Locomotive end def hint_text - localized_string(method, options[:hint], :hint).tap do |foo| - Rails.logger.debug foo.inspect - end + localized_string(method, options[:hint], :hint) end def to_html diff --git a/app/inputs/locomotive/subdomain_input.rb b/app/inputs/locomotive/subdomain_input.rb index e9ca9866..bb7d32d5 100644 --- a/app/inputs/locomotive/subdomain_input.rb +++ b/app/inputs/locomotive/subdomain_input.rb @@ -12,6 +12,7 @@ module Locomotive input_wrapping do label_html << + template.content_tag(:em, "http://") << builder.text_field(method, input_html_options) << template.content_tag(:em, ".#{domain}") end diff --git a/app/models/locomotive/site.rb b/app/models/locomotive/site.rb index e37bcff2..2aa50c6b 100644 --- a/app/models/locomotive/site.rb +++ b/app/models/locomotive/site.rb @@ -29,7 +29,7 @@ module Locomotive ## behaviours ## enable_subdomain_n_domains_if_multi_sites - accepts_nested_attributes_for :memberships + accepts_nested_attributes_for :memberships, :allow_destroy => true ## methods ## diff --git a/app/presenters/locomotive/site_presenter.rb b/app/presenters/locomotive/site_presenter.rb index c88ac114..41168d52 100644 --- a/app/presenters/locomotive/site_presenter.rb +++ b/app/presenters/locomotive/site_presenter.rb @@ -1,10 +1,10 @@ module Locomotive class SitePresenter < BasePresenter - delegate :name, :subdomain, :domains, :robots_txt, :seo_title, :meta_keywords, :meta_description, :domains_without_subdomain, :to => :source + delegate :name, :subdomain, :domains, :robots_txt, :seo_title, :meta_keywords, :meta_description, :domains_without_subdomain, :memberships, :to => :source def included_methods - super + %w(name subdomain domains robots_txt seo_title meta_keywords meta_description domains_without_subdomain) + super + %w(name subdomain domains robots_txt seo_title meta_keywords meta_description domains_without_subdomain memberships) end end diff --git a/app/views/locomotive/current_site/_form.html.haml b/app/views/locomotive/current_site/_form.html.haml index 0d67467c..aed844d2 100644 --- a/app/views/locomotive/current_site/_form.html.haml +++ b/app/views/locomotive/current_site/_form.html.haml @@ -24,30 +24,32 @@ - if can?(:index, Locomotive::Membership) = f.inputs :name => :memberships do - = f.semantic_fields_for :memberships do |fm| + %li{ :class => 'input empty no-label' } + .list.memberships + = f.semantic_fields_for :memberships do |fm| - - membership, account = fm.object, fm.object.account + - membership, account = fm.object, fm.object.account - %li.item.membership{ :'data-role' => membership.role } - %strong= account.name + .entry + = fm.hidden_field :_destroy - %em.email= account.email + %strong= account.name - - if can?(:update, membership) - .role - %em.editable= t("locomotive.memberships.roles.#{membership.role}") + %em.email= account.email + + - if can?(:update, membership) + .role + - if can?(:grant_admin, membership) + = fm.select :role, Locomotive::Ability::ROLES.map { |r| [t("locomotive.memberships.roles.#{r}"), r] }, :include_blank => false + - else + = fm.select :role, (Locomotive::Ability::ROLES - ['admin']).map { |r| [t("locomotive.memberships.roles.#{r}"), r] }, :include_blank => false + + %span.actions + = link_to 'x', '#', :class => 'remove' - - if can?(:grant_admin, membership) - = fm.select :role, Locomotive::Ability::ROLES.map { |r| [t("locomotive.memberships.roles.#{r}"), r] }, :include_blank => false - else - = fm.select :role, (Locomotive::Ability::ROLES - ['admin']).map { |r| [t("locomotive.memberships.roles.#{r}"), r] }, :include_blank => false - - %span.actions - = link_to image_tag('admin/form/icons/trash.png'), membership_url(membership), :class => 'remove first', :confirm =>t('locomotive.messages.confirm'), :method => :delete - - - else - .role - %em.locked= t("locomotive.memberships.roles.#{membership.role}") + .role + %em.locked= t("locomotive.memberships.roles.#{membership.role}") - if can?(:manage, current_site) diff --git a/app/views/locomotive/current_site/edit.html.haml b/app/views/locomotive/current_site/edit.html.haml index a49da23e..01954d04 100644 --- a/app/views/locomotive/current_site/edit.html.haml +++ b/app/views/locomotive/current_site/edit.html.haml @@ -12,7 +12,7 @@ %p!= t('.help') -= semantic_form_for @site, :url => current_site_url, :html => { :class => 'save-with-shortcut' } do |form| += semantic_form_for @site, :url => current_site_url do |form| = render 'form', :f => form diff --git a/app/views/locomotive/pages/edit.html.haml b/app/views/locomotive/pages/edit.html.haml index bc87c695..abb0f89a 100644 --- a/app/views/locomotive/pages/edit.html.haml +++ b/app/views/locomotive/pages/edit.html.haml @@ -2,7 +2,7 @@ - content_for :submenu do = render 'locomotive/shared/menu/contents' - + - content_for :actions do = render 'locomotive/shared/actions/contents' @@ -11,7 +11,7 @@ %p!= t('.help') -= semantic_form_for @page, :url => page_url(@page), :html => { :class => 'save-with-shortcut', :multipart => true } do |form| += semantic_form_for @page, :url => page_url(@page), :html => { :multipart => true } do |form| = render 'form', :f => form diff --git a/app/views/locomotive/shared/_header.html.haml b/app/views/locomotive/shared/_header.html.haml index 6ff530a5..b5dfdb41 100644 --- a/app/views/locomotive/shared/_header.html.haml +++ b/app/views/locomotive/shared/_header.html.haml @@ -1,7 +1,7 @@ %h1 = link_to current_site.name, pages_url -= render_cell 'locomotive/global_actions', :show, :current_locomotive_account => current_locomotive_account, :current_site_url => current_site_url += render_cell 'locomotive/global_actions', :show, :current_locomotive_account => current_locomotive_account, :current_site_url => current_site_public_url - if multi_sites? && current_locomotive_account.sites.size > 1 #sites-picker{ :style => 'display: none' } diff --git a/app/views/locomotive/sites/_domains.html.haml b/app/views/locomotive/sites/_domains.html.haml index 8de60510..9da24035 100644 --- a/app/views/locomotive/sites/_domains.html.haml +++ b/app/views/locomotive/sites/_domains.html.haml @@ -1,10 +1,14 @@ %script{ :type => 'text/html', :id => 'domains_list' } + %p.empty{ :style => 'display: none' }!= t('.empty') + %ul + %hr + .new-entry %em http:// - = text_field_tag 'domain', '', :id => '', :placeholder => t('formtastic.hints.site.domain_name') + = text_field_tag 'domain', '', :id => '', :placeholder => t('formtastic.hints.site.domain_name'), :class => 'path' %span.actions = link_to t('locomotive.buttons.new_item'), '#', :class => 'add' @@ -12,7 +16,7 @@ %script{ :type => 'text/html', :id => 'domain_entry' } %em http:// - = text_field_tag 'site[domains][]', '{{name}}', :id => '' + = text_field_tag 'site[domains][]', '{{name}}', :id => '', :class => 'path' {{#if error}} %span.inline-errors {{error}} diff --git a/app/views/locomotive/sites/_form.html.haml b/app/views/locomotive/sites/_form.html.haml new file mode 100644 index 00000000..d1362bc8 --- /dev/null +++ b/app/views/locomotive/sites/_form.html.haml @@ -0,0 +1,37 @@ +- content_for :head do + = include_javascripts :site + += f.foldable_inputs :name => :information, :style => "#{'display: none' unless @site.new_record?}" do + = f.input :name, :required => false + +- if manage_subdomain_or_domains? + = f.foldable_inputs :name => :access_points, :class => 'editable-list off' do + + = f.custom_input :subdomain, :css => 'path' do + %em + http:// + = f.text_field :subdomain + \. + %em + = application_domain + + - if manage_domains? + - @site.domains_without_subdomain.each_with_index do |name, index| + %li{ :class => "item added #{'last' if index == @site.domains.size - 1}" } + %em + http:// + = text_field_tag 'site[domains][]', name, :class => 'string label void domain' +   + = error_on_domain(@site, name) + %span.actions + = link_to image_tag('admin/form/icons/trash.png'), '#', :class => 'remove first', :confirm => t('locomotive.messages.confirm') + + %li.item.template + %em + http:// + = text_field_tag 'label', t('formtastic.hints.site.domain_name'), :class => 'string label void domain' +   + %span.actions + = link_to image_tag('admin/form/icons/trash.png'), '#', :class => 'remove first', :confirm => t('locomotive.messages.confirm') + %button{ :class => 'button light add', :type => 'button' } + %span!= t('locomotive.buttons.new_item') \ No newline at end of file diff --git a/app/views/locomotive/sites/new.html.haml b/app/views/locomotive/sites/new.html.haml new file mode 100644 index 00000000..f1ba197f --- /dev/null +++ b/app/views/locomotive/sites/new.html.haml @@ -0,0 +1,12 @@ +- title t('.title') + +- content_for :submenu do + = render_cell 'locomotive/settings_menu', :show + +%p!= t('.help') + += semantic_form_for @site, :url => sites_url do |form| + + = render 'form', :f => form + + = render 'locomotive/shared/form_actions', :back_url => edit_my_account_url, :button_label => :create \ No newline at end of file diff --git a/config/locales/admin_ui.en.yml b/config/locales/admin_ui.en.yml index 9bbca113..af3ee629 100644 --- a/config/locales/admin_ui.en.yml +++ b/config/locales/admin_ui.en.yml @@ -144,6 +144,8 @@ en: new: title: New site help: "Fill in the form below to create your new site." + domains: + empty: "There are no domains tied this site yet. Simply add your domains just below. Do not forget to upgrade your DNS." current_site: edit: diff --git a/doc/TODO b/doc/TODO index 00f42ca7..432bb2d5 100644 --- a/doc/TODO +++ b/doc/TODO @@ -16,11 +16,12 @@ x fix css in firefox x update page in ajax - fix other sections - edit my site + x css + x robots.txt - domains - - robots.txt - roles - save - - css + - create a new site - edit my account - theme assets diff --git a/lib/locomotive/routing/site_dispatcher.rb b/lib/locomotive/routing/site_dispatcher.rb index 8bbffa07..08d3e2dc 100644 --- a/lib/locomotive/routing/site_dispatcher.rb +++ b/lib/locomotive/routing/site_dispatcher.rb @@ -47,7 +47,7 @@ module Locomotive sign_out(current_locomotive_account) flash[:alert] = I18n.t(:no_membership, :scope => [:devise, :failure, :locomotive]) - redirect_to new_session_url and return false + redirect_to new_locomotive_account_session_url and return false end end diff --git a/vendor/assets/javascripts/editable_field.js b/vendor/assets/javascripts/editable_field.js new file mode 100644 index 00000000..f951366d --- /dev/null +++ b/vendor/assets/javascripts/editable_field.js @@ -0,0 +1,50 @@ +/** + * Version 0.0.1 + * tiny effect to display an input field when clicking on a label + * Didier Lafforgue + */ +$.fn.editableField = function(settings) { + + var destroy = false; + + if ('destroy' == settings) { + destroy = true + } else { + settings = $.extend({}, settings); + } + + function getText(element) { + if (element.is('select')) { + return element[0].options[element[0].options.selectedIndex].text; + } else { + return element.val(); + } + } + + return this.each(function() { + if (destroy) { + $(this).unbind('mouseenter').unbind('mouseleave'); + $(this).prev('.editable').unbind('click').remove(); + } else { + var input = $(this).hide(); + var label = $('').addClass('editable').html(getText(input)); + var timer = null; + + input.before(label); + + label.bind('click', function() { + label.hide(); + input.show().focus(); + }); + + input.hover(function() { + clearTimeout(timer); + }, function() { + timer = setTimeout(function() { input.hide(); label.show() }, 1000); + }).change(function() { + input.hide(); + label.show().html(getText(input)) + }); + } + }); +} \ No newline at end of file