diff --git a/Gemfile b/Gemfile index 05a0a1e5..4c23e50d 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ source 'https://rubygems.org' gem 'simple_calendar' gem 'rails' +gem 'has_scope' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0.0.beta1' diff --git a/Gemfile.lock b/Gemfile.lock index 0c2451ac..99464f9a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: git://github.com/activeadmin/activeadmin.git - revision: c26ae0b1393311180b5137c6b4a271de3385d069 + revision: 809142efe855e590331cdc41e72dcad76b719a46 specs: activeadmin (1.0.0.pre) arbre (~> 1.0, >= 1.0.2) @@ -150,7 +150,7 @@ GEM actionpack (>= 3.2.13) formtastic_i18n (0.1.1) geocoder (1.2.5) - guard (2.7.1) + guard (2.8.0) formatador (>= 0.2.4) listen (~> 2.7) lumberjack (~> 1.0) @@ -169,7 +169,7 @@ GEM guard-minitest (2.3.2) guard (~> 2.0) minitest (>= 3.0) - guard-rubocop (1.1.0) + guard-rubocop (1.2.0) guard (~> 2.0) rubocop (~> 0.20) haml (4.0.5) @@ -219,7 +219,7 @@ GEM rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) lumberjack (1.0.9) - mail (2.6.1) + mail (2.6.3) mime-types (>= 1.16, < 3) memoizable (0.4.2) thread_safe (~> 0.3, >= 0.3.1) @@ -234,7 +234,7 @@ GEM mysql2 (0.3.16) naught (1.0.0) orm_adapter (0.5.0) - parser (2.2.0.pre.6) + parser (2.2.0.pre.7) ast (>= 1.1, < 3.0) slop (~> 3.4, >= 3.4.5) polyamorous (1.1.0) @@ -290,7 +290,7 @@ GEM powerpack (~> 0.0.6) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.4) - ruby-progressbar (1.6.1) + ruby-progressbar (1.7.0) ruby2ruby (2.1.3) ruby_parser (~> 3.1) sexp_processor (~> 4.0) @@ -341,7 +341,7 @@ GEM tilt (1.4.1) timers (4.0.1) hitimes - tinymce-rails (4.1.5) + tinymce-rails (4.1.6) railties (>= 3.1.1) tinymce-rails-langs (4.20140129) tinymce-rails (~> 4.0) @@ -393,6 +393,7 @@ DEPENDENCIES guard-minitest guard-rubocop haml-rails + has_scope http_accept_language i18n-active_record! jbuilder (~> 2.0) diff --git a/Guardfile b/Guardfile index 4baac254..51b3dae4 100644 --- a/Guardfile +++ b/Guardfile @@ -29,7 +29,7 @@ end notification :notifysend -guard 'brakeman', run_on_start: true, quiet: true, min_confidence: 10 do +guard :brakeman, run_on_start: true, quiet: true, min_confidence: 10 do watch(%r{^app/.+\.(erb|haml|rhtml|rb)$}) watch(%r{^config/.+\.rb$}) watch(%r{^lib/.+\.rb$}) diff --git a/app/admin/dashboard.rb b/app/admin/dashboard.rb index 9722ae48..64f86785 100644 --- a/app/admin/dashboard.rb +++ b/app/admin/dashboard.rb @@ -29,7 +29,7 @@ ActiveAdmin.register_page 'Dashboard' do #{link_to(`git rev-parse --short HEAD`, "https://gitorious.org/agenda-du-libre-rails/agenda-du-libre-rails/commit/ #{`git rev-parse HEAD`}")}) - .html_safe + .html_safe end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cc5d1edd..efb4d53a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -11,4 +11,11 @@ class ApplicationController < ActionController::Base I18n.locale = http_accept_language .compatible_language_from I18n.available_locales end + + protected + + # Useful to manage absolute url in mails + def set_mailer_host + ActionMailer::Base.default_url_options[:host] = request.host_with_port + end end diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index 2b7c0e34..9b458651 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -1,33 +1,33 @@ # Event life cycle # This is a central part to this project class EventsController < ApplicationController + has_scope :region, :locality, :tag, :daylimit + before_action :set_events, only: [:index] - before_action :set_event, only: - [:show, :edit, :preview, :update, :cancel, :destroy] - before_action :check_secret, only: - [:edit, :preview, :update, :cancel, :destroy] + before_action :set_event, except: [:index, :new, :preview_create, :create] + before_action :set_create_event, only: [:preview_create, :create] + before_action :check_secret, only: [:edit, :preview, :update, :destroy] + before_action :set_old_event, only: [:update] before_action :set_mailer_host rescue_from ActiveRecord::StaleObjectError, with: :locked def index respond_to do |format| format.html { render layout: 'iframe' if params[:iframe] } - format.rss { @events = @events.future.in params[:daylimit] } - format.ics { @events = @events.last_year.order :id } - format.xml { @events = @events.includes(:related_region).order :id } + format.rss { @events = @events.future } + format.ics { @events = @events.last_year } + format.xml { @events = @events.includes :related_region } end end # GET /users/new def new - @event = Event.new - @event.start_time ||= Time.now.change(min: 0) + 1.day + 1.hour - @event.end_time ||= Time.now.change(min: 0) + 1.day + 2.hour + @event = Event.new start_time: Time.now.change(min: 0) + 1.day + 1.hour, + end_time: Time.now.change(min: 0) + 1.day + 2.hour end # POST /events/preview def preview_create - @event = Event.new event_params @event.valid? render action: :new end @@ -35,8 +35,6 @@ class EventsController < ApplicationController # POST /events # POST /events.json def create - @event = Event.new event_params - respond_to do |format| if @event.save && send_creation_mails format.html { redirect_to :root, notice: t('.ok') } @@ -60,7 +58,6 @@ class EventsController < ApplicationController # PATCH/PUT /events/1 # PATCH/PUT /events/1.json def update - @older_event = Event.new @event.attributes respond_to do |format| if @event.update(event_params) && send_update_mails format.html { redirect_to :root, notice: t('.ok') } @@ -78,7 +75,7 @@ class EventsController < ApplicationController def destroy @event.destroy respond_to do |format| - format.html { redirect_to events_url, notice: t('.ok') } + format.html { redirect_to :root, notice: t('.ok') } format.json { head :no_content } end end @@ -86,10 +83,7 @@ class EventsController < ApplicationController private def set_events - @events = Event.moderated - @events = @events.region params[:region] if params[:region] - @events = @events.locality params[:locality] if params[:locality] - @events = @events.tag params[:tag] if params[:tag] + @events = apply_scopes Event.moderated end # Use callbacks to share common setup or constraints between actions @@ -102,6 +96,14 @@ class EventsController < ApplicationController @event = @event.find params[:id] end + def set_create_event + @event = Event.new event_params + end + + def set_old_event + @older_event = Event.new @event.attributes + end + # Never trust parameters from the scary internet, only allow the white list # through def event_params @@ -117,11 +119,6 @@ class EventsController < ApplicationController unless params[:secret] == @event.secret end - # Useful to manage absolute url in mails - def set_mailer_host - ActionMailer::Base.default_url_options[:host] = request.host_with_port - end - def send_creation_mails # Send an event creation mail to its author EventMailer.create(@event).deliver diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 474bfac1..84eb53c4 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -2,16 +2,12 @@ # # Access to OSM controls class MapsController < ApplicationController + has_scope :region, :locality, :tag + def index respond_to do |format| format.html - format.json do - @events = Event.moderated.future.geo - @events = @events.region params[:region] if params[:region] - @events = @events.locality params[:locality] if params[:locality] - @events = @events.tag params[:tag] if params[:tag] - render json: @events - end + format.json { render json: apply_scopes(Event.moderated.future.geo) } end end end diff --git a/app/controllers/moderations_controller.rb b/app/controllers/moderations_controller.rb index 2a78bc1d..5ba4d5b2 100644 --- a/app/controllers/moderations_controller.rb +++ b/app/controllers/moderations_controller.rb @@ -3,6 +3,7 @@ class ModerationsController < ApplicationController before_action :authenticate_user! before_action :set_moderation, :set_mailer_host, only: [:show, :edit, :preview, :update, :validate, :accept, :refuse, :destroy] + before_action :set_old_mod, only: [:update] rescue_from ActiveRecord::StaleObjectError, with: :locked def index @@ -18,10 +19,9 @@ class ModerationsController < ApplicationController # PATCH/PUT /moderations/1 # PATCH/PUT /moderations/1.json def update - @older_mod = Event.new @event.attributes respond_to do |format| if @moderation.update_attributes(moderation_params) && send_mails - format.html { redirect_to moderations_url, notice: t('.ok') } + format.html { redirect_to :moderations, notice: t('.ok') } format.json { head :no_content } else format.html { render action: 'edit' } @@ -34,28 +34,20 @@ class ModerationsController < ApplicationController # PATCH/PUT /accept/1 # PATCH/PUT /accept/1.json def accept + @moderation.update moderated: true + send_accept_mails respond_to do |format| - if @moderation.update(moderated: true) && send_accept_mails - tweet - format.html { redirect_to moderations_url, notice: t('.ok') } - format.json { head :no_content } - else - format.html { render action: 'edit' } - # 422 means :unprocessable_entity - format.json { render json: @moderation.errors, status: 422 } - end + format.html { redirect_to :moderations, notice: t('.ok') } + format.json { head :no_content } end end # DELETE /events/1 # DELETE /events/1.json def destroy - if @moderation.destroy && send_destroy_mails - EventMailer.destroy(@moderation, current_user, @reason).deliver - ModerationMailer.destroy(@moderation, current_user, @reason).deliver - end + send_destroy_mails if @moderation.destroy respond_to do |format| - format.html { redirect_to moderations_url, notice: t('.ok') } + format.html { redirect_to :moderations, notice: t('.ok') } format.json { head :no_content } end end @@ -68,6 +60,10 @@ class ModerationsController < ApplicationController @moderation = @event end + def set_old_mod + @older_mod = Event.new @event.attributes + end + # Never trust parameters from the scary internet, only allow the white list # through. def moderation_params @@ -88,6 +84,8 @@ class ModerationsController < ApplicationController end def send_accept_mails + tweet + # Send an acceptation mail to its author EventMailer.accept(@moderation, current_user).deliver @@ -113,6 +111,9 @@ class ModerationsController < ApplicationController else @reason = t "moderations.refuse.reason_#{params[:reason]}_long" end + + EventMailer.destroy(@moderation, current_user, @reason).deliver + ModerationMailer.destroy(@moderation, current_user, @reason).deliver end def locked diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index 28f48a39..a28ce1a6 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -1,6 +1,7 @@ # Events, particulary during moderation, can have notes associated to them class NotesController < ApplicationController - before_action :set_event, :set_mailer_host, only: [:new, :create] + before_action :set_event, only: [:new, :create] + before_action :create_note, :set_mailer_host, only: [:create] # GET /moderations/id/new def new @@ -8,14 +9,12 @@ class NotesController < ApplicationController end def create - @note = @moderation.notes.new note_params.merge author: current_user - respond_to do |format| if @note.save && send_mails format.html { redirect_to moderations_url, notice: t('.ok') } format.json { render action: :show, status: :created, location: @event } else - format.html { render action: 'new' } + format.html { render action: :new } format.json { render json: @note.errors, status: :unprocessable_entity } end end @@ -29,6 +28,10 @@ class NotesController < ApplicationController @moderation = @event end + def create_note + @note = @moderation.notes.new note_params.merge author: current_user + end + # Never trust parameters from the scary internet, only allow the white list # through. def note_params diff --git a/app/controllers/regions_controller.rb b/app/controllers/regions_controller.rb index e18ebae2..8b465953 100644 --- a/app/controllers/regions_controller.rb +++ b/app/controllers/regions_controller.rb @@ -1,32 +1,3 @@ # Manage regions, mostly get stats out of them class RegionsController < InheritedResources::Base - def stats - @region_events = Event.joins(:related_region).group(:name) - .order('count(name) desc').count :name - - @city_events = Event.group(:city).having('count(city) > 3') - .order('count(city) desc').count :city - - @year_events = Event.group(year_grouping).count - - @month_events = Event.group(year_grouping, month_grouping).count - end - - private - - def year_grouping - if %w(Mysql2 MySQL PostgreSQL).include? Event.connection.adapter_name - 'extract(year from start_time)' - elsif Event.connection.adapter_name == 'SQLite' - 'strftime("%Y", start_time)' - end - end - - def month_grouping - if %w(Mysql2 MySQL PostgreSQL).include? Event.connection.adapter_name - 'extract(month from start_time)' - elsif Event.connection.adapter_name == 'SQLite' - 'strftime("%m", start_time)' - end - end end diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb new file mode 100644 index 00000000..84fad600 --- /dev/null +++ b/app/controllers/stats_controller.rb @@ -0,0 +1,34 @@ +# Generate statistics, around events, by date or place +class StatsController < ApplicationController + before_action :set_temporal, :set_local, only: [:index] + + private + + def set_temporal + @year_events = Event.group(year_grouping).count + @month_events = Event.group(year_grouping, month_grouping).count + end + + def set_local + @region_events = Event.joins(:related_region).group(:name) + .order('count(name) desc').count + @city_events = Event.group(:city).having('count(city) > 3') + .order('count(city) desc').count + end + + def year_grouping + if %w(Mysql2 MySQL PostgreSQL).include? Event.connection.adapter_name + 'extract(year from start_time)' + elsif Event.connection.adapter_name == 'SQLite' + 'strftime("%Y", start_time)' + end + end + + def month_grouping + if %w(Mysql2 MySQL PostgreSQL).include? Event.connection.adapter_name + 'extract(month from start_time)' + elsif Event.connection.adapter_name == 'SQLite' + 'strftime("%m", start_time)' + end + end +end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 1964b2a9..9c310542 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -2,15 +2,15 @@ class TagsController < InheritedResources::Base def index @tags = Event - .pluck(:tags).map(&:split).flatten - .group_by { |i| i } - .map { |k, v| [k, v.size] } - .reject { |_k, v| v <= 3 } - .sort + .pluck(:tags).map(&:split).flatten + .group_by { |i| i } + .map { |k, v| [k, v.size] } + .reject { |_k, v| v <= 3 } + .sort respond_to do |format| format.html - format.json { render json: @tags.to_json } + format.json { render json: @tags } end end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index da97cb1e..7c9aee9e 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -26,17 +26,25 @@ module EventsHelper def display_date(event = @event) if event.start_time.to_date == event.end_time.to_date - t 'date.formats.same_day', - date: l(event.start_time.to_date, format: :long), - start: l(event.start_time, format: :hours), - end: l(event.end_time, format: :hours) + display_sameday event else - t 'date.formats.period', - start: l(event.start_time, format: :at), - end: l(event.end_time, format: :at) + display_multi_days event end end + def display_sameday(event) + t 'date.formats.same_day', + date: l(event.start_time.to_date, format: :long), + start: l(event.start_time, format: :hours), + end: l(event.end_time, format: :hours) + end + + def display_multi_days(event) + t 'date.formats.period', + start: l(event.start_time, format: :at), + end: l(event.end_time, format: :at) + end + def wrap(s, width = 78) s.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n") end diff --git a/app/models/event.rb b/app/models/event.rb index 321980c2..bc198d21 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -29,7 +29,7 @@ class Event < ActiveRecord::Base scope :last_year, -> { where '? <= end_time', 1.year.ago } scope :past, -> { where 'start_time <= ?', DateTime.now } scope :future, -> { where '? <= end_time', DateTime.now } - scope :in, -> days { where 'end_time <= ?', (days || 30).to_i.days.from_now } + scope :daylimit, -> d { where 'end_time <= ?', (d || 30).to_i.days.from_now } scope :year, (lambda do |year| where '? <= end_time and start_time <= ?', Date.new(year, 1, 1).beginning_of_week, diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 3121a981..f934cfde 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -57,7 +57,7 @@ = link_to application_infos_path do %em.fa.fa-info =t '.infos' - = link_to stats_regions_path do + = link_to stats_path do %em.fa.fa-signal =t '.stats' = link_to application_contact_path do diff --git a/app/views/regions/stats.html.haml b/app/views/stats/index.html.haml similarity index 100% rename from app/views/regions/stats.html.haml rename to app/views/stats/index.html.haml diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index ac3ecacb..90c72653 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -138,7 +138,8 @@ it more readable or agreable. Example: `%{tag}` \n* You can modify the 30 days limit with the parameter `daylimit`. \n Example: `%{daylimit}`" - stats: + stats: + index: title: Statistics all: Validated events allModeration: Events waiting for validation diff --git a/config/locales/views/fr.yml b/config/locales/views/fr.yml index 3768e385..fe925ec3 100644 --- a/config/locales/views/fr.yml +++ b/config/locales/views/fr.yml @@ -136,7 +136,8 @@ fr: * Vous pouvez modifier la limite des 30 prochains jours des flux en utilisant le paramètre `daylimit`. \n Exemple: `%{daylimit}`" - stats: + stats: + index: title: Statistiques all: Événements validés allModeration: Événements en cours de modération diff --git a/config/routes.rb b/config/routes.rb index c282a348..120befa6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,7 @@ Rails.application.routes.draw do get 'application/infos' get 'application/contact' get 'application/rules' + get 'stats', to: 'stats#index' resources :users resources :events do @@ -15,9 +16,7 @@ Rails.application.routes.draw do get :validate, :refuse, on: :member put :accept, on: :member end - resources :regions, only: [:index] do - get 'stats', on: :collection - end + resources :regions, only: [:index] resources :tags, only: [:index, :show] resources :maps, only: [:index] resources :lugs, only: [:index, :show] diff --git a/deploy/before_restart b/deploy/before_restart index 9fe8a96c..32593e3c 100755 --- a/deploy/before_restart +++ b/deploy/before_restart @@ -29,7 +29,7 @@ if File.file? 'Rakefile' # precompile assets changed_assets = `git diff #{oldrev} #{newrev} --name-only -z app/assets` - .split("\0") + .split("\0") tasks << 'assets:precompile' if changed_assets.size > 0 run "#{rake_cmd} #{tasks.join(' ')} RAILS_ENV=#{RAILS_ENV}" if tasks.any? diff --git a/public/webshims/polyfiller.js b/public/webshims/polyfiller.js index 528ace81..fe1c75f8 100644 --- a/public/webshims/polyfiller.js +++ b/public/webshims/polyfiller.js @@ -119,6 +119,7 @@ promise: 'es6', URL: 'url' }; + var supportCapture = 'capture' in create('input'); clearInterval(webshims.timer); support.advancedObjectProperties = support.objectAccessor = support.ES5 = !!('create' in Object && 'seal' in Object); @@ -136,7 +137,7 @@ } $.extend(webshims, { - version: '1.15.3', + version: '1.15.4', cfg: { enhanceAuto: window.Audio && (!window.matchMedia || matchMedia('(min-device-width: 721px)').matches), @@ -212,11 +213,13 @@ })(), _polyfill: function(features){ var toLoadFeatures = []; - var hasFormsExt; + var hasFormsExt, needExtStyles; if(!firstRun.run){ hasFormsExt = $.inArray('forms-ext', features) !== -1; firstRun(); + needExtStyles = (hasFormsExt && !modules["form-number-date-ui"].test()) || (!supportCapture && $.inArray('mediacapture', features) !== -1); + if(hasFormsExt && $.inArray('forms', features) == -1){ features.push('forms'); if(WSDEBUG){ @@ -224,7 +227,7 @@ } } if(webCFG.loadStyles){ - loader.loadCSS('styles/shim'+((hasFormsExt && !modules["form-number-date-ui"].test()) ? '-ext' : '')+'.css'); + loader.loadCSS('styles/shim'+(needExtStyles ? '-ext' : '')+'.css'); } } @@ -922,7 +925,7 @@ // - // - // + // + + // + + // - /* - // - */ - //
= 12){ @@ -2432,6 +2441,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine createFormat('d'); var tmp, obj; var ret = ''; + if(opts.splitInput){ obj = {yy: 0, mm: 1, dd: 2}; } else { @@ -2453,8 +2463,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-'); } - return ret - ; + return ret; }, color: function(val, opts){ var ret = '#000000'; @@ -2756,9 +2765,11 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; ['defaultValue', 'value'].forEach(function(name){ + var formatName = 'format'+name; wsWidgetProto[name] = function(val, force){ - if(!this._init || force || val !== this.options[name]){ - this.element.prop(name, this.formatValue(val)); + if(!this._init || force || val !== this.options[name] || this.options[formatName] != this.element.prop(name)){ + this.options[formatName] = this.formatValue(val); + this.element.prop(name, this.options[formatName]); this.options[name] = val; this._propertyChange(name); this.mirrorValidity(); @@ -2882,36 +2893,34 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine var isValue = name == 'value'; spinBtnProto[name] = function(val, force, isLive){ var selectionEnd; - if(!this._init || force || this.options[name] !== val){ - if(isValue){ - this._beforeValue(val); - } else { - this.elemHelper.prop(name, val); - } - - val = formatVal[this.type](val, this.options); - if(this.options.splitInput){ - $.each(this.splits, function(i, elem){ - var setOption; - if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ - $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); - } else { - $.prop(elem, name, val[i]); - } - }); - } else { - val = this.toFixed(val); - if(isLive && this._getSelectionEnd){ - selectionEnd = this._getSelectionEnd(val); - } - this.element.prop(name, val); - if(selectionEnd != null){ - this.element.prop('selectionEnd', selectionEnd); - } - } - this._propertyChange(name); - this.mirrorValidity(); + if(isValue){ + this._beforeValue(val); + } else { + this.elemHelper.prop(name, val); } + + val = formatVal[this.type](val, this.options); + if(this.options.splitInput){ + $.each(this.splits, function(i, elem){ + var setOption; + if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ + $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); + } else { + $.prop(elem, name, val[i]); + } + }); + } else { + val = this.toFixed(val); + if(isLive && this._getSelectionEnd){ + selectionEnd = this._getSelectionEnd(val); + } + this.element.prop(name, val); + if(selectionEnd != null){ + this.element.prop('selectionEnd', selectionEnd); + } + } + this._propertyChange(name); + this.mirrorValidity(); }; }); diff --git a/public/webshims/shims/combos/11.js b/public/webshims/shims/combos/11.js index b837903c..53cf8165 100644 --- a/public/webshims/shims/combos/11.js +++ b/public/webshims/shims/combos/11.js @@ -1044,9 +1044,13 @@ }, time: function(val, o, noCorrect){ var fVal, i; + if(val){ val = val.split(':'); + if(val.length != 2 || isNaN(parseInt(val[0] || '', 10)) || isNaN(parseInt(val[1] || '', 10))){ + return val.join(':'); + } if(curCfg.meridian){ fVal = (val[0] * 1); if(fVal && fVal >= 12){ @@ -1201,6 +1205,7 @@ createFormat('d'); var tmp, obj; var ret = ''; + if(opts.splitInput){ obj = {yy: 0, mm: 1, dd: 2}; } else { @@ -1222,8 +1227,7 @@ } ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-'); } - return ret - ; + return ret; }, color: function(val, opts){ var ret = '#000000'; @@ -1525,9 +1529,11 @@ }; ['defaultValue', 'value'].forEach(function(name){ + var formatName = 'format'+name; wsWidgetProto[name] = function(val, force){ - if(!this._init || force || val !== this.options[name]){ - this.element.prop(name, this.formatValue(val)); + if(!this._init || force || val !== this.options[name] || this.options[formatName] != this.element.prop(name)){ + this.options[formatName] = this.formatValue(val); + this.element.prop(name, this.options[formatName]); this.options[name] = val; this._propertyChange(name); this.mirrorValidity(); @@ -1651,36 +1657,34 @@ var isValue = name == 'value'; spinBtnProto[name] = function(val, force, isLive){ var selectionEnd; - if(!this._init || force || this.options[name] !== val){ - if(isValue){ - this._beforeValue(val); - } else { - this.elemHelper.prop(name, val); - } - - val = formatVal[this.type](val, this.options); - if(this.options.splitInput){ - $.each(this.splits, function(i, elem){ - var setOption; - if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ - $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); - } else { - $.prop(elem, name, val[i]); - } - }); - } else { - val = this.toFixed(val); - if(isLive && this._getSelectionEnd){ - selectionEnd = this._getSelectionEnd(val); - } - this.element.prop(name, val); - if(selectionEnd != null){ - this.element.prop('selectionEnd', selectionEnd); - } - } - this._propertyChange(name); - this.mirrorValidity(); + if(isValue){ + this._beforeValue(val); + } else { + this.elemHelper.prop(name, val); } + + val = formatVal[this.type](val, this.options); + if(this.options.splitInput){ + $.each(this.splits, function(i, elem){ + var setOption; + if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ + $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); + } else { + $.prop(elem, name, val[i]); + } + }); + } else { + val = this.toFixed(val); + if(isLive && this._getSelectionEnd){ + selectionEnd = this._getSelectionEnd(val); + } + this.element.prop(name, val); + if(selectionEnd != null){ + this.element.prop('selectionEnd', selectionEnd); + } + } + this._propertyChange(name); + this.mirrorValidity(); }; }); diff --git a/public/webshims/shims/combos/12.js b/public/webshims/shims/combos/12.js index a497911c..22bcef70 100644 --- a/public/webshims/shims/combos/12.js +++ b/public/webshims/shims/combos/12.js @@ -893,10 +893,11 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u var copyName = {srclang: 'language'}; var updateMediaTrackList = function(baseData, trackList){ + var i, len; + var callChange = false; var removed = []; var added = []; var newTracks = []; - var i, len; if(!baseData){ baseData = webshims.data(this, 'mediaelementBase') || webshims.data(this, 'mediaelementBase', {}); } @@ -931,12 +932,13 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u removed.push(trackList[i]); } } - + if(removed.length || added.length){ trackList.splice(0); for(i = 0, len = newTracks.length; i < len; i++){ trackList.push(newTracks[i]); + } for(i = 0, len = removed.length; i < len; i++){ $([trackList]).triggerHandler($.Event({type: 'removetrack', track: removed[i]})); @@ -949,6 +951,16 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u $(this).triggerHandler('updatetrackdisplay'); } } + + for(i = 0, len = trackList.length; i < len; i++){ + if(trackList[i].__wsmode != trackList[i].mode){ + trackList[i].__wsmode = trackList[i].mode; + callChange = true; + } + } + if(callChange){ + $([trackList]).triggerHandler('change'); + } }; var refreshTrack = function(track, trackData){ diff --git a/public/webshims/shims/combos/13.js b/public/webshims/shims/combos/13.js index 12cb9955..28fc13ac 100644 --- a/public/webshims/shims/combos/13.js +++ b/public/webshims/shims/combos/13.js @@ -670,10 +670,11 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u var copyName = {srclang: 'language'}; var updateMediaTrackList = function(baseData, trackList){ + var i, len; + var callChange = false; var removed = []; var added = []; var newTracks = []; - var i, len; if(!baseData){ baseData = webshims.data(this, 'mediaelementBase') || webshims.data(this, 'mediaelementBase', {}); } @@ -708,12 +709,13 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u removed.push(trackList[i]); } } - + if(removed.length || added.length){ trackList.splice(0); for(i = 0, len = newTracks.length; i < len; i++){ trackList.push(newTracks[i]); + } for(i = 0, len = removed.length; i < len; i++){ $([trackList]).triggerHandler($.Event({type: 'removetrack', track: removed[i]})); @@ -726,6 +728,16 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u $(this).triggerHandler('updatetrackdisplay'); } } + + for(i = 0, len = trackList.length; i < len; i++){ + if(trackList[i].__wsmode != trackList[i].mode){ + trackList[i].__wsmode = trackList[i].mode; + callChange = true; + } + } + if(callChange){ + $([trackList]).triggerHandler('change'); + } }; var refreshTrack = function(track, trackData){ diff --git a/public/webshims/shims/combos/15.js b/public/webshims/shims/combos/15.js index 4bb2d83d..741a9c8b 100644 --- a/public/webshims/shims/combos/15.js +++ b/public/webshims/shims/combos/15.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1487,6 +1492,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; @@ -2149,22 +2156,25 @@ if(webshims.support.inputtypes.date && /webkit/i.test(navigator.userAgent)){ webshims.addReady(function(context, contextElem){ //start constrain-validation - var focusElem; + $('form', context) .add(contextElem.filter('form')) .on('invalid', $.noop) ; - - try { - if(context == document && !('form' in (document.activeElement || {}))) { - focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; - if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) { - focusElem.focus(); + + setTimeout(function(){ + var focusElem; + try { + if(!('form' in (document.activeElement || {}))) { + focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; + if (focusElem && (focusElem.offsetHeight || focusElem.offsetWidth)) { + focusElem.focus(); + } } } - } - catch (er) {} - + catch (er) {} + }, 9); + }); if(!webshims.support.datalist){ diff --git a/public/webshims/shims/combos/16.js b/public/webshims/shims/combos/16.js index 6d835b00..dcf1e2f8 100644 --- a/public/webshims/shims/combos/16.js +++ b/public/webshims/shims/combos/16.js @@ -325,20 +325,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -759,7 +764,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1710,6 +1715,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; @@ -2372,22 +2379,25 @@ if(webshims.support.inputtypes.date && /webkit/i.test(navigator.userAgent)){ webshims.addReady(function(context, contextElem){ //start constrain-validation - var focusElem; + $('form', context) .add(contextElem.filter('form')) .on('invalid', $.noop) ; - - try { - if(context == document && !('form' in (document.activeElement || {}))) { - focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; - if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) { - focusElem.focus(); + + setTimeout(function(){ + var focusElem; + try { + if(!('form' in (document.activeElement || {}))) { + focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; + if (focusElem && (focusElem.offsetHeight || focusElem.offsetWidth)) { + focusElem.focus(); + } } } - } - catch (er) {} - + catch (er) {} + }, 9); + }); if(!webshims.support.datalist){ diff --git a/public/webshims/shims/combos/17.js b/public/webshims/shims/combos/17.js index cd7e1c39..0f7d0c4e 100644 --- a/public/webshims/shims/combos/17.js +++ b/public/webshims/shims/combos/17.js @@ -1660,9 +1660,13 @@ webshims.register('form-number-date-api', function($, webshims, window, document }, time: function(val, o, noCorrect){ var fVal, i; + if(val){ val = val.split(':'); + if(val.length != 2 || isNaN(parseInt(val[0] || '', 10)) || isNaN(parseInt(val[1] || '', 10))){ + return val.join(':'); + } if(curCfg.meridian){ fVal = (val[0] * 1); if(fVal && fVal >= 12){ @@ -1817,6 +1821,7 @@ webshims.register('form-number-date-api', function($, webshims, window, document createFormat('d'); var tmp, obj; var ret = ''; + if(opts.splitInput){ obj = {yy: 0, mm: 1, dd: 2}; } else { @@ -1838,8 +1843,7 @@ webshims.register('form-number-date-api', function($, webshims, window, document } ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-'); } - return ret - ; + return ret; }, color: function(val, opts){ var ret = '#000000'; @@ -2141,9 +2145,11 @@ webshims.register('form-number-date-api', function($, webshims, window, document }; ['defaultValue', 'value'].forEach(function(name){ + var formatName = 'format'+name; wsWidgetProto[name] = function(val, force){ - if(!this._init || force || val !== this.options[name]){ - this.element.prop(name, this.formatValue(val)); + if(!this._init || force || val !== this.options[name] || this.options[formatName] != this.element.prop(name)){ + this.options[formatName] = this.formatValue(val); + this.element.prop(name, this.options[formatName]); this.options[name] = val; this._propertyChange(name); this.mirrorValidity(); @@ -2267,36 +2273,34 @@ webshims.register('form-number-date-api', function($, webshims, window, document var isValue = name == 'value'; spinBtnProto[name] = function(val, force, isLive){ var selectionEnd; - if(!this._init || force || this.options[name] !== val){ - if(isValue){ - this._beforeValue(val); - } else { - this.elemHelper.prop(name, val); - } - - val = formatVal[this.type](val, this.options); - if(this.options.splitInput){ - $.each(this.splits, function(i, elem){ - var setOption; - if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ - $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); - } else { - $.prop(elem, name, val[i]); - } - }); - } else { - val = this.toFixed(val); - if(isLive && this._getSelectionEnd){ - selectionEnd = this._getSelectionEnd(val); - } - this.element.prop(name, val); - if(selectionEnd != null){ - this.element.prop('selectionEnd', selectionEnd); - } - } - this._propertyChange(name); - this.mirrorValidity(); + if(isValue){ + this._beforeValue(val); + } else { + this.elemHelper.prop(name, val); } + + val = formatVal[this.type](val, this.options); + if(this.options.splitInput){ + $.each(this.splits, function(i, elem){ + var setOption; + if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ + $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); + } else { + $.prop(elem, name, val[i]); + } + }); + } else { + val = this.toFixed(val); + if(isLive && this._getSelectionEnd){ + selectionEnd = this._getSelectionEnd(val); + } + this.element.prop(name, val); + if(selectionEnd != null){ + this.element.prop('selectionEnd', selectionEnd); + } + } + this._propertyChange(name); + this.mirrorValidity(); }; }); diff --git a/public/webshims/shims/combos/18.js b/public/webshims/shims/combos/18.js index 9f38e644..a6542797 100644 --- a/public/webshims/shims/combos/18.js +++ b/public/webshims/shims/combos/18.js @@ -1,580 +1,440 @@ -webshim.ready('matchMedia', function($, webshim, w, doc, undefined){ - try { - new Image(); - } catch(e){ - window.Image = function(){ - return document.createElement('img'); - }; +/*! respimage - v0.9.5 - 2014-10-22 + Licensed MIT */ +!function(window, document, undefined) { + "use strict"; + function trim(str) { + return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ""); } - webshim.isReady('picture', true); -// Enable strict mode + function updateView() { + isVwDirty = !1, ri.vW = window.innerWidth || Math.max(docElem.offsetWidth || 0, docElem.clientWidth || 0), + vH = window.innerHeight || Math.max(docElem.offsetHeight || 0, docElem.clientHeight || 0); + } + function parseDescriptor(descriptor) { + if (!(descriptor in memDescriptor)) { + var descriptorObj = { + val: 1, + type: "x" + }, parsedDescriptor = trim(descriptor || ""); + parsedDescriptor && (parsedDescriptor.match(regDescriptor) ? (descriptorObj.val = 1 * RegExp.$1, + descriptorObj.type = RegExp.$2) : descriptorObj = !1), memDescriptor[descriptor] = descriptorObj; + } + return memDescriptor[descriptor]; + } + function chooseLowRes(lowRes, diff, dpr) { + return lowRes / dpr > .2 && (lowRes += diff * greed, diff > tHigh && (lowRes += tLow)), + lowRes > dpr; + } + function inView(el) { + if (!el.getBoundingClientRect) return !0; + var bottom, right, left, top, rect = el.getBoundingClientRect(); + return !!((bottom = rect.bottom) >= -9 && (top = rect.top) <= vH + 9 && (right = rect.right) >= -9 && (left = rect.left) <= ri.vW + 9 && (bottom || right || left || top)); + } + function applyBestCandidate(img) { + var srcSetCandidates, matchingSet = ri.getSet(img), evaluated = !1; + "pending" != matchingSet && (evaluated = !0, matchingSet && (srcSetCandidates = ri.setRes(matchingSet), + evaluated = ri.applySetCandidate(srcSetCandidates, img))), img[ri.ns].evaled = evaluated; + } + function ascendingSort(a, b) { + return a.res - b.res; + } + function setSrcToCur(img, src, set) { + var candidate; + return !set && src && (set = img[ri.ns].sets, set = set && set[set.length - 1]), + candidate = getCandidateForSrc(src, set), candidate && (src = ri.makeUrl(src), img[ri.ns].curSrc = src, + img[ri.ns].curCan = candidate, currentSrcSupported || (img.currentSrc = src), candidate.res || setResolution(candidate, candidate.set.sizes)), + candidate; + } + function getCandidateForSrc(src, set) { + var i, candidate, candidates; + if (src && set) for (candidates = ri.parseSet(set), src = ri.makeUrl(src), i = 0; i < candidates.length; i++) if (src == ri.makeUrl(candidates[i].url)) { + candidate = candidates[i]; + break; + } + return candidate; + } + function hasOneX(set) { + var i, ret, candidates, desc; + if (set) for (candidates = ri.parseSet(set), i = 0; i < candidates.length; i++) if (desc = candidates[i].desc, + "x" == desc.type && 1 == desc.val) { + ret = !0; + break; + } + return ret; + } + function hasWDescripor(set) { + if (!set) return !1; + var candidates = ri.parseSet(set); + return candidates[0] && "w" == candidates[0].desc.type; + } + function getAllSourceElements(picture, candidates) { + var i, len, source, srcset, sources = picture.getElementsByTagName("source"); + for (i = 0, len = sources.length; len > i; i++) source = sources[i], source[ri.ns] = !0, + srcset = source.getAttribute("srcset"), srcset && candidates.push({ + srcset: srcset, + media: source.getAttribute("media"), + type: source.getAttribute("type"), + sizes: source.getAttribute("sizes") + }); + } + function setResolution(candidate, sizesattr) { + var descriptor = candidate.desc; + return "w" == descriptor.type ? (candidate.cWidth = ri.calcListLength(sizesattr || "100vw"), + candidate.res = descriptor.val / candidate.cWidth) : candidate.res = descriptor.val, + candidate; + } + document.createElement("picture"); + var lengthElInstered, lengthEl, currentSrcSupported, curSrcProp, ri = {}, noop = function() {}, image = document.createElement("img"), getImgAttr = image.getAttribute, setImgAttr = image.setAttribute, removeImgAttr = image.removeAttribute, docElem = document.documentElement, types = {}, cfg = { + addSize: !1, + xQuant: 1, + tLow: .1, + tHigh: .5, + tLazy: .1, + greed: .32 + }, srcAttr = "data-risrc", srcsetAttr = srcAttr + "set"; + ri.ns = ("ri" + new Date().getTime()).substr(0, 9), currentSrcSupported = "currentSrc" in image, + curSrcProp = currentSrcSupported ? "currentSrc" : "src", ri.supSrcset = "srcset" in image, + ri.supSizes = "sizes" in image, ri.selShort = "picture > img, img[srcset]", ri.sel = ri.selShort, + ri.cfg = cfg, ri.supSrcset && (ri.sel += ", img[" + srcsetAttr + "]"); + var anchor = document.createElement("a"); + ri.makeUrl = function(src) { + return anchor.href = src, anchor.href; + }, ri.qsa = function(context, sel) { + return context.querySelectorAll(sel); + }; + { + var on = (window.console && "function" == typeof console.warn ? function(message) { + console.warn(message); + } : noop, function(obj, evt, fn, capture) { + obj.addEventListener ? obj.addEventListener(evt, fn, capture || !1) : obj.attachEvent && obj.attachEvent("on" + evt, fn); + }), off = function(obj, evt, fn, capture) { + obj.removeEventListener ? obj.removeEventListener(evt, fn, capture || !1) : obj.detachEvent && obj.detachEvent("on" + evt, fn); + }; + "https:" == location.protocol; + } + ri.matchesMedia = function() { + return ri.matchesMedia = window.matchMedia && (matchMedia("(min-width: 0.1em)") || {}).matches ? function(media) { + return !media || matchMedia(media).matches; + } : ri.mMQ, ri.matchesMedia.apply(this, arguments); + }, ri.vW = 0; + var vH, isVwDirty = !0, regex = { + minw: /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/, + maxw: /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ + }, mediaCache = {}; + ri.mMQ = function(media) { + var min, max, ret = !1; + return media ? (mediaCache[media] || (min = media.match(regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""), + max = media.match(regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""), min && (min = parseFloat(min, 10) * (min.indexOf("em") > 0 ? ri.getEmValue() : 1)), + max && (max = parseFloat(max, 10) * (max.indexOf("em") > 0 ? ri.getEmValue() : 1)), + mediaCache[media] = { + min: min, + max: max + }), min = mediaCache[media].min, max = mediaCache[media].max, (min && ri.vW >= min || max && ri.vW <= max) && (ret = !0), + ret) : !0; + }, ri.DPR = window.devicePixelRatio || 1; + var lengthCache = {}, regLength = /^([\d\.]+)(em|vw|px)$/, baseStyle = "position:absolute;left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;"; + ri.calcLength = function(sourceSizeValue) { + var failed, parsedLength, orirgValue = sourceSizeValue, value = !1; + if (!(orirgValue in lengthCache)) { + if (parsedLength = sourceSizeValue.match(regLength)) parsedLength[1] = parseFloat(parsedLength[1], 10), + value = parsedLength[1] ? "vw" == parsedLength[2] ? ri.vW * parsedLength[1] / 100 : "em" == parsedLength[2] ? ri.getEmValue() * parsedLength[1] : parsedLength[1] : !1; else if (sourceSizeValue.indexOf("calc") > -1 || parseInt(sourceSizeValue, 10)) { + sourceSizeValue = sourceSizeValue.replace("vw", "%"), lengthEl || (lengthEl = document.createElement("div"), + lengthEl.style.cssText = baseStyle), lengthElInstered || (lengthElInstered = !0, + docElem.insertBefore(lengthEl, docElem.firstChild)), lengthEl.style.width = "0px"; + try { + lengthEl.style.width = sourceSizeValue; + } catch (e) { + failed = !0; + } + value = lengthEl.offsetWidth, failed && (value = !1); + } + 0 >= value && (value = !1), lengthCache[orirgValue] = value; + } + return lengthCache[orirgValue]; + }, ri.types = types, types["image/jpeg"] = !0, types["image/gif"] = !0, types["image/png"] = !0, + types["image/svg+xml"] = document.implementation.hasFeature("http://wwwindow.w3.org/TR/SVG11/feature#Image", "1.1"), + ri.supportsType = function(type) { + return type ? types[type] : !0; + }; + var regSize = /(\([^)]+\))?\s*(.+)/, memSize = {}; + ri.parseSize = function(sourceSizeStr) { + var match; + return memSize[sourceSizeStr] || (match = (sourceSizeStr || "").match(regSize), + memSize[sourceSizeStr] = { + media: match && match[1], + length: match && match[2] + }), memSize[sourceSizeStr]; + }, ri.parseSet = function(set) { + if (!set.cands) { + var pos, url, descriptor, last, descpos, srcset = set.srcset; + for (set.cands = []; srcset; ) srcset = srcset.replace(/^\s+/g, ""), pos = srcset.search(/\s/g), + descriptor = null, -1 != pos ? (url = srcset.slice(0, pos), last = url.charAt(url.length - 1), + "," != last && url || (url = url.replace(/,+$/, ""), descriptor = ""), srcset = srcset.slice(pos + 1), + null == descriptor && (descpos = srcset.indexOf(","), -1 != descpos ? (descriptor = srcset.slice(0, descpos), + srcset = srcset.slice(descpos + 1)) : (descriptor = srcset, srcset = ""))) : (url = srcset, + srcset = ""), url && (descriptor = parseDescriptor(descriptor)) && set.cands.push({ + url: url.replace(/^,+/, ""), + desc: descriptor, + set: set + }); + } + return set.cands; + }; + var eminpx, memDescriptor = {}, regDescriptor = /^([\+eE\d\.]+)(w|x)$/, fsCss = "font-size:100% !important;"; + ri.getEmValue = function() { + var body; + if (!eminpx && (body = document.body)) { + var div = document.createElement("div"), originalHTMLCSS = docElem.style.cssText, originalBodyCSS = body.style.cssText; + div.style.cssText = baseStyle, docElem.style.cssText = fsCss, body.style.cssText = fsCss, + body.appendChild(div), eminpx = div.offsetWidth, body.removeChild(div), eminpx = parseFloat(eminpx, 10), + docElem.style.cssText = originalHTMLCSS, body.style.cssText = originalBodyCSS; + } + return eminpx || 16; + }; + var sizeLengthCache = {}; + ri.calcListLength = function(sourceSizeListStr) { + if (!(sourceSizeListStr in sizeLengthCache) || cfg.uT) { + var sourceSize, parsedSize, length, media, i, len, sourceSizeList = trim(sourceSizeListStr).split(/\s*,\s*/), winningLength = !1; + for (i = 0, len = sourceSizeList.length; len > i && (sourceSize = sourceSizeList[i], + parsedSize = ri.parseSize(sourceSize), length = parsedSize.length, media = parsedSize.media, + !length || !ri.matchesMedia(media) || (winningLength = ri.calcLength(length)) === !1); i++) ; + sizeLengthCache[sourceSizeListStr] = winningLength ? winningLength : ri.vW; + } + return sizeLengthCache[sourceSizeListStr]; + }, ri.setRes = function(set) { + var candidates, candidate; + if (set) { + candidates = ri.parseSet(set); + for (var i = 0, len = candidates.length; len > i; i++) candidate = candidates[i], + candidate.descriptor || setResolution(candidate, set.sizes); + } + return candidates; + }; + var dprM, tLow, greed, tLazy, tHigh, tMemory, isWinComplete; + ri.applySetCandidate = function(candidates, img) { + if (candidates.length) { + var candidate, dpr, i, j, diff, length, bestCandidate, curSrc, curCan, isSameSet, candidateSrc, imageData = img[ri.ns], evaled = !0; + if (curSrc = imageData.curSrc || img[curSrcProp], curCan = imageData.curCan || setSrcToCur(img, curSrc, candidates[0].set), + dpr = ri.getX(candidates, curCan), curSrc && (curCan && (curCan.res += tLazy), isSameSet = !imageData.pic || curCan && curCan.set == candidates[0].set, + curCan && isSameSet && curCan.res >= dpr && tMemory > curCan.res - dpr ? bestCandidate = curCan : img.complete || imageData.src != getImgAttr.call(img, "src") || img.lazyload || (isSameSet || !isWinComplete && !inView(img)) && (bestCandidate = curCan, + candidateSrc = curSrc, evaled = "lazy", isWinComplete && reevaluateAfterLoad(img))), + !bestCandidate) for (candidates.sort(ascendingSort), length = candidates.length, + bestCandidate = candidates[length - 1], i = 0; length > i; i++) if (candidate = candidates[i], + candidate.res >= dpr) { + j = i - 1, bestCandidate = candidates[j] && (diff = candidate.res - dpr) && curSrc != ri.makeUrl(candidate.url) && chooseLowRes(candidates[j].res, diff, dpr) ? candidates[j] : candidate; + break; + } + return curSrc && curCan && (curCan.res -= tLazy), bestCandidate && (candidateSrc = ri.makeUrl(bestCandidate.url), + currentSrcSupported || (img.currentSrc = candidateSrc), imageData.curSrc = candidateSrc, + imageData.curCan = bestCandidate, candidateSrc != curSrc ? ri.setSrc(img, bestCandidate) : ri.setSize(img)), + evaled; + } + }; + ri.getX = function() { + return ri.DPR * cfg.xQuant; + }, ri.setSrc = function(img, bestCandidate) { + var origWidth; + img.src = bestCandidate.url, "image/svg+xml" == bestCandidate.set.type && (origWidth = img.style.width, + img.style.width = img.offsetWidth + 1 + "px", img.offsetWidth + 1 && (img.style.width = origWidth)); + }; + var intrinsicSizeHandler = function() { + off(this, "load", intrinsicSizeHandler), ri.setSize(this); + }; + ri.setSize = function(img) { + var width, curCandidate = img[ri.ns].curCan; + cfg.addSize && curCandidate && !img[ri.ns].dims && (img.complete || (off(img, "load", intrinsicSizeHandler), + on(img, "load", intrinsicSizeHandler)), width = img.naturalWidth, width && ("x" == curCandidate.desc.type ? setImgAttr.call(img, "width", parseInt(width / curCandidate.res / cfg.xQuant, 10)) : "w" == curCandidate.desc.type && setImgAttr.call(img, "width", parseInt(curCandidate.cWidth * (width / curCandidate.desc.val), 10)))); + }, document.addEventListener && "naturalWidth" in image && "complete" in image || (ri.setSize = noop), + ri.getSet = function(img) { + var i, set, supportsType, match = !1, sets = img[ri.ns].sets; + for (i = 0; i < sets.length && !match; i++) if (set = sets[i], set.srcset && ri.matchesMedia(set.media) && (supportsType = ri.supportsType(set.type))) { + "pending" == supportsType && (set = supportsType), match = set; + break; + } + return match; + }; + var alwaysCheckWDescriptor = ri.supSrcset && !ri.supSizes; + ri.parseSets = function(element, parent) { + var srcsetAttribute, fallbackCandidate, isWDescripor, srcsetParsed, hasPicture = "PICTURE" == parent.nodeName.toUpperCase(), imageData = element[ri.ns]; + imageData.src === undefined && (imageData.src = getImgAttr.call(element, "src"), + imageData.src ? setImgAttr.call(element, srcAttr, imageData.src) : removeImgAttr.call(element, srcAttr)), + imageData.srcset === undefined && (srcsetAttribute = getImgAttr.call(element, "srcset"), + imageData.srcset = srcsetAttribute, srcsetParsed = !0), imageData.dims === undefined && (imageData.dims = getImgAttr.call(element, "height") && getImgAttr.call(element, "width")), + imageData.sets = [], hasPicture && (imageData.pic = !0, getAllSourceElements(parent, imageData.sets)), + imageData.srcset ? (fallbackCandidate = { + srcset: imageData.srcset, + sizes: getImgAttr.call(element, "sizes") + }, imageData.sets.push(fallbackCandidate), isWDescripor = alwaysCheckWDescriptor || imageData.src ? hasWDescripor(fallbackCandidate) : !1, + isWDescripor || !imageData.src || getCandidateForSrc(imageData.src, fallbackCandidate) || hasOneX(fallbackCandidate) || (fallbackCandidate.srcset += ", " + imageData.src, + fallbackCandidate.cands = !1)) : imageData.src && imageData.sets.push({ + srcset: imageData.src, + sizes: null + }), imageData.curCan = null, imageData.supported = !(hasPicture || fallbackCandidate && !ri.supSrcset || isWDescripor), + srcsetParsed && ri.supSrcset && !imageData.supported && (srcsetAttribute ? (setImgAttr.call(element, srcsetAttr, srcsetAttribute), + element.srcset = "") : removeImgAttr.call(element, srcsetAttr)), imageData.parsed = !0; + }; + var reevaluateAfterLoad = function() { + var onload = function() { + off(this, "load", onload), ri.fillImgs({ + elements: [ this ] + }); + }; + return function(img) { + off(img, "load", onload), on(img, "load", onload); + }; + }(); + ri.fillImg = function(element, options) { + var parent, imageData, extreme = options.reparse || options.reevaluate; + if (element[ri.ns] || (element[ri.ns] = {}), imageData = element[ri.ns], "lazy" == imageData.evaled && (isWinComplete || element.complete) && (imageData.evaled = !1), + extreme || !imageData.evaled) { + if (!imageData.parsed || options.reparse) { + if (parent = element.parentNode, !parent) return; + ri.parseSets(element, parent, options); + } + imageData.supported ? imageData.evaled = !0 : applyBestCandidate(element); + } + }; + var resizeThrottle; + ri.setupRun = function(options) { + (!alreadyRun || options.reevaluate || isVwDirty) && (cfg.uT || (ri.DPR = window.devicePixelRatio || 1), + dprM = Math.min(Math.max(ri.DPR * cfg.xQuant, 1), 2.5), tLow = cfg.tLow * dprM, + tLazy = cfg.tLazy * dprM, greed = cfg.greed * dprM, tHigh = cfg.tHigh, tMemory = .6 + .4 * dprM + tLazy), + isVwDirty && (lengthCache = {}, sizeLengthCache = {}, updateView(), options.elements || options.context || clearTimeout(resizeThrottle)); + }, ri.teardownRun = function() { + var parent; + lengthElInstered && (lengthElInstered = !1, parent = lengthEl.parentNode, parent && parent.removeChild(lengthEl)); + }; + var alreadyRun = !1, respimage = function(opt) { + var elements, i, plen, options = opt || {}; + if (options.elements && 1 == options.elements.nodeType && ("IMG" == options.elements.nodeName.toUpperCase() ? options.elements = [ options.elements ] : (options.context = options.elements, + options.elements = null)), elements = options.elements || ri.qsa(options.context || document, options.reevaluate || options.reparse ? ri.sel : ri.selShort), + plen = elements.length) { + for (ri.setupRun(options), alreadyRun = !0, i = 0; plen > i; i++) ri.fillImg(elements[i], options); + ri.teardownRun(options); + } + }; + ri.fillImgs = respimage, window.HTMLPictureElement ? (respimage = noop, ri.fillImg = noop) : !function() { + var regWinComplete = /^loade|^c/, run = function() { + clearTimeout(timerId), timerId = setTimeout(run, 3e3), document.body && (regWinComplete.test(document.readyState || "") && (isWinComplete = !0, + clearTimeout(timerId), off(document, "readystatechange", run)), ri.fillImgs()); + }, resizeEval = function() { + ri.fillImgs({ + reevaluate: !0 + }); + }, onResize = function() { + clearTimeout(resizeThrottle), isVwDirty = !0, resizeThrottle = setTimeout(resizeEval, 99); + }, timerId = setTimeout(run, document.body ? 9 : 99); + on(window, "resize", onResize), on(document, "readystatechange", run); + }(), respimage._ = ri, respimage.config = function(name, value, value2) { + if ("addType" == name) { + if (types[value] = value2, "pending" == value2) return; + } else cfg[name] = value; + alreadyRun && ri.fillImgs({ + reevaluate: !0 + }); + }, window.respimage = respimage; +}(window, document); +(function( factory ) { + "use strict"; + var interValId; + var intervalIndex = 0; + var run = function(){ + if ( window.respimage ) { + factory( window.respimage ); + } + if(window.respimage || intervalIndex > 9999){ + clearInterval(interValId); + } + intervalIndex++; + }; + interValId = setInterval(run, 8); + + run(); + +}( function( respimage ) { "use strict"; - // If picture is supported, well, that's awesome. Let's get outta here... - if ( w.HTMLPictureElement ) { - w.picturefill = function() { }; + var ri = respimage._; + var runningTests = 0; + var setTypeValue = function(types, value){ + var i; + for(i = 0; i < types.length; i++){ + ri.types[types[i]] = value; + } + }; + + if(window.HTMLPictureElement && !ri.cfg.uT){ + respimage.testTypeSupport = function(){}; return; } - // HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround) - doc.createElement( "picture" ); + ri.types["image/bmp"] = true; + ri.types["image/x-bmp"] = true; - // local object for method references and testing exposure - var pf = {}; - - // namespace - pf.ns = "picturefill"; - - // srcset support test - pf.srcsetSupported = "srcset" in doc.createElement( "img" ); - pf.sizesSupported = w.HTMLImageElement.sizes; - - // just a string trim workaround - pf.trim = function( str ) { - return str.trim ? str.trim() : str.replace( /^\s+|\s+$/g, "" ); - }; - - // just a string endsWith workaround - pf.endsWith = function( str, suffix ) { - return str.endsWith ? str.endsWith( suffix ) : str.indexOf( suffix, str.length - suffix.length ) !== -1; - }; - - /** - * Shortcut method for matchMedia ( for easy overriding in tests ) - */ - pf.matchesMedia = function( media ) { - return w.matchMedia && w.matchMedia( media ).matches; - }; - - /** - * Shortcut method for `devicePixelRatio` ( for easy overriding in tests ) - */ - pf.getDpr = function() { - return ( w.devicePixelRatio || 1 ); - }; - - /** - * Get width in css pixel value from a "length" value - * http://dev.w3.org/csswg/css-values-3/#length-value - */ - pf.getWidthFromLength = function( length ) { - // If no length was specified, or it is 0 or negative, default to `100vw` (per the spec). - length = length && ( parseFloat( length ) > 0 || length.indexOf( "calc(" ) > -1 ) ? length : "100vw"; - - /** - * If length is specified in `vw` units, use `%` instead since the div we’re measuring - * is injected at the top of the document. - * - * TODO: maybe we should put this behind a feature test for `vw`? - */ - length = length.replace( "vw", "%" ); - - // Create a cached element for getting length value widths - if ( !pf.lengthEl ) { - pf.lengthEl = doc.createElement( "div" ); - doc.documentElement.insertBefore( pf.lengthEl, doc.documentElement.firstChild ); + respimage.testTypeSupport = function(types, url, width, useCanvas){ + if(typeof types == "string"){ + types = types.split(/\s*\,*\s+/g); } - - // Positioning styles help prevent padding/margin/width on `html` from throwing calculations off. - pf.lengthEl.style.cssText = "position: absolute; left: 0; width: " + length + ";"; - - if ( pf.lengthEl.offsetWidth <= 0 ) { - // Something has gone wrong. `calc()` is in use and unsupported, most likely. Default to `100vw` (`100%`, for broader support.): - pf.lengthEl.style.cssText = "width: 100%;"; - } - - return pf.lengthEl.offsetWidth; - }; - - // container of supported mime types that one might need to qualify before using - pf.types = {}; - - // Add support for standard mime types. - pf.types["image/jpeg"] = true; - pf.types["image/gif"] = true; - pf.types["image/png"] = true; - - // test svg support - pf.types[ "image/svg+xml" ] = doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1"); - - // test webp support, only when the markup calls for it - pf.types[ "image/webp" ] = function() { - // based on Modernizr's lossless img-webp test - // note: asynchronous - var img = new w.Image(), - type = "image/webp"; - - img.onerror = function() { - pf.types[ type ] = false; - picturefill(); + var canvas; + var supports = "pending"; + var img = document.createElement('img'); + var onComplete = function(){ + runningTests--; + setTypeValue(types, supports); + if(runningTests < 1){ + respimage({reevaluate: true}); + } }; - img.onload = function() { - pf.types[ type ] = img.width === 1; - picturefill(); - }; - img.src = "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA="; - }; - /** - * Takes a source element and checks if its type attribute is present and if so, supported - * Note: for type tests that require a async logic, - * you can define them as a function that'll run only if that type needs to be tested. Just make the test function call picturefill again when it is complete. - * see the async webp test above for example - */ - pf.verifyTypeSupport = function( source ) { - var type = source.getAttribute( "type" ); - // if type attribute exists, return test result, otherwise return true - if ( type === null || type === "" ) { - return true; - } else { - // if the type test is a function, run it and return "pending" status. The function will rerun picturefill on pending elements once finished. - if ( typeof( pf.types[ type ] ) === "function" ) { - pf.types[ type ](); - return "pending"; - } else { - return pf.types[ type ]; - } - } - }; - - /** - * Parses an individual `size` and returns the length, and optional media query - */ - pf.parseSize = function( sourceSizeStr ) { - var match = /(\([^)]+\))?\s*(.+)/g.exec( sourceSizeStr ); - return { - media: match && match[1], - length: match && match[2] - }; - }; - - /** - * Takes a string of sizes and returns the width in pixels as a number - */ - pf.findWidthFromSourceSize = function( sourceSizeListStr ) { - // Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33% - // or (min-width:30em) calc(30% - 15px) - var sourceSizeList = pf.trim( sourceSizeListStr ).split( /\s*,\s*/ ), - winningLength; - - for ( var i = 0, len = sourceSizeList.length; i < len; i++ ) { - // Match ? length, ie ( min-width: 50em ) 100% - var sourceSize = sourceSizeList[ i ], - // Split "( min-width: 50em ) 100%" into separate strings - parsedSize = pf.parseSize( sourceSize ), - length = parsedSize.length, - media = parsedSize.media; - - if ( !length ) { - continue; - } - if ( !media || pf.matchesMedia( media ) ) { - // if there is no media query or it matches, choose this as our winning length - // and end algorithm - winningLength = length; - break; - } - } - - // pass the length to a method that can properly determine length - // in pixels based on these formats: http://dev.w3.org/csswg/css-values-3/#length-value - return pf.getWidthFromLength( winningLength ); - }; - - pf.parseSrcset = function( srcset ) { - /** - * A lot of this was pulled from Boris Smus’ parser for the now-defunct WHATWG `srcset` - * https://github.com/borismus/srcset-polyfill/blob/master/js/srcset-info.js - * - * 1. Let input (`srcset`) be the value passed to this algorithm. - * 2. Let position be a pointer into input, initially pointing at the start of the string. - * 3. Let raw candidates be an initially empty ordered list of URLs with associated - * unparsed descriptors. The order of entries in the list is the order in which entries - * are added to the list. - */ - var candidates = []; - - while ( srcset !== "" ) { - srcset = srcset.replace(/^\s+/g,""); - - // 5. Collect a sequence of characters that are not space characters, and let that be url. - var pos = srcset.search(/\s/g), - url, descriptor = null; - - if ( pos !== -1 ) { - url = srcset.slice( 0, pos ); - - var last = url[ url.length - 1 ]; - - // 6. If url ends with a U+002C COMMA character (,), remove that character from url - // and let descriptors be the empty string. Otherwise, follow these substeps - // 6.1. If url is empty, then jump to the step labeled descriptor parser. - - if ( last === "," || url === "" ) { - url = url.replace(/,+$/, ""); - descriptor = ""; - } - srcset = srcset.slice( pos + 1 ); - - // 6.2. Collect a sequence of characters that are not U+002C COMMA characters (,), and - // let that be descriptors. - if ( descriptor === null ) { - var descpos = srcset.indexOf(","); - if ( descpos !== -1 ) { - descriptor = srcset.slice( 0, descpos ); - srcset = srcset.slice( descpos + 1 ); - } else { - descriptor = srcset; - srcset = ""; - } - } - } else { - url = srcset; - srcset = ""; - } - - // 7. Add url to raw candidates, associated with descriptors. - if ( url || descriptor ) { - candidates.push({ - url: url, - descriptor: descriptor - }); - } - } - return candidates; - }; - - pf.parseDescriptor = function( descriptor, sizesattr ) { - // 11. Descriptor parser: Let candidates be an initially empty source set. The order of entries in the list - // is the order in which entries are added to the list. - var sizes = sizesattr || "100vw", - sizeDescriptor = descriptor && descriptor.replace(/(^\s+|\s+$)/g, ""), - widthInCssPixels = pf.findWidthFromSourceSize( sizes ), - resCandidate; - - if ( sizeDescriptor ) { - var splitDescriptor = sizeDescriptor.split(" "); - - for (var i = splitDescriptor.length + 1; i >= 0; i--) { - if ( splitDescriptor[ i ] !== undefined ) { - var curr = splitDescriptor[ i ], - lastchar = curr && curr.slice( curr.length - 1 ); - - if ( ( lastchar === "h" || lastchar === "w" ) && !pf.sizesSupported ) { - resCandidate = parseFloat( ( parseInt( curr, 10 ) / widthInCssPixels ) ); - } else if ( lastchar === "x" ) { - var res = curr && parseFloat( curr, 10 ); - resCandidate = res && !isNaN( res ) ? res : 1; - } - } - } - } - return resCandidate || 1; - }; - - /** - * Takes a srcset in the form of url/ - * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or - * "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or - * "images/pic-small.png" - * Get an array of image candidates in the form of - * {url: "/foo/bar.png", resolution: 1} - * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value - * If sizes is specified, resolution is calculated - */ - pf.getCandidatesFromSourceSet = function( srcset, sizes ) { - var candidates = pf.parseSrcset( srcset ), - formattedCandidates = []; - - for ( var i = 0, len = candidates.length; i < len; i++ ) { - var candidate = candidates[ i ]; - - formattedCandidates.push({ - url: candidate.url, - resolution: pf.parseDescriptor( candidate.descriptor, sizes ) - }); - } - return formattedCandidates; - }; - - /* - * if it's an img element and it has a srcset property, - * we need to remove the attribute so we can manipulate src - * (the property's existence infers native srcset support, and a srcset-supporting browser will prioritize srcset's value over our winning picture candidate) - * this moves srcset's value to memory for later use and removes the attr - */ - pf.dodgeSrcset = function( img ) { - if ( img.srcset ) { - img[ pf.ns ].srcset = img.srcset; - img.removeAttribute( "srcset" ); - } - }; - - /* - * Accept a source or img element and process its srcset and sizes attrs - */ - pf.processSourceSet = function( el ) { - var srcset = el.getAttribute( "srcset" ), - sizes = el.getAttribute( "sizes" ), - candidates = []; - - // if it's an img element, use the cached srcset property (defined or not) - if ( el.nodeName.toUpperCase() === "IMG" && el[ pf.ns ] && el[ pf.ns ].srcset ) { - srcset = el[ pf.ns ].srcset; - } - - if ( srcset ) { - candidates = pf.getCandidatesFromSourceSet( srcset, sizes ); - } - return candidates; - }; - - pf.applyBestCandidate = function( candidates, picImg ) { - var candidate, - length, - bestCandidate; - - candidates.sort( pf.ascendingSort ); - - length = candidates.length; - bestCandidate = candidates[ length - 1 ]; - - for ( var i = 0; i < length; i++ ) { - candidate = candidates[ i ]; - if ( candidate.resolution >= pf.getDpr() ) { - bestCandidate = candidate; - break; - } - } - - if ( bestCandidate && !pf.endsWith( picImg.src, bestCandidate.url ) ) { - picImg.src = bestCandidate.url; - // currentSrc attribute and property to match - // http://picture.responsiveimages.org/#the-img-element - picImg.currentSrc = picImg.src; - } - }; - - pf.ascendingSort = function( a, b ) { - return a.resolution - b.resolution; - }; - - /* - * In IE9, elements get removed if they aren't children of - * video elements. Thus, we conditionally wrap source elements - * using - * and must account for that here by moving those source elements - * back into the picture element. - */ - pf.removeVideoShim = function( picture ) { - var videos = picture.getElementsByTagName( "video" ); - if ( videos.length ) { - var video = videos[ 0 ], - vsources = video.getElementsByTagName( "source" ); - while ( vsources.length ) { - picture.insertBefore( vsources[ 0 ], video ); - } - // Remove the video element once we're finished removing its children - video.parentNode.removeChild( video ); - } - }; - - /* - * Find all `img` elements, and add them to the candidate list if they have - * a `picture` parent, a `sizes` attribute in basic `srcset` supporting browsers, - * a `srcset` attribute at all, and they haven’t been evaluated already. - */ - pf.getAllElements = function() { - var elems = [], - imgs = doc.getElementsByTagName( "img" ); - - for ( var h = 0, len = imgs.length; h < len; h++ ) { - var currImg = imgs[ h ]; - - if ( currImg.parentNode.nodeName.toUpperCase() === "PICTURE" || - ( currImg.getAttribute( "srcset" ) !== null ) || currImg[ pf.ns ] && currImg[ pf.ns ].srcset !== null ) { - elems.push( currImg ); - } - } - return elems; - }; - - pf.getMatch = function( img, picture ) { - var sources = picture.childNodes, - match; - - // Go through each child, and if they have media queries, evaluate them - for ( var j = 0, slen = sources.length; j < slen; j++ ) { - var source = sources[ j ]; - - // ignore non-element nodes - if ( source.nodeType !== 1 ) { - continue; - } - - // Hitting the `img` element that started everything stops the search for `sources`. - // If no previous `source` matches, the `img` itself is evaluated later. - if ( source === img ) { - return match; - } - - // ignore non-`source` nodes - if ( source.nodeName.toUpperCase() !== "SOURCE" ) { - continue; - } - // if it's a source element that has the `src` property set, throw a warning in the console - if ( source.getAttribute( "src" ) !== null && typeof console !== undefined ){ - console.warn("The `src` attribute is invalid on `picture` `source` element; instead, use `srcset`."); - } - - var media = source.getAttribute( "media" ); - - // if source does not have a srcset attribute, skip - if ( !source.getAttribute( "srcset" ) ) { - continue; - } - - // if there's no media specified, OR w.matchMedia is supported - if ( ( !media || pf.matchesMedia( media ) ) ) { - var typeSupported = pf.verifyTypeSupport( source ); - - if ( typeSupported === true ) { - match = source; - break; - } else if ( typeSupported === "pending" ) { - return false; - } - } - } - - return match; - }; - - function picturefill( opt ) { - var elements, - element, - parent, - firstMatch, - candidates, - - options = opt || {}; - elements = options.elements || pf.getAllElements(); - - // Loop through all elements - for ( var i = 0, plen = elements.length; i < plen; i++ ) { - element = elements[ i ]; - parent = element.parentNode; - firstMatch = undefined; - candidates = undefined; - - // expando for caching data on the img - if ( !element[ pf.ns ] ) { - element[ pf.ns ] = {}; - } - - // if the element has already been evaluated, skip it - // unless `options.force` is set to true ( this, for example, - // is set to true when running `picturefill` on `resize` ). - if ( !options.reevaluate && element[ pf.ns ].evaluated ) { - continue; - } - - // if `img` is in a `picture` element - if ( parent.nodeName.toUpperCase() === "PICTURE" ) { - - // IE9 video workaround - pf.removeVideoShim( parent ); - - // return the first match which might undefined - // returns false if there is a pending source - // TODO the return type here is brutal, cleanup - firstMatch = pf.getMatch( element, parent ); - - // if any sources are pending in this picture due to async type test(s) - // remove the evaluated attr and skip for now ( the pending test will - // rerun picturefill on this element when complete) - if ( firstMatch === false ) { - continue; - } - } else { - firstMatch = undefined; - } - - // Cache and remove `srcset` if present and we’re going to be doing `picture`/`srcset`/`sizes` polyfilling to it. - if ( parent.nodeName.toUpperCase() === "PICTURE" || - ( element.srcset && !pf.srcsetSupported ) || - ( !pf.sizesSupported && ( element.srcset && element.srcset.indexOf("w") > -1 ) ) ) { - pf.dodgeSrcset( element ); - } - - if ( firstMatch ) { - candidates = pf.processSourceSet( firstMatch ); - pf.applyBestCandidate( candidates, element ); - } else { - // No sources matched, so we’re down to processing the inner `img` as a source. - candidates = pf.processSourceSet( element ); - - if ( element.srcset === undefined || element[ pf.ns ].srcset ) { - // Either `srcset` is completely unsupported, or we need to polyfill `sizes` functionality. - pf.applyBestCandidate( candidates, element ); - } // Else, resolution-only `srcset` is supported natively. - } - - // set evaluated to true to avoid unnecessary reparsing - element[ pf.ns ].evaluated = true; - } - } - - /** - * Sets up picture polyfill by polling the document and running - * the polyfill every 250ms until the document is ready. - * Also attaches picturefill on resize - */ - function runPicturefill() { - picturefill(); - var intervalId = setInterval( function() { - // When the document has finished loading, stop checking for new images - // https://github.com/ded/domready/blob/master/ready.js#L15 - picturefill(); - if ( /^loaded|^i|^c/.test( doc.readyState ) ) { - clearInterval( intervalId ); + if(useCanvas){ + canvas = document.createElement('canvas'); + if(!canvas.getContext){ + setTypeValue(types, false); return; } - }, 250 ); - if ( w.addEventListener ) { - var resizeThrottle; - w.addEventListener( "resize", function() { - if (!w._picturefillWorking) { - w._picturefillWorking = true; - w.clearTimeout( resizeThrottle ); - resizeThrottle = w.setTimeout( function() { - picturefill({ reevaluate: true }); - w._picturefillWorking = false; - }, 60 ); - } - }, false ); } - } - runPicturefill(); - - /* expose methods for testing */ - picturefill._ = pf; - - /* expose picturefill */ - w.picturefill = picturefill; - - (function(){ - - webshim.isReady('picture', true); - var sel = 'picture, img[srcset]'; - webshim.addReady(function(context){ - if(context.querySelector(sel)){ - window.picturefill(); + img.onload = function(){ + var ctx; + supports = true; + if(width){ + supports = img.width == width; } - }); - })(); -} ); + + if(useCanvas){ + ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + supports = ctx.getImageData(0, 0, 1, 1).data[3] === 0; + } + onComplete(); + }; + + img.onerror = function(){ + supports = false; + onComplete(); + }; + runningTests++; + setTypeValue(types, "pending"); + img.src = url; + }; + + + respimage.testTypeSupport("image/webp", "data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==", 1); + respimage.testTypeSupport("image/jp2 image/jpx image/jpm", "data:image/jp2;base64,AAAADGpQICANCocKAAAAFGZ0eXBqcDIgAAAAAGpwMiAAAABHanAyaAAAABZpaGRyAAAAAQAAAAEAAQAHAAAAAAAPY29scgEAAAAAABEAAAAacmVzIAAAABJyZXNjAGAA/gBgAP4EBAAAAABqcDJj/0//UQApAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAABAAEB/1wADUAIEBAYEBAYEBAY/1IADAAAAAEAAwQEAAH/ZAAPAAFMV0ZfSlAyXzIxMf+QAAoAAAAAABIAAf+TgICAgP/Z", 1); + respimage.testTypeSupport("image/vnd.ms-photo", "data:image/vnd.ms-photo;base64,SUm8AQgAAAAFAAG8AQAQAAAASgAAAIC8BAABAAAAAQAAAIG8BAABAAAAAQAAAMC8BAABAAAAWgAAAMG8BAABAAAAHwAAAAAAAAAkw91vA07+S7GFPXd2jckNV01QSE9UTwAZAYBxAAAAABP/gAAEb/8AAQAAAQAAAA==", 1); + respimage.testTypeSupport("video/png video/apng video/x-mng video/x-png", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==", false, true); + +})); + +(function(){ + + webshim.isReady('picture', true); + var sel = 'picture, img[srcset]'; + webshim.addReady(function(context){ + if(context.querySelector(sel)){ + window.respimage(); + } + }); +})(); ;/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ diff --git a/public/webshims/shims/combos/2.js b/public/webshims/shims/combos/2.js index 258147b9..8eb6f76f 100644 --- a/public/webshims/shims/combos/2.js +++ b/public/webshims/shims/combos/2.js @@ -325,20 +325,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -759,7 +764,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1710,6 +1715,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; diff --git a/public/webshims/shims/combos/21.js b/public/webshims/shims/combos/21.js index fd661965..1bceb39c 100644 --- a/public/webshims/shims/combos/21.js +++ b/public/webshims/shims/combos/21.js @@ -1463,6 +1463,25 @@ VIDEO: 1 }; var tested = {}; + var addToBlob = function(){ + var desc = webshim.defineNodeNameProperty('canvas', 'toBlob', { + prop: { + value: function(){ + var context = $(this).callProp('getContext', ['2d']); + var that = this; + var args = arguments; + var cb = function(){ + return desc.prop._supvalue.apply(that, args); + }; + if(context.wsImageComplete && context._wsIsLoading){ + context.wsImageComplete(cb); + } else { + return cb(); + } + } + } + }); + }; if(!_drawImage){ webshim.error('canvas.drawImage feature is needed. In IE8 flashvanvas pro can be used'); @@ -1537,6 +1556,12 @@ } return _drawImage.apply(this, arguments); }; + + if(!document.createElement('canvas').toBlob){ + webshims.ready('filereader', addToBlob); + } else { + addToBlob(); + } return true; }; @@ -1810,10 +1835,11 @@ var copyName = {srclang: 'language'}; var updateMediaTrackList = function(baseData, trackList){ + var i, len; + var callChange = false; var removed = []; var added = []; var newTracks = []; - var i, len; if(!baseData){ baseData = webshims.data(this, 'mediaelementBase') || webshims.data(this, 'mediaelementBase', {}); } @@ -1848,12 +1874,13 @@ removed.push(trackList[i]); } } - + if(removed.length || added.length){ trackList.splice(0); for(i = 0, len = newTracks.length; i < len; i++){ trackList.push(newTracks[i]); + } for(i = 0, len = removed.length; i < len; i++){ $([trackList]).triggerHandler($.Event({type: 'removetrack', track: removed[i]})); @@ -1866,6 +1893,16 @@ $(this).triggerHandler('updatetrackdisplay'); } } + + for(i = 0, len = trackList.length; i < len; i++){ + if(trackList[i].__wsmode != trackList[i].mode){ + trackList[i].__wsmode = trackList[i].mode; + callChange = true; + } + } + if(callChange){ + $([trackList]).triggerHandler('change'); + } }; var refreshTrack = function(track, trackData){ diff --git a/public/webshims/shims/combos/22.js b/public/webshims/shims/combos/22.js index 824dba25..45649a08 100644 --- a/public/webshims/shims/combos/22.js +++ b/public/webshims/shims/combos/22.js @@ -260,10 +260,11 @@ webshims.register('details', function($, webshims, window, doc, undefined, optio var copyName = {srclang: 'language'}; var updateMediaTrackList = function(baseData, trackList){ + var i, len; + var callChange = false; var removed = []; var added = []; var newTracks = []; - var i, len; if(!baseData){ baseData = webshims.data(this, 'mediaelementBase') || webshims.data(this, 'mediaelementBase', {}); } @@ -298,12 +299,13 @@ webshims.register('details', function($, webshims, window, doc, undefined, optio removed.push(trackList[i]); } } - + if(removed.length || added.length){ trackList.splice(0); for(i = 0, len = newTracks.length; i < len; i++){ trackList.push(newTracks[i]); + } for(i = 0, len = removed.length; i < len; i++){ $([trackList]).triggerHandler($.Event({type: 'removetrack', track: removed[i]})); @@ -316,6 +318,16 @@ webshims.register('details', function($, webshims, window, doc, undefined, optio $(this).triggerHandler('updatetrackdisplay'); } } + + for(i = 0, len = trackList.length; i < len; i++){ + if(trackList[i].__wsmode != trackList[i].mode){ + trackList[i].__wsmode = trackList[i].mode; + callChange = true; + } + } + if(callChange){ + $([trackList]).triggerHandler('change'); + } }; var refreshTrack = function(track, trackData){ diff --git a/public/webshims/shims/combos/25.js b/public/webshims/shims/combos/25.js index 4ca46549..2c50c176 100644 --- a/public/webshims/shims/combos/25.js +++ b/public/webshims/shims/combos/25.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1611,22 +1616,19 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine qualitiy = 0.8; } loadMoxie(); - setTimeout(function(){ + webshim.ready('moxie', function(){ + var img = new mOxie.Image(); dataURL = $canvas.callProp('getAsDataURL', [type, qualitiy]); - webshim.ready('moxie', function(){ - var img = new mOxie.Image(); - - img.onload = function() { - var blob = img.getAsBlob(); - webshim.defineProperty(blob, '_wsDataURL', { - value: dataURL, - enumerable: false - }); - cb(blob); - }; - img.load(dataURL); - }); - }, 9); + img.onload = function() { + var blob = img.getAsBlob(); + webshim.defineProperty(blob, '_wsDataURL', { + value: dataURL, + enumerable: false + }); + cb(blob); + }; + img.load(dataURL); + }); } } }); @@ -2896,6 +2898,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine VIDEO: 1 }; var tested = {}; + var addToBlob = function(){ + var desc = webshim.defineNodeNameProperty('canvas', 'toBlob', { + prop: { + value: function(){ + var context = $(this).callProp('getContext', ['2d']); + var that = this; + var args = arguments; + var cb = function(){ + return desc.prop._supvalue.apply(that, args); + }; + if(context.wsImageComplete && context._wsIsLoading){ + context.wsImageComplete(cb); + } else { + return cb(); + } + } + } + }); + }; if(!_drawImage){ webshim.error('canvas.drawImage feature is needed. In IE8 flashvanvas pro can be used'); @@ -2970,6 +2991,12 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return _drawImage.apply(this, arguments); }; + + if(!document.createElement('canvas').toBlob){ + webshims.ready('filereader', addToBlob); + } else { + addToBlob(); + } return true; }; diff --git a/public/webshims/shims/combos/27.js b/public/webshims/shims/combos/27.js index 880c79cb..643ff70b 100644 --- a/public/webshims/shims/combos/27.js +++ b/public/webshims/shims/combos/27.js @@ -1632,22 +1632,19 @@ webshims.register('form-shim-extend2', function($, webshims, window, document, u qualitiy = 0.8; } loadMoxie(); - setTimeout(function(){ + webshim.ready('moxie', function(){ + var img = new mOxie.Image(); dataURL = $canvas.callProp('getAsDataURL', [type, qualitiy]); - webshim.ready('moxie', function(){ - var img = new mOxie.Image(); - - img.onload = function() { - var blob = img.getAsBlob(); - webshim.defineProperty(blob, '_wsDataURL', { - value: dataURL, - enumerable: false - }); - cb(blob); - }; - img.load(dataURL); - }); - }, 9); + img.onload = function() { + var blob = img.getAsBlob(); + webshim.defineProperty(blob, '_wsDataURL', { + value: dataURL, + enumerable: false + }); + cb(blob); + }; + img.load(dataURL); + }); } } }); diff --git a/public/webshims/shims/combos/28.js b/public/webshims/shims/combos/28.js index 8c626b0a..3c619726 100644 --- a/public/webshims/shims/combos/28.js +++ b/public/webshims/shims/combos/28.js @@ -607,22 +607,25 @@ if(webshims.support.inputtypes.date && /webkit/i.test(navigator.userAgent)){ webshims.addReady(function(context, contextElem){ //start constrain-validation - var focusElem; + $('form', context) .add(contextElem.filter('form')) .on('invalid', $.noop) ; - - try { - if(context == document && !('form' in (document.activeElement || {}))) { - focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; - if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) { - focusElem.focus(); + + setTimeout(function(){ + var focusElem; + try { + if(!('form' in (document.activeElement || {}))) { + focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; + if (focusElem && (focusElem.offsetHeight || focusElem.offsetWidth)) { + focusElem.focus(); + } } } - } - catch (er) {} - + catch (er) {} + }, 9); + }); if(!webshims.support.datalist){ diff --git a/public/webshims/shims/combos/3.js b/public/webshims/shims/combos/3.js index adfb33d3..dffab67c 100644 --- a/public/webshims/shims/combos/3.js +++ b/public/webshims/shims/combos/3.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1487,6 +1492,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; diff --git a/public/webshims/shims/combos/30.js b/public/webshims/shims/combos/30.js index eac80544..5c9cda5d 100644 --- a/public/webshims/shims/combos/30.js +++ b/public/webshims/shims/combos/30.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1487,6 +1492,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; diff --git a/public/webshims/shims/combos/31.js b/public/webshims/shims/combos/31.js index 63d04c5f..54eb2e30 100644 --- a/public/webshims/shims/combos/31.js +++ b/public/webshims/shims/combos/31.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1487,6 +1492,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; diff --git a/public/webshims/shims/combos/34.js b/public/webshims/shims/combos/34.js index 879cc92e..d8a11592 100644 --- a/public/webshims/shims/combos/34.js +++ b/public/webshims/shims/combos/34.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1343,10 +1348,11 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine var copyName = {srclang: 'language'}; var updateMediaTrackList = function(baseData, trackList){ + var i, len; + var callChange = false; var removed = []; var added = []; var newTracks = []; - var i, len; if(!baseData){ baseData = webshims.data(this, 'mediaelementBase') || webshims.data(this, 'mediaelementBase', {}); } @@ -1381,12 +1387,13 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine removed.push(trackList[i]); } } - + if(removed.length || added.length){ trackList.splice(0); for(i = 0, len = newTracks.length; i < len; i++){ trackList.push(newTracks[i]); + } for(i = 0, len = removed.length; i < len; i++){ $([trackList]).triggerHandler($.Event({type: 'removetrack', track: removed[i]})); @@ -1399,6 +1406,16 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine $(this).triggerHandler('updatetrackdisplay'); } } + + for(i = 0, len = trackList.length; i < len; i++){ + if(trackList[i].__wsmode != trackList[i].mode){ + trackList[i].__wsmode = trackList[i].mode; + callChange = true; + } + } + if(callChange){ + $([trackList]).triggerHandler('change'); + } }; var refreshTrack = function(track, trackData){ diff --git a/public/webshims/shims/combos/4.js b/public/webshims/shims/combos/4.js index a71f92e4..7d8c8ff0 100644 --- a/public/webshims/shims/combos/4.js +++ b/public/webshims/shims/combos/4.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; diff --git a/public/webshims/shims/combos/5.js b/public/webshims/shims/combos/5.js index 843cbd9e..6258221e 100644 --- a/public/webshims/shims/combos/5.js +++ b/public/webshims/shims/combos/5.js @@ -1871,9 +1871,13 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef }, time: function(val, o, noCorrect){ var fVal, i; + if(val){ val = val.split(':'); + if(val.length != 2 || isNaN(parseInt(val[0] || '', 10)) || isNaN(parseInt(val[1] || '', 10))){ + return val.join(':'); + } if(curCfg.meridian){ fVal = (val[0] * 1); if(fVal && fVal >= 12){ @@ -2028,6 +2032,7 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef createFormat('d'); var tmp, obj; var ret = ''; + if(opts.splitInput){ obj = {yy: 0, mm: 1, dd: 2}; } else { @@ -2049,8 +2054,7 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef } ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-'); } - return ret - ; + return ret; }, color: function(val, opts){ var ret = '#000000'; @@ -2352,9 +2356,11 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef }; ['defaultValue', 'value'].forEach(function(name){ + var formatName = 'format'+name; wsWidgetProto[name] = function(val, force){ - if(!this._init || force || val !== this.options[name]){ - this.element.prop(name, this.formatValue(val)); + if(!this._init || force || val !== this.options[name] || this.options[formatName] != this.element.prop(name)){ + this.options[formatName] = this.formatValue(val); + this.element.prop(name, this.options[formatName]); this.options[name] = val; this._propertyChange(name); this.mirrorValidity(); @@ -2478,36 +2484,34 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef var isValue = name == 'value'; spinBtnProto[name] = function(val, force, isLive){ var selectionEnd; - if(!this._init || force || this.options[name] !== val){ - if(isValue){ - this._beforeValue(val); - } else { - this.elemHelper.prop(name, val); - } - - val = formatVal[this.type](val, this.options); - if(this.options.splitInput){ - $.each(this.splits, function(i, elem){ - var setOption; - if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ - $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); - } else { - $.prop(elem, name, val[i]); - } - }); - } else { - val = this.toFixed(val); - if(isLive && this._getSelectionEnd){ - selectionEnd = this._getSelectionEnd(val); - } - this.element.prop(name, val); - if(selectionEnd != null){ - this.element.prop('selectionEnd', selectionEnd); - } - } - this._propertyChange(name); - this.mirrorValidity(); + if(isValue){ + this._beforeValue(val); + } else { + this.elemHelper.prop(name, val); } + + val = formatVal[this.type](val, this.options); + if(this.options.splitInput){ + $.each(this.splits, function(i, elem){ + var setOption; + if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ + $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); + } else { + $.prop(elem, name, val[i]); + } + }); + } else { + val = this.toFixed(val); + if(isLive && this._getSelectionEnd){ + selectionEnd = this._getSelectionEnd(val); + } + this.element.prop(name, val); + if(selectionEnd != null){ + this.element.prop('selectionEnd', selectionEnd); + } + } + this._propertyChange(name); + this.mirrorValidity(); }; }); diff --git a/public/webshims/shims/combos/6.js b/public/webshims/shims/combos/6.js index 03a4171c..5fbe93ec 100644 --- a/public/webshims/shims/combos/6.js +++ b/public/webshims/shims/combos/6.js @@ -1871,9 +1871,13 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef }, time: function(val, o, noCorrect){ var fVal, i; + if(val){ val = val.split(':'); + if(val.length != 2 || isNaN(parseInt(val[0] || '', 10)) || isNaN(parseInt(val[1] || '', 10))){ + return val.join(':'); + } if(curCfg.meridian){ fVal = (val[0] * 1); if(fVal && fVal >= 12){ @@ -2028,6 +2032,7 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef createFormat('d'); var tmp, obj; var ret = ''; + if(opts.splitInput){ obj = {yy: 0, mm: 1, dd: 2}; } else { @@ -2049,8 +2054,7 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef } ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-'); } - return ret - ; + return ret; }, color: function(val, opts){ var ret = '#000000'; @@ -2352,9 +2356,11 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef }; ['defaultValue', 'value'].forEach(function(name){ + var formatName = 'format'+name; wsWidgetProto[name] = function(val, force){ - if(!this._init || force || val !== this.options[name]){ - this.element.prop(name, this.formatValue(val)); + if(!this._init || force || val !== this.options[name] || this.options[formatName] != this.element.prop(name)){ + this.options[formatName] = this.formatValue(val); + this.element.prop(name, this.options[formatName]); this.options[name] = val; this._propertyChange(name); this.mirrorValidity(); @@ -2478,36 +2484,34 @@ webshims.register('form-native-extend', function($, webshims, window, doc, undef var isValue = name == 'value'; spinBtnProto[name] = function(val, force, isLive){ var selectionEnd; - if(!this._init || force || this.options[name] !== val){ - if(isValue){ - this._beforeValue(val); - } else { - this.elemHelper.prop(name, val); - } - - val = formatVal[this.type](val, this.options); - if(this.options.splitInput){ - $.each(this.splits, function(i, elem){ - var setOption; - if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ - $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); - } else { - $.prop(elem, name, val[i]); - } - }); - } else { - val = this.toFixed(val); - if(isLive && this._getSelectionEnd){ - selectionEnd = this._getSelectionEnd(val); - } - this.element.prop(name, val); - if(selectionEnd != null){ - this.element.prop('selectionEnd', selectionEnd); - } - } - this._propertyChange(name); - this.mirrorValidity(); + if(isValue){ + this._beforeValue(val); + } else { + this.elemHelper.prop(name, val); } + + val = formatVal[this.type](val, this.options); + if(this.options.splitInput){ + $.each(this.splits, function(i, elem){ + var setOption; + if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ + $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); + } else { + $.prop(elem, name, val[i]); + } + }); + } else { + val = this.toFixed(val); + if(isLive && this._getSelectionEnd){ + selectionEnd = this._getSelectionEnd(val); + } + this.element.prop(name, val); + if(selectionEnd != null){ + this.element.prop('selectionEnd', selectionEnd); + } + } + this._propertyChange(name); + this.mirrorValidity(); }; }); diff --git a/public/webshims/shims/combos/7.js b/public/webshims/shims/combos/7.js index e70a5838..8f05d1bf 100644 --- a/public/webshims/shims/combos/7.js +++ b/public/webshims/shims/combos/7.js @@ -325,20 +325,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -759,7 +764,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1710,6 +1715,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; diff --git a/public/webshims/shims/combos/8.js b/public/webshims/shims/combos/8.js index 2c5ee658..6a80bdbd 100644 --- a/public/webshims/shims/combos/8.js +++ b/public/webshims/shims/combos/8.js @@ -325,20 +325,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -759,7 +764,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -1710,6 +1715,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; diff --git a/public/webshims/shims/combos/9.js b/public/webshims/shims/combos/9.js index 5e544054..5b2e7006 100644 --- a/public/webshims/shims/combos/9.js +++ b/public/webshims/shims/combos/9.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; @@ -2275,9 +2280,13 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }, time: function(val, o, noCorrect){ var fVal, i; + if(val){ val = val.split(':'); + if(val.length != 2 || isNaN(parseInt(val[0] || '', 10)) || isNaN(parseInt(val[1] || '', 10))){ + return val.join(':'); + } if(curCfg.meridian){ fVal = (val[0] * 1); if(fVal && fVal >= 12){ @@ -2432,6 +2441,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine createFormat('d'); var tmp, obj; var ret = ''; + if(opts.splitInput){ obj = {yy: 0, mm: 1, dd: 2}; } else { @@ -2453,8 +2463,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine } ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-'); } - return ret - ; + return ret; }, color: function(val, opts){ var ret = '#000000'; @@ -2756,9 +2765,11 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; ['defaultValue', 'value'].forEach(function(name){ + var formatName = 'format'+name; wsWidgetProto[name] = function(val, force){ - if(!this._init || force || val !== this.options[name]){ - this.element.prop(name, this.formatValue(val)); + if(!this._init || force || val !== this.options[name] || this.options[formatName] != this.element.prop(name)){ + this.options[formatName] = this.formatValue(val); + this.element.prop(name, this.options[formatName]); this.options[name] = val; this._propertyChange(name); this.mirrorValidity(); @@ -2882,36 +2893,34 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine var isValue = name == 'value'; spinBtnProto[name] = function(val, force, isLive){ var selectionEnd; - if(!this._init || force || this.options[name] !== val){ - if(isValue){ - this._beforeValue(val); - } else { - this.elemHelper.prop(name, val); - } - - val = formatVal[this.type](val, this.options); - if(this.options.splitInput){ - $.each(this.splits, function(i, elem){ - var setOption; - if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ - $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); - } else { - $.prop(elem, name, val[i]); - } - }); - } else { - val = this.toFixed(val); - if(isLive && this._getSelectionEnd){ - selectionEnd = this._getSelectionEnd(val); - } - this.element.prop(name, val); - if(selectionEnd != null){ - this.element.prop('selectionEnd', selectionEnd); - } - } - this._propertyChange(name); - this.mirrorValidity(); + if(isValue){ + this._beforeValue(val); + } else { + this.elemHelper.prop(name, val); } + + val = formatVal[this.type](val, this.options); + if(this.options.splitInput){ + $.each(this.splits, function(i, elem){ + var setOption; + if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ + $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); + } else { + $.prop(elem, name, val[i]); + } + }); + } else { + val = this.toFixed(val); + if(isLive && this._getSelectionEnd){ + selectionEnd = this._getSelectionEnd(val); + } + this.element.prop(name, val); + if(selectionEnd != null){ + this.element.prop('selectionEnd', selectionEnd); + } + } + this._propertyChange(name); + this.mirrorValidity(); }; }); diff --git a/public/webshims/shims/dom-extend.js b/public/webshims/shims/dom-extend.js index bb800076..6b120aec 100644 --- a/public/webshims/shims/dom-extend.js +++ b/public/webshims/shims/dom-extend.js @@ -102,20 +102,25 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine }; //jquery mobile and jquery ui - if(!$.widget){ + if(!$.widget && (!$.pluginFactory || !$.pluginFactory.mixin)){ (function(){ var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - if(!$.widget){ - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = (function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; (elem = elems[i]) != null; i++ ) { try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + // http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} } - } - _cleanData( elems ); - }; + orig( elems ); + }; + })( $.cleanData ); })(); } @@ -536,7 +541,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine return id; }; })(), - domPrefixes: ["ws", "webkit", "moz", "ms", "o"], + domPrefixes: ["webkit", "moz", "ms", "o", "ws"], prefixed: function (prop, obj){ var i, testProp; diff --git a/public/webshims/shims/es5.js b/public/webshims/shims/es5.js index 4d51acf4..31228a70 100644 --- a/public/webshims/shims/es5.js +++ b/public/webshims/shims/es5.js @@ -16,40 +16,147 @@ setTimeout(function(){ // Shortcut to an often accessed properties, in order to avoid multiple // dereference that costs universally. - var call = Function.prototype.call; - var prototypeOfArray = Array.prototype; - var prototypeOfObject = Object.prototype; - var _Array_slice_ = prototypeOfArray.slice; - var array_splice = Array.prototype.splice; - var array_push = Array.prototype.push; - var array_unshift = Array.prototype.unshift; + var ArrayPrototype = Array.prototype; + var ObjectPrototype = Object.prototype; + var FunctionPrototype = Function.prototype; + var StringPrototype = String.prototype; + var NumberPrototype = Number.prototype; + var array_slice = ArrayPrototype.slice; + var array_splice = ArrayPrototype.splice; + var array_push = ArrayPrototype.push; + var array_unshift = ArrayPrototype.unshift; + var call = FunctionPrototype.call; // Having a toString local variable name breaks in Opera so use _toString. - var _toString = prototypeOfObject.toString; + var _toString = ObjectPrototype.toString; var isFunction = function (val) { - return prototypeOfObject.toString.call(val) === '[object Function]'; + return ObjectPrototype.toString.call(val) === '[object Function]'; }; var isRegex = function (val) { - return prototypeOfObject.toString.call(val) === '[object RegExp]'; + return ObjectPrototype.toString.call(val) === '[object RegExp]'; }; var isArray = function isArray(obj) { return _toString.call(obj) === "[object Array]"; }; + var isString = function isString(obj) { + return _toString.call(obj) === "[object String]"; + }; var isArguments = function isArguments(value) { var str = _toString.call(value); var isArgs = str === '[object Arguments]'; if (!isArgs) { - isArgs = !isArray(str) - && value !== null - && typeof value === 'object' - && typeof value.length === 'number' - && value.length >= 0 - && isFunction(value.callee); + isArgs = !isArray(value) + && value !== null + && typeof value === 'object' + && typeof value.length === 'number' + && value.length >= 0 + && isFunction(value.callee); } return isArgs; }; + var supportsDescriptors = Object.defineProperty && (function () { + try { + Object.defineProperty({}, 'x', {}); + return true; + } catch (e) { /* this is ES3 */ + return false; + } + }()); + +// Define configurable, writable and non-enumerable props +// if they don't exist. + var defineProperty; + if (supportsDescriptors) { + defineProperty = function (object, name, method, forceAssign) { + if (!forceAssign && (name in object)) { return; } + Object.defineProperty(object, name, { + configurable: true, + enumerable: false, + writable: true, + value: method + }); + }; + } else { + defineProperty = function (object, name, method, forceAssign) { + if (!forceAssign && (name in object)) { return; } + object[name] = method; + }; + } + var defineProperties = function (object, map, forceAssign) { + for (var name in map) { + if (ObjectPrototype.hasOwnProperty.call(map, name)) { + defineProperty(object, name, map[name], forceAssign); + } + } + }; + +// +// Util +// ====== +// + +// ES5 9.4 +// http://es5.github.com/#x9.4 +// http://jsperf.com/to-integer + + function toInteger(n) { + n = +n; + if (n !== n) { // isNaN + n = 0; + } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + return n; + } + + function isPrimitive(input) { + var type = typeof input; + return ( + input === null || + type === "undefined" || + type === "boolean" || + type === "number" || + type === "string" + ); + } + + function toPrimitive(input) { + var val, valueOf, toStr; + if (isPrimitive(input)) { + return input; + } + valueOf = input.valueOf; + if (isFunction(valueOf)) { + val = valueOf.call(input); + if (isPrimitive(val)) { + return val; + } + } + toStr = input.toString; + if (isFunction(toStr)) { + val = toStr.call(input); + if (isPrimitive(val)) { + return val; + } + } + throw new TypeError(); + } + +// ES5 9.9 +// http://es5.github.com/#x9.9 + var toObject = function (o) { + if (o == null) { // this matches both null and undefined + throw new TypeError("can't convert " + o + " to object"); + } + return Object(o); + }; + + var ToUint32 = function ToUint32(x) { + return x >>> 0; + }; + // // Function // ======== @@ -60,8 +167,8 @@ setTimeout(function(){ function Empty() {} - if (!Function.prototype.bind) { - Function.prototype.bind = function bind(that) { // .length is 1 + defineProperties(FunctionPrototype, { + bind: function bind(that) { // .length is 1 // 1. Let Target be the this value. var target = this; // 2. If IsCallable(Target) is false, throw a TypeError exception. @@ -69,18 +176,18 @@ setTimeout(function(){ throw new TypeError("Function.prototype.bind called on incompatible " + target); } // 3. Let A be a new (possibly empty) internal list of all of the - // argument values provided after thisArg (arg1, arg2 etc), in order. + // argument values provided after thisArg (arg1, arg2 etc), in order. // XXX slicedArgs will stand in for "A" if used - var args = _Array_slice_.call(arguments, 1); // for normal call + var args = array_slice.call(arguments, 1); // for normal call // 4. Let F be a new native ECMAScript object. // 11. Set the [[Prototype]] internal property of F to the standard - // built-in Function prototype object as specified in 15.3.3.1. + // built-in Function prototype object as specified in 15.3.3.1. // 12. Set the [[Call]] internal property of F as described in - // 15.3.4.5.1. + // 15.3.4.5.1. // 13. Set the [[Construct]] internal property of F as described in - // 15.3.4.5.2. + // 15.3.4.5.2. // 14. Set the [[HasInstance]] internal property of F as described in - // 15.3.4.5.3. + // 15.3.4.5.3. var binder = function () { if (this instanceof bound) { @@ -89,20 +196,20 @@ setTimeout(function(){ // F that was created using the bind function is called with a // list of arguments ExtraArgs, the following steps are taken: // 1. Let target be the value of F's [[TargetFunction]] - // internal property. + // internal property. // 2. If target has no [[Construct]] internal method, a - // TypeError exception is thrown. + // TypeError exception is thrown. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal - // property. + // property. // 4. Let args be a new list containing the same values as the - // list boundArgs in the same order followed by the same - // values as the list ExtraArgs in the same order. + // list boundArgs in the same order followed by the same + // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Construct]] internal - // method of target providing args as the arguments. + // method of target providing args as the arguments. var result = target.apply( this, - args.concat(_Array_slice_.call(arguments)) + args.concat(array_slice.call(arguments)) ); if (Object(result) === result) { return result; @@ -116,22 +223,22 @@ setTimeout(function(){ // this value and a list of arguments ExtraArgs, the following // steps are taken: // 1. Let boundArgs be the value of F's [[BoundArgs]] internal - // property. + // property. // 2. Let boundThis be the value of F's [[BoundThis]] internal - // property. + // property. // 3. Let target be the value of F's [[TargetFunction]] internal - // property. + // property. // 4. Let args be a new list containing the same values as the - // list boundArgs in the same order followed by the same - // values as the list ExtraArgs in the same order. + // list boundArgs in the same order followed by the same + // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Call]] internal method - // of target providing boundThis as the this value and - // providing args as the arguments. + // of target providing boundThis as the this value and + // providing args as the arguments. // equiv: target.call(this, ...boundArgs, ...args) return target.apply( that, - args.concat(_Array_slice_.call(arguments)) + args.concat(array_slice.call(arguments)) ); } @@ -139,15 +246,15 @@ setTimeout(function(){ }; // 15. If the [[Class]] internal property of Target is "Function", then - // a. Let L be the length property of Target minus the length of A. - // b. Set the length own property of F to either 0 or L, whichever is - // larger. + // a. Let L be the length property of Target minus the length of A. + // b. Set the length own property of F to either 0 or L, whichever is + // larger. // 16. Else set the length own property of F to 0. var boundLength = Math.max(0, target.length - args.length); // 17. Set the attributes of the length own property of F to the values - // specified in 15.3.5.1. + // specified in 15.3.5.1. var boundArgs = []; for (var i = 0; i < boundLength; i++) { boundArgs.push("$" + i); @@ -174,13 +281,13 @@ setTimeout(function(){ // TODO // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). // 20. Call the [[DefineOwnProperty]] internal method of F with - // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: - // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and - // false. + // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: + // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and + // false. // 21. Call the [[DefineOwnProperty]] internal method of F with - // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, - // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, - // and false. + // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, + // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, + // and false. // TODO // NOTE Function objects created using Function.prototype.bind do not @@ -190,12 +297,12 @@ setTimeout(function(){ // 22. Return F. return bound; - }; - } + } + }); // _Please note: Shortcuts are defined after `Function.prototype.bind` as we // us it in defining shortcuts. - var owns = call.bind(prototypeOfObject.hasOwnProperty); + var owns = call.bind(ObjectPrototype.hasOwnProperty); // If JS engine supports accessors creating shortcuts. var defineGetter; @@ -203,11 +310,11 @@ setTimeout(function(){ var lookupGetter; var lookupSetter; var supportsAccessors; - if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { - defineGetter = call.bind(prototypeOfObject.__defineGetter__); - defineSetter = call.bind(prototypeOfObject.__defineSetter__); - lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); - lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); + if ((supportsAccessors = owns(ObjectPrototype, "__defineGetter__"))) { + defineGetter = call.bind(ObjectPrototype.__defineGetter__); + defineSetter = call.bind(ObjectPrototype.__defineSetter__); + lookupGetter = call.bind(ObjectPrototype.__lookupGetter__); + lookupSetter = call.bind(ObjectPrototype.__lookupSetter__); } // @@ -217,63 +324,68 @@ setTimeout(function(){ // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.12 - var spliceWorksWithEmptyObject = (function () { - var obj = {}; - Array.prototype.splice.call(obj, 0, 0, 1); - return obj.length === 1; - }()); - var omittingSecondSpliceArgIsNoop = [1].splice(0).length === 0; var spliceNoopReturnsEmptyArray = (function () { var a = [1, 2]; var result = a.splice(); return a.length === 2 && isArray(result) && result.length === 0; }()); - if (spliceNoopReturnsEmptyArray) { - // Safari 5.0 bug where .split() returns undefined - Array.prototype.splice = function splice(start, deleteCount) { - if (arguments.length === 0) { return []; } - else { return array_splice.apply(this, arguments); } - }; - } - if (!omittingSecondSpliceArgIsNoop || !spliceWorksWithEmptyObject) { - Array.prototype.splice = function splice(start, deleteCount) { + defineProperties(ArrayPrototype, { + // Safari 5.0 bug where .splice() returns undefined + splice: function splice(start, deleteCount) { + if (arguments.length === 0) { + return []; + } else { + return array_splice.apply(this, arguments); + } + } + }, spliceNoopReturnsEmptyArray); + + var spliceWorksWithEmptyObject = (function () { + var obj = {}; + ArrayPrototype.splice.call(obj, 0, 0, 1); + return obj.length === 1; + }()); + defineProperties(ArrayPrototype, { + splice: function splice(start, deleteCount) { if (arguments.length === 0) { return []; } var args = arguments; this.length = Math.max(toInteger(this.length), 0); if (arguments.length > 0 && typeof deleteCount !== 'number') { - args = _Array_slice_.call(arguments); - if (args.length < 2) { args.push(toInteger(deleteCount)); } - else { args[1] = toInteger(deleteCount); } + args = array_slice.call(arguments); + if (args.length < 2) { + args.push(this.length - start); + } else { + args[1] = toInteger(deleteCount); + } } return array_splice.apply(this, args); - }; - } + } + }, !spliceWorksWithEmptyObject); // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.13 // Return len+argCount. // [bugfix, ielt8] // IE < 8 bug: [].unshift(0) === undefined but should be "1" - if ([].unshift(0) !== 1) { - Array.prototype.unshift = function () { + var hasUnshiftReturnValueBug = [].unshift(0) !== 1; + defineProperties(ArrayPrototype, { + unshift: function () { array_unshift.apply(this, arguments); return this.length; - }; - } + } + }, hasUnshiftReturnValueBug); // ES5 15.4.3.2 // http://es5.github.com/#x15.4.3.2 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray - if (!Array.isArray) { - Array.isArray = isArray; - } + defineProperties(Array, { isArray: isArray }); // The IsCallable() check in the Array functions // has been replaced with a strict check on the // internal class of the object to trap cases where // the provided function was actually a regular // expression literal, which in V8 and -// JavaScriptCore is a typeof "function". Only in +// JavaScriptCore is a typeof "function". Only in // V8 are regular expression literals permitted as // reduce parameters, so it is desirable in the // general case for the shim to match the more @@ -306,12 +418,10 @@ setTimeout(function(){ return !!method && properlyBoxesNonStrict && properlyBoxesStrict; }; - if (!Array.prototype.forEach || !properlyBoxesContext(Array.prototype.forEach)) { - Array.prototype.forEach = function forEach(fun /*, thisp*/) { + defineProperties(ArrayPrototype, { + forEach: function forEach(fun /*, thisp*/) { var object = toObject(this), - self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - object, + self = splitString && isString(this) ? this.split('') : object, thisp = arguments[1], i = -1, length = self.length >>> 0; @@ -329,18 +439,16 @@ setTimeout(function(){ fun.call(thisp, self[i], i, object); } } - }; - } + } + }, !properlyBoxesContext(ArrayPrototype.forEach)); // ES5 15.4.4.19 // http://es5.github.com/#x15.4.4.19 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map - if (!Array.prototype.map || !properlyBoxesContext(Array.prototype.map)) { - Array.prototype.map = function map(fun /*, thisp*/) { + defineProperties(ArrayPrototype, { + map: function map(fun /*, thisp*/) { var object = toObject(this), - self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - object, + self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, result = Array(length), thisp = arguments[1]; @@ -356,18 +464,16 @@ setTimeout(function(){ } } return result; - }; - } + } + }, !properlyBoxesContext(ArrayPrototype.map)); // ES5 15.4.4.20 // http://es5.github.com/#x15.4.4.20 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter - if (!Array.prototype.filter || !properlyBoxesContext(Array.prototype.filter)) { - Array.prototype.filter = function filter(fun /*, thisp */) { + defineProperties(ArrayPrototype, { + filter: function filter(fun /*, thisp */) { var object = toObject(this), - self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - object, + self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, result = [], value, @@ -387,18 +493,16 @@ setTimeout(function(){ } } return result; - }; - } + } + }, !properlyBoxesContext(ArrayPrototype.filter)); // ES5 15.4.4.16 // http://es5.github.com/#x15.4.4.16 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every - if (!Array.prototype.every || !properlyBoxesContext(Array.prototype.every)) { - Array.prototype.every = function every(fun /*, thisp */) { + defineProperties(ArrayPrototype, { + every: function every(fun /*, thisp */) { var object = toObject(this), - self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - object, + self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, thisp = arguments[1]; @@ -413,18 +517,16 @@ setTimeout(function(){ } } return true; - }; - } + } + }, !properlyBoxesContext(ArrayPrototype.every)); // ES5 15.4.4.17 // http://es5.github.com/#x15.4.4.17 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some - if (!Array.prototype.some || !properlyBoxesContext(Array.prototype.some)) { - Array.prototype.some = function some(fun /*, thisp */) { + defineProperties(ArrayPrototype, { + some: function some(fun /*, thisp */) { var object = toObject(this), - self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - object, + self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, thisp = arguments[1]; @@ -439,22 +541,20 @@ setTimeout(function(){ } } return false; - }; - } + } + }, !properlyBoxesContext(ArrayPrototype.some)); // ES5 15.4.4.21 // http://es5.github.com/#x15.4.4.21 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce var reduceCoercesToObject = false; - if (Array.prototype.reduce) { - reduceCoercesToObject = typeof Array.prototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object'; + if (ArrayPrototype.reduce) { + reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } - if (!Array.prototype.reduce || !reduceCoercesToObject) { - Array.prototype.reduce = function reduce(fun /*, initial*/) { + defineProperties(ArrayPrototype, { + reduce: function reduce(fun /*, initial*/) { var object = toObject(this), - self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - object, + self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0; // If no callback function or if callback is not a callable function @@ -492,22 +592,20 @@ setTimeout(function(){ } return result; - }; - } + } + }, !reduceCoercesToObject); // ES5 15.4.4.22 // http://es5.github.com/#x15.4.4.22 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight var reduceRightCoercesToObject = false; - if (Array.prototype.reduceRight) { - reduceRightCoercesToObject = typeof Array.prototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object'; + if (ArrayPrototype.reduceRight) { + reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } - if (!Array.prototype.reduceRight || !reduceRightCoercesToObject) { - Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { + defineProperties(ArrayPrototype, { + reduceRight: function reduceRight(fun /*, initial*/) { var object = toObject(this), - self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - object, + self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0; // If no callback function or if callback is not a callable function @@ -548,17 +646,16 @@ setTimeout(function(){ } while (i--); return result; - }; - } + } + }, !reduceRightCoercesToObject); // ES5 15.4.4.14 // http://es5.github.com/#x15.4.4.14 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf - if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) !== -1)) { - Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { - var self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - toObject(this), + var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1; + defineProperties(ArrayPrototype, { + indexOf: function indexOf(sought /*, fromIndex */ ) { + var self = splitString && isString(this) ? this.split('') : toObject(this), length = self.length >>> 0; if (!length) { @@ -578,17 +675,16 @@ setTimeout(function(){ } } return -1; - }; - } + } + }, hasFirefox2IndexOfBug); // ES5 15.4.4.15 // http://es5.github.com/#x15.4.4.15 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf - if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) !== -1)) { - Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { - var self = splitString && _toString.call(this) === "[object String]" ? - this.split("") : - toObject(this), + var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1; + defineProperties(ArrayPrototype, { + lastIndexOf: function lastIndexOf(sought /*, fromIndex */) { + var self = splitString && isString(this) ? this.split('') : toObject(this), length = self.length >>> 0; if (!length) { @@ -606,8 +702,8 @@ setTimeout(function(){ } } return -1; - }; - } + } + }, hasFirefox2LastIndexOfBug); // // Object @@ -616,29 +712,27 @@ setTimeout(function(){ // ES5 15.2.3.14 // http://es5.github.com/#x15.2.3.14 - var keysWorksWithArguments = Object.keys && (function () { - return Object.keys(arguments).length === 2; - }(1, 2)); - if (!Object.keys) { - // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation - var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), - hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), - dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" - ], - dontEnumsLength = dontEnums.length; - Object.keys = function keys(object) { +// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), + hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ], + dontEnumsLength = dontEnums.length; + + defineProperties(Object, { + keys: function keys(object) { var isFn = isFunction(object), isArgs = isArguments(object), isObject = object !== null && typeof object === 'object', - isString = isObject && _toString.call(object) === '[object String]'; + isStr = isObject && isString(object); if (!isObject && !isFn && !isArgs) { throw new TypeError("Object.keys called on a non-object"); @@ -646,7 +740,7 @@ setTimeout(function(){ var theKeys = []; var skipProto = hasProtoEnumBug && isFn; - if (isString || isArgs) { + if (isStr || isArgs) { for (var i = 0; i < object.length; ++i) { theKeys.push(String(i)); } @@ -669,18 +763,23 @@ setTimeout(function(){ } } return theKeys; - }; - } else if (!keysWorksWithArguments) { - // Safari 5.0 bug - var originalKeys = Object.keys; - Object.keys = function keys(object) { + } + }); + + var keysWorksWithArguments = Object.keys && (function () { + // Safari 5.0 bug + return Object.keys(arguments).length === 2; + }(1, 2)); + var originalKeys = Object.keys; + defineProperties(Object, { + keys: function keys(object) { if (isArguments(object)) { - return originalKeys(Array.prototype.slice.call(object)); + return originalKeys(ArrayPrototype.slice.call(object)); } else { return originalKeys(object); } - }; - } + } + }, !keysWorksWithArguments); // // Date @@ -694,13 +793,12 @@ setTimeout(function(){ // string format defined in 15.9.1.15. All fields are present in the String. // The time zone is always UTC, denoted by the suffix Z. If the time value of // this object is not a finite Number a RangeError exception is thrown. - var negativeDate = -62198755200000, - negativeYearString = "-000001"; - if ( - !Date.prototype.toISOString || - (new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1) - ) { - Date.prototype.toISOString = function toISOString() { + var negativeDate = -62198755200000; + var negativeYearString = "-000001"; + var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; + + defineProperties(Date.prototype, { + toISOString: function toISOString() { var result, length, value, year, month; if (!isFinite(this)) { throw new RangeError("Date.prototype.toISOString called on non-finite value."); @@ -716,9 +814,9 @@ setTimeout(function(){ // the date time string format is specified in 15.9.1.15. result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; year = ( - (year < 0 ? "-" : (year > 9999 ? "+" : "")) + - ("00000" + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6) - ); + (year < 0 ? "-" : (year > 9999 ? "+" : "")) + + ("00000" + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6) + ); length = result.length; while (length--) { @@ -731,12 +829,12 @@ setTimeout(function(){ } // pad milliseconds to have three digits. return ( - year + "-" + result.slice(0, 2).join("-") + - "T" + result.slice(2).join(":") + "." + - ("000" + this.getUTCMilliseconds()).slice(-3) + "Z" - ); - }; - } + year + "-" + result.slice(0, 2).join("-") + + "T" + result.slice(2).join(":") + "." + + ("000" + this.getUTCMilliseconds()).slice(-3) + "Z" + ); + } + }, hasNegativeDateBug); // ES5 15.9.5.44 @@ -746,15 +844,15 @@ setTimeout(function(){ var dateToJSONIsSupported = false; try { dateToJSONIsSupported = ( - Date.prototype.toJSON && - new Date(NaN).toJSON() === null && - new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && - Date.prototype.toJSON.call({ // generic - toISOString: function () { - return true; - } - }) - ); + Date.prototype.toJSON && + new Date(NaN).toJSON() === null && + new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && + Date.prototype.toJSON.call({ // generic + toISOString: function () { + return true; + } + }) + ); } catch (e) { } if (!dateToJSONIsSupported) { @@ -762,7 +860,7 @@ setTimeout(function(){ // When the toJSON method is called with argument key, the following // steps are taken: - // 1. Let O be the result of calling ToObject, giving it the this + // 1. Let O be the result of calling ToObject, giving it the this // value as its argument. // 2. Let tv be toPrimitive(O, hint Number). var o = Object(this), @@ -780,7 +878,7 @@ setTimeout(function(){ throw new TypeError("toISOString property is not callable"); } // 6. Return the result of calling the [[Call]] internal method of - // toISO with O as the this value and an empty argument list. + // toISO with O as the this value and an empty argument list. return toISO.call(o); // NOTE 1 The argument is ignored. @@ -832,26 +930,26 @@ setTimeout(function(){ // 15.9.1.15 Date Time String Format. var isoDateExpression = new RegExp("^" + - "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + - // 6-digit extended year - "(?:-(\\d{2})" + // optional month capture - "(?:-(\\d{2})" + // optional day capture - "(?:" + // capture hours:minutes:seconds.milliseconds - "T(\\d{2})" + // hours capture - ":(\\d{2})" + // minutes capture - "(?:" + // optional :seconds.milliseconds - ":(\\d{2})" + // seconds capture - "(?:(\\.\\d{1,}))?" + // milliseconds capture - ")?" + - "(" + // capture UTC offset component - "Z|" + // UTC capture - "(?:" + // offset specifier +/-hours:minutes - "([-+])" + // sign capture - "(\\d{2})" + // hours offset capture - ":(\\d{2})" + // minutes offset capture - ")" + - ")?)?)?)?" + - "$"); + "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + + // 6-digit extended year + "(?:-(\\d{2})" + // optional month capture + "(?:-(\\d{2})" + // optional day capture + "(?:" + // capture hours:minutes:seconds.milliseconds + "T(\\d{2})" + // hours capture + ":(\\d{2})" + // minutes capture + "(?:" + // optional :seconds.milliseconds + ":(\\d{2})" + // seconds capture + "(?:(\\.\\d{1,}))?" + // milliseconds capture + ")?" + + "(" + // capture UTC offset component + "Z|" + // UTC capture + "(?:" + // offset specifier +/-hours:minutes + "([-+])" + // sign capture + "(\\d{2})" + // hours offset capture + ":(\\d{2})" + // minutes offset capture + ")" + + ")?)?)?)?" + + "$"); var months = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 @@ -860,12 +958,12 @@ setTimeout(function(){ function dayFromMonth(year, month) { var t = month > 1 ? 1 : 0; return ( - months[month] + - Math.floor((year - 1969 + t) / 4) - - Math.floor((year - 1901 + t) / 100) + - Math.floor((year - 1601 + t) / 400) + - 365 * (year - 1970) - ); + months[month] + + Math.floor((year - 1969 + t) / 4) - + Math.floor((year - 1901 + t) / 100) + + Math.floor((year - 1601 + t) / 400) + + 365 * (year - 1970) + ); } function toUTC(t) { @@ -909,25 +1007,25 @@ setTimeout(function(){ hour < ( minute > 0 || second > 0 || millisecond > 0 ? 24 : 25 - ) && - minute < 60 && second < 60 && millisecond < 1000 && - month > -1 && month < 12 && hourOffset < 24 && - minuteOffset < 60 && // detect invalid offsets - day > -1 && - day < ( - dayFromMonth(year, month + 1) - - dayFromMonth(year, month) - ) - ) { + ) && + minute < 60 && second < 60 && millisecond < 1000 && + month > -1 && month < 12 && hourOffset < 24 && + minuteOffset < 60 && // detect invalid offsets + day > -1 && + day < ( + dayFromMonth(year, month + 1) - + dayFromMonth(year, month) + ) + ) { result = ( - (dayFromMonth(year, month) + day) * 24 + - hour + - hourOffset * signOffset - ) * 60; + (dayFromMonth(year, month) + day) * 24 + + hour + + hourOffset * signOffset + ) * 60; result = ( - (result + minute + minuteOffset * signOffset) * 60 + - second - ) * 1000 + millisecond; + (result + minute + minuteOffset * signOffset) * 60 + + second + ) * 1000 + millisecond; if (isLocalTime) { result = toUTC(result); } @@ -960,152 +1058,151 @@ setTimeout(function(){ // ES5.1 15.7.4.5 // http://es5.github.com/#x15.7.4.5 - if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") { - // Hide these variables and functions - (function () { - var base, size, data, i; + var hasToFixedBugs = NumberPrototype.toFixed && ( + (0.00008).toFixed(3) !== '0.000' + || (0.9).toFixed(0) !== '1' + || (1.255).toFixed(2) !== '1.25' + || (1000000000000000128).toFixed(0) !== "1000000000000000128" + ); - base = 1e7; - size = 6; - data = [0, 0, 0, 0, 0, 0]; - - function multiply(n, c) { - var i = -1; - while (++i < size) { - c += n * data[i]; - data[i] = c % base; - c = Math.floor(c / base); - } + var toFixedHelpers = { + base: 1e7, + size: 6, + data: [0, 0, 0, 0, 0, 0], + multiply: function multiply(n, c) { + var i = -1; + while (++i < toFixedHelpers.size) { + c += n * toFixedHelpers.data[i]; + toFixedHelpers.data[i] = c % toFixedHelpers.base; + c = Math.floor(c / toFixedHelpers.base); } - - function divide(n) { - var i = size, c = 0; - while (--i >= 0) { - c += data[i]; - data[i] = Math.floor(c / n); - c = (c % n) * base; - } + }, + divide: function divide(n) { + var i = toFixedHelpers.size, c = 0; + while (--i >= 0) { + c += toFixedHelpers.data[i]; + toFixedHelpers.data[i] = Math.floor(c / n); + c = (c % n) * toFixedHelpers.base; } - - function numToString() { - var i = size; - var s = ''; - while (--i >= 0) { - if (s !== '' || i === 0 || data[i] !== 0) { - var t = String(data[i]); - if (s === '') { - s = t; - } else { - s += '0000000'.slice(0, 7 - t.length) + t; - } - } - } - return s; - } - - function pow(x, n, acc) { - return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); - } - - function log(x) { - var n = 0; - while (x >= 4096) { - n += 12; - x /= 4096; - } - while (x >= 2) { - n += 1; - x /= 2; - } - return n; - } - - Number.prototype.toFixed = function toFixed(fractionDigits) { - var f, x, s, m, e, z, j, k; - - // Test for NaN and round fractionDigits down - f = Number(fractionDigits); - f = f !== f ? 0 : Math.floor(f); - - if (f < 0 || f > 20) { - throw new RangeError("Number.toFixed called with invalid number of decimals"); - } - - x = Number(this); - - // Test for NaN - if (x !== x) { - return "NaN"; - } - - // If it is too big or small, return the string value of the number - if (x <= -1e21 || x >= 1e21) { - return String(x); - } - - s = ""; - - if (x < 0) { - s = "-"; - x = -x; - } - - m = "0"; - - if (x > 1e-21) { - // 1e-21 < x < 1e21 - // -70 < log2(x) < 70 - e = log(x * pow(2, 69, 1)) - 69; - z = (e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1)); - z *= 0x10000000000000; // Math.pow(2, 52); - e = 52 - e; - - // -18 < e < 122 - // x = z / 2 ^ e - if (e > 0) { - multiply(0, z); - j = f; - - while (j >= 7) { - multiply(1e7, 0); - j -= 7; - } - - multiply(pow(10, j, 1), 0); - j = e - 1; - - while (j >= 23) { - divide(1 << 23); - j -= 23; - } - - divide(1 << j); - multiply(1, 1); - divide(2); - m = numToString(); + }, + numToString: function numToString() { + var i = toFixedHelpers.size; + var s = ''; + while (--i >= 0) { + if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) { + var t = String(toFixedHelpers.data[i]); + if (s === '') { + s = t; } else { - multiply(0, z); - multiply(1 << (-e), 0); - m = numToString() + '0.00000000000000000000'.slice(2, 2 + f); + s += '0000000'.slice(0, 7 - t.length) + t; } } + } + return s; + }, + pow: function pow(x, n, acc) { + return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); + }, + log: function log(x) { + var n = 0; + while (x >= 4096) { + n += 12; + x /= 4096; + } + while (x >= 2) { + n += 1; + x /= 2; + } + return n; + } + }; - if (f > 0) { - k = m.length; + defineProperties(NumberPrototype, { + toFixed: function toFixed(fractionDigits) { + var f, x, s, m, e, z, j, k; - if (k <= f) { - m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m; - } else { - m = s + m.slice(0, k - f) + '.' + m.slice(k - f); + // Test for NaN and round fractionDigits down + f = Number(fractionDigits); + f = f !== f ? 0 : Math.floor(f); + + if (f < 0 || f > 20) { + throw new RangeError("Number.toFixed called with invalid number of decimals"); + } + + x = Number(this); + + // Test for NaN + if (x !== x) { + return "NaN"; + } + + // If it is too big or small, return the string value of the number + if (x <= -1e21 || x >= 1e21) { + return String(x); + } + + s = ""; + + if (x < 0) { + s = "-"; + x = -x; + } + + m = "0"; + + if (x > 1e-21) { + // 1e-21 < x < 1e21 + // -70 < log2(x) < 70 + e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69; + z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1)); + z *= 0x10000000000000; // Math.pow(2, 52); + e = 52 - e; + + // -18 < e < 122 + // x = z / 2 ^ e + if (e > 0) { + toFixedHelpers.multiply(0, z); + j = f; + + while (j >= 7) { + toFixedHelpers.multiply(1e7, 0); + j -= 7; } + + toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0); + j = e - 1; + + while (j >= 23) { + toFixedHelpers.divide(1 << 23); + j -= 23; + } + + toFixedHelpers.divide(1 << j); + toFixedHelpers.multiply(1, 1); + toFixedHelpers.divide(2); + m = toFixedHelpers.numToString(); } else { - m = s + m; + toFixedHelpers.multiply(0, z); + toFixedHelpers.multiply(1 << (-e), 0); + m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f); } + } - return m; - }; - }()); - } + if (f > 0) { + k = m.length; + + if (k <= f) { + m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m; + } else { + m = s + m.slice(0, k - f) + '.' + m.slice(k - f); + } + } else { + m = s + m; + } + + return m; + } + }, hasToFixedBugs); // @@ -1121,26 +1218,26 @@ setTimeout(function(){ // do not perform the split correctly under obscure conditions. // See http://blog.stevenlevithan.com/archives/cross-browser-split // I've tested in many browsers and this seems to cover the deviant ones: -// 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] -// '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] -// 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not -// [undefined, "t", undefined, "e", ...] -// ''.split(/.?/) should be [], not [""] -// '.'.split(/()()/) should be ["."], not ["", "", "."] +// 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] +// '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] +// 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not +// [undefined, "t", undefined, "e", ...] +// ''.split(/.?/) should be [], not [""] +// '.'.split(/()()/) should be ["."], not ["", "", "."] - var string_split = String.prototype.split; + var string_split = StringPrototype.split; if ( 'ab'.split(/(?:ab)*/).length !== 2 || - '.'.split(/(.?)(.?)/).length !== 4 || - 'tesst'.split(/(s)*/)[1] === "t" || - 'test'.split(/(?:)/, -1).length !== 4 || - ''.split(/.?/).length || - '.'.split(/()()/).length > 1 - ) { + '.'.split(/(.?)(.?)/).length !== 4 || + 'tesst'.split(/(s)*/)[1] === "t" || + 'test'.split(/(?:)/, -1).length !== 4 || + ''.split(/.?/).length || + '.'.split(/()()/).length > 1 + ) { (function () { var compliantExecNpcg = /()??/.exec("")[1] === void 0; // NPCG: nonparticipating capturing group - String.prototype.split = function (separator, limit) { + StringPrototype.split = function (separator, limit) { var string = this; if (separator === void 0 && limit === 0) { return []; @@ -1153,9 +1250,9 @@ setTimeout(function(){ var output = [], flags = (separator.ignoreCase ? "i" : "") + - (separator.multiline ? "m" : "") + - (separator.extended ? "x" : "") + // Proposed for ES6 - (separator.sticky ? "y" : ""), // Firefox 3+ + (separator.multiline ? "m" : "") + + (separator.extended ? "x" : "") + // Proposed for ES6 + (separator.sticky ? "y" : ""), // Firefox 3+ lastLastIndex = 0, // Make `global` and avoid `lastIndex` issues by working with a copy separator2, match, lastIndex, lastLength; @@ -1173,7 +1270,7 @@ setTimeout(function(){ * If other: Type-convert, then use the above rules */ limit = limit === void 0 ? - -1 >>> 0 : // Math.pow(2, 32) - 1 + -1 >>> 0 : // Math.pow(2, 32) - 1 ToUint32(limit); while (match = separator.exec(string)) { // `separator.lastIndex` is not reliable cross-browser @@ -1192,7 +1289,7 @@ setTimeout(function(){ }); } if (match.length > 1 && match.index < string.length) { - Array.prototype.push.apply(output, match.slice(1)); + ArrayPrototype.push.apply(output, match.slice(1)); } lastLength = match[0].length; lastLastIndex = lastIndex; @@ -1222,13 +1319,13 @@ setTimeout(function(){ // elements. // "0".split(undefined, 0) -> [] } else if ("0".split(void 0, 0).length) { - String.prototype.split = function split(separator, limit) { + StringPrototype.split = function split(separator, limit) { if (separator === void 0 && limit === 0) { return []; } return string_split.call(this, separator, limit); }; } - var str_replace = String.prototype.replace; + var str_replace = StringPrototype.replace; var replaceReportsGroupsCorrectly = (function () { var groups = []; 'x'.replace(/x(.)?/g, function (match, group) { @@ -1238,7 +1335,7 @@ setTimeout(function(){ }()); if (!replaceReportsGroupsCorrectly) { - String.prototype.replace = function replace(searchValue, replaceValue) { + StringPrototype.replace = function replace(searchValue, replaceValue) { var isFn = isFunction(replaceValue); var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source); if (!isFn || !hasCapturingGroups) { @@ -1263,22 +1360,17 @@ setTimeout(function(){ // non-normative section suggesting uniform semantics and it should be // normalized across all browsers // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE - if ("".substr && "0b".substr(-1) !== "b") { - var string_substr = String.prototype.substr; - /** - * Get the substring of a string - * @param {integer} start where to start the substring - * @param {integer} length how many characters to return - * @return {string} - */ - String.prototype.substr = function substr(start, length) { + var string_substr = StringPrototype.substr; + var hasNegativeSubstrBug = "".substr && "0b".substr(-1) !== "b"; + defineProperties(StringPrototype, { + substr: function substr(start, length) { return string_substr.call( this, start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start, length ); - }; - } + } + }, hasNegativeSubstrBug); // ES5 15.5.4.20 // whitespace from: http://es5.github.io/#x15.5.4.20 @@ -1286,21 +1378,20 @@ setTimeout(function(){ "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + "\u2029\uFEFF"; var zeroWidth = '\u200b'; - if (!String.prototype.trim || ws.trim() || !zeroWidth.trim()) { + var wsRegexChars = "[" + ws + "]"; + var trimBeginRegexp = new RegExp("^" + wsRegexChars + wsRegexChars + "*"); + var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + "*$"); + var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim()); + defineProperties(StringPrototype, { // http://blog.stevenlevithan.com/archives/faster-trim-javascript // http://perfectionkills.com/whitespace-deviations/ - ws = "[" + ws + "]"; - var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), - trimEndRegexp = new RegExp(ws + ws + "*$"); - String.prototype.trim = function trim() { + trim: function trim() { if (this === void 0 || this === null) { throw new TypeError("can't convert " + this + " to object"); } - return String(this) - .replace(trimBeginRegexp, "") - .replace(trimEndRegexp, ""); - }; - } + return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); + } + }, hasTrimWhitespaceBug); // ES-5 15.1.2.2 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { @@ -1316,71 +1407,6 @@ setTimeout(function(){ }(parseInt)); } -// -// Util -// ====== -// - -// ES5 9.4 -// http://es5.github.com/#x9.4 -// http://jsperf.com/to-integer - - function toInteger(n) { - n = +n; - if (n !== n) { // isNaN - n = 0; - } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - return n; - } - - function isPrimitive(input) { - var type = typeof input; - return ( - input === null || - type === "undefined" || - type === "boolean" || - type === "number" || - type === "string" - ); - } - - function toPrimitive(input) { - var val, valueOf, toStr; - if (isPrimitive(input)) { - return input; - } - valueOf = input.valueOf; - if (isFunction(valueOf)) { - val = valueOf.call(input); - if (isPrimitive(val)) { - return val; - } - } - toStr = input.toString; - if (isFunction(toStr)) { - val = toStr.call(input); - if (isPrimitive(val)) { - return val; - } - } - throw new TypeError(); - } - -// ES5 9.9 -// http://es5.github.com/#x9.9 - var toObject = function (o) { - if (o == null) { // this matches both null and undefined - throw new TypeError("can't convert " + o + " to object"); - } - return Object(o); - }; - - var ToUint32 = function ToUint32(x) { - return x >>> 0; - }; - })(); diff --git a/public/webshims/shims/filereader-xhr.js b/public/webshims/shims/filereader-xhr.js index b2f7f2d2..27f54f44 100644 --- a/public/webshims/shims/filereader-xhr.js +++ b/public/webshims/shims/filereader-xhr.js @@ -380,22 +380,19 @@ webshim.register('filereader-xhr', function($, webshim, window, document, undefi qualitiy = 0.8; } loadMoxie(); - setTimeout(function(){ + webshim.ready('moxie', function(){ + var img = new mOxie.Image(); dataURL = $canvas.callProp('getAsDataURL', [type, qualitiy]); - webshim.ready('moxie', function(){ - var img = new mOxie.Image(); - - img.onload = function() { - var blob = img.getAsBlob(); - webshim.defineProperty(blob, '_wsDataURL', { - value: dataURL, - enumerable: false - }); - cb(blob); - }; - img.load(dataURL); - }); - }, 9); + img.onload = function() { + var blob = img.getAsBlob(); + webshim.defineProperty(blob, '_wsDataURL', { + value: dataURL, + enumerable: false + }); + cb(blob); + }; + img.load(dataURL); + }); } } }); diff --git a/public/webshims/shims/form-core.js b/public/webshims/shims/form-core.js index 430ae199..dd4063d9 100644 --- a/public/webshims/shims/form-core.js +++ b/public/webshims/shims/form-core.js @@ -256,6 +256,8 @@ webshims.register('form-core', function($, webshims, window, document, undefined } return message || ''; }; + + webshims.refreshCustomValidityRules = $.noop; $.fn.getErrorMessage = function(key){ var message = ''; diff --git a/public/webshims/shims/form-number-date-ui.js b/public/webshims/shims/form-number-date-ui.js index e13363bf..22b78df1 100644 --- a/public/webshims/shims/form-number-date-ui.js +++ b/public/webshims/shims/form-number-date-ui.js @@ -424,9 +424,13 @@ webshims.register('form-number-date-ui', function($, webshims, window, document, }, time: function(val, o, noCorrect){ var fVal, i; + if(val){ val = val.split(':'); + if(val.length != 2 || isNaN(parseInt(val[0] || '', 10)) || isNaN(parseInt(val[1] || '', 10))){ + return val.join(':'); + } if(curCfg.meridian){ fVal = (val[0] * 1); if(fVal && fVal >= 12){ @@ -581,6 +585,7 @@ webshims.register('form-number-date-ui', function($, webshims, window, document, createFormat('d'); var tmp, obj; var ret = ''; + if(opts.splitInput){ obj = {yy: 0, mm: 1, dd: 2}; } else { @@ -602,8 +607,7 @@ webshims.register('form-number-date-ui', function($, webshims, window, document, } ret = ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-'); } - return ret - ; + return ret; }, color: function(val, opts){ var ret = '#000000'; @@ -905,9 +909,11 @@ webshims.register('form-number-date-ui', function($, webshims, window, document, }; ['defaultValue', 'value'].forEach(function(name){ + var formatName = 'format'+name; wsWidgetProto[name] = function(val, force){ - if(!this._init || force || val !== this.options[name]){ - this.element.prop(name, this.formatValue(val)); + if(!this._init || force || val !== this.options[name] || this.options[formatName] != this.element.prop(name)){ + this.options[formatName] = this.formatValue(val); + this.element.prop(name, this.options[formatName]); this.options[name] = val; this._propertyChange(name); this.mirrorValidity(); @@ -1031,36 +1037,34 @@ webshims.register('form-number-date-ui', function($, webshims, window, document, var isValue = name == 'value'; spinBtnProto[name] = function(val, force, isLive){ var selectionEnd; - if(!this._init || force || this.options[name] !== val){ - if(isValue){ - this._beforeValue(val); - } else { - this.elemHelper.prop(name, val); - } - - val = formatVal[this.type](val, this.options); - if(this.options.splitInput){ - $.each(this.splits, function(i, elem){ - var setOption; - if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ - $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); - } else { - $.prop(elem, name, val[i]); - } - }); - } else { - val = this.toFixed(val); - if(isLive && this._getSelectionEnd){ - selectionEnd = this._getSelectionEnd(val); - } - this.element.prop(name, val); - if(selectionEnd != null){ - this.element.prop('selectionEnd', selectionEnd); - } - } - this._propertyChange(name); - this.mirrorValidity(); + if(isValue){ + this._beforeValue(val); + } else { + this.elemHelper.prop(name, val); } + + val = formatVal[this.type](val, this.options); + if(this.options.splitInput){ + $.each(this.splits, function(i, elem){ + var setOption; + if(!(name in elem) && !isValue && $.nodeName(elem, 'select')){ + $('option[value="'+ val[i] +'"]', elem).prop('defaultSelected', true); + } else { + $.prop(elem, name, val[i]); + } + }); + } else { + val = this.toFixed(val); + if(isLive && this._getSelectionEnd){ + selectionEnd = this._getSelectionEnd(val); + } + this.element.prop(name, val); + if(selectionEnd != null){ + this.element.prop('selectionEnd', selectionEnd); + } + } + this._propertyChange(name); + this.mirrorValidity(); }; }); diff --git a/public/webshims/shims/form-shim-extend.js b/public/webshims/shims/form-shim-extend.js index b73c4ec8..0b64432e 100644 --- a/public/webshims/shims/form-shim-extend.js +++ b/public/webshims/shims/form-shim-extend.js @@ -607,22 +607,25 @@ if(webshims.support.inputtypes.date && /webkit/i.test(navigator.userAgent)){ webshims.addReady(function(context, contextElem){ //start constrain-validation - var focusElem; + $('form', context) .add(contextElem.filter('form')) .on('invalid', $.noop) ; - - try { - if(context == document && !('form' in (document.activeElement || {}))) { - focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; - if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) { - focusElem.focus(); + + setTimeout(function(){ + var focusElem; + try { + if(!('form' in (document.activeElement || {}))) { + focusElem = $(context.querySelector('input[autofocus], select[autofocus], textarea[autofocus]')).eq(0).getShadowFocusElement()[0]; + if (focusElem && (focusElem.offsetHeight || focusElem.offsetWidth)) { + focusElem.focus(); + } } } - } - catch (er) {} - + catch (er) {} + }, 9); + }); if(!webshims.support.datalist){ diff --git a/public/webshims/shims/form-validation.js b/public/webshims/shims/form-validation.js index d31ee479..f82b7ece 100644 --- a/public/webshims/shims/form-validation.js +++ b/public/webshims/shims/form-validation.js @@ -117,7 +117,7 @@ webshims.register('form-validation', function($, webshims, window, document, und ){ return; } - if(webshims.refreshCustomValidityRules && webshims.refreshCustomValidityRules(elem) == 'async'){ + if(webshims.refreshCustomValidityRules(elem) == 'async'){ $(elem).one('updatevalidation.webshims', switchValidityClass); return; } @@ -423,7 +423,7 @@ webshims.register('form-validation', function($, webshims, window, document, und if(!appendElement && !invalidParent.test(parent.nodeName)){ appendElement = parent; } - if(appendElement && $.css(parent, 'overflow') == 'hidden' && $.css(parent, 'position') != 'static'){ + if(appendElement && $.css(parent, 'overflow') != 'visible' && $.css(parent, 'position') != 'static'){ appendElement = false; } } diff --git a/public/webshims/shims/form-validators.js b/public/webshims/shims/form-validators.js index 484c0389..f084fa65 100644 --- a/public/webshims/shims/form-validators.js +++ b/public/webshims/shims/form-validators.js @@ -7,10 +7,6 @@ webshims.ready('form-validation', function(){ }); (function(){ - if(webshims.refreshCustomValidityRules){ - webshims.error("form-validators already included. please remove custom-validity.js"); - } - var customValidityRules = {}; var formReady = false; var blockCustom; @@ -341,8 +337,6 @@ webshims.ready('form-validation', function(){ val = $.inArray(val, data.specialVal) !== -1; } if(data.toggle){ val = !val; - } else { - val = !!val; } $.prop( elem, data.prop, val); if(iValClasses && e){ diff --git a/public/webshims/shims/forms-picker.js b/public/webshims/shims/forms-picker.js index 10ca13f6..5af95a2d 100644 --- a/public/webshims/shims/forms-picker.js +++ b/public/webshims/shims/forms-picker.js @@ -1188,12 +1188,12 @@ webshims.register('forms-picker', function($, webshims, window, document, undefi str.push(''+ dateCfg.weekHeader +''); - for(k = dateCfg.firstDay; k < dateCfg.dayNamesShort.length; k++){ - str.push(''+ dateCfg.dayNamesShort[k] +''); + for(k = dateCfg.firstDay; k < dateCfg.dayNamesMin.length; k++){ + str.push(''+ dateCfg.dayNamesMin[k] +''); } k = dateCfg.firstDay; while(k--){ - str.push(''+ dateCfg.dayNamesShort[k] +''); + str.push(''+ dateCfg.dayNamesMin[k] +''); } str.push(''); diff --git a/public/webshims/shims/i18n/formcfg-ca.js b/public/webshims/shims/i18n/formcfg-ca.js new file mode 100644 index 00000000..e9010587 --- /dev/null +++ b/public/webshims/shims/i18n/formcfg-ca.js @@ -0,0 +1,65 @@ +webshims.validityMessages.es = { + "typeMismatch": { + "email": "Si us plau, introduïu una adreça de correu.", + "url": "Si us plau, introduïu un URL." + }, + "badInput": { + "number": "Valor no válid", + "date": "Valor no válid", + "time": "Valor no válid", + "range": "Valor no válid", + "datetime-local": "Valor no válid" + }, + "tooLong": "Valor no válid", + "patternMismatch": "Si us plau, ajusteu-vos al format sol·licitat: {%title}.", + "valueMissing": { + "defaultMessage": "Si us plau, ompliu aquest camp.", + "checkbox": "Si us plau, marqueu aquesta casella si voleu continuar.", + "select": "Si us plau, seleccioneu un element de la llista.", + "radio": "Si us plau, seleccioneu una de les opcions." + }, + "rangeUnderflow": { + "defaultMessage": "El valor ha de superior o igual a {%min}.", + "date": "El valor ha de superior o igual a {%min}.", + "time": "El valor ha de superior o igual a {%min}.", + "datetime-local": "El valor ha de superior o igual a {%min}." + }, + "rangeOverflow": { + "defaultMessage": "El valor ha de inferior o igual a {%max}.", + "date": "El valor ha de inferior o igual a {%max}.", + "time": "El valor ha de inferior o igual a {%max}.", + "datetime-local": "El valor ha de inferior o igual a {%max}." + }, + "stepMismatch": "Valor no válid" +}; +webshims.formcfg.es = { + numberFormat: { + ".": ".", + ",": "," + }, + numberSigns: '.', + dateSigns: '/', + timeSigns: ":. ", + dFormat: "/", + patterns: { + d: 'dd/mm/yy' + }, + date: { + closeText: 'Tanca', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Avui', + monthNames: ['gener','gebrer','març','abril','maig','juny', + 'juliol','agost','setembre','octubre','novembre','desembre'], + monthNamesShort: ['gen','febr','març','abr','maig','juny', + 'jul','ag','set','oct','nov','des'], + dayNames: ['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'], + dayNamesShort: ['dg','dl','dt','dc','dj','dv','ds'], + dayNamesMin: ['dg','dl','dt','dc','dj','dv','ds'], + weekHeader: 'St', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + } +}; diff --git a/public/webshims/shims/i18n/formcfg-ru.js b/public/webshims/shims/i18n/formcfg-ru.js index 8f7dfbac..03dca4e3 100644 --- a/public/webshims/shims/i18n/formcfg-ru.js +++ b/public/webshims/shims/i18n/formcfg-ru.js @@ -44,8 +44,15 @@ webshims.formcfg.ru = { patterns: { d: 'dd.mm.yy' }, + month: { + currentText: 'Текущий месяц' + }, + time: { + currentText: 'Сейчас' + }, date: { closeText: 'Закрыть', + clear: 'Очистить', prevText: '<Пред', nextText: 'След>', currentText: 'Сегодня', @@ -53,7 +60,7 @@ webshims.formcfg.ru = { 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', 'Июл','Авг','Сен','Окт','Ноя','Дек'], - dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], + dayNames: ['Воскресенье','Понедельник','Вторник','Среда','Четверг','Пятница','Суббота'], dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], weekHeader: 'Нед', diff --git a/public/webshims/shims/jme/controls.css b/public/webshims/shims/jme/controls.css index 10ece81e..262d1dcc 100644 --- a/public/webshims/shims/jme/controls.css +++ b/public/webshims/shims/jme/controls.css @@ -103,7 +103,6 @@ 0% { -webkit-transform: rotate(0deg); } - 100% { -webkit-transform: rotate(360deg); } @@ -113,7 +112,6 @@ -webkit-transform: rotate(0deg); transform: rotate(0deg); } - 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); @@ -468,7 +466,7 @@ .mediaplayer .mediamenu > div > .media-submenu { margin: 0.3125em 0; padding: 0.3125em 0; - border-top: 0.0625em solid #eeeeee; + border-top: 0.0625em solid #eee; border-top: 0.0625em solid rgba(255, 255, 255, 0.4); } .mediaplayer .mediamenu > div > .media-submenu:first-child { diff --git a/public/webshims/shims/jpicker/images/AlphaBar.png b/public/webshims/shims/jpicker/images/AlphaBar.png index 2950daeb..602ede62 100644 Binary files a/public/webshims/shims/jpicker/images/AlphaBar.png and b/public/webshims/shims/jpicker/images/AlphaBar.png differ diff --git a/public/webshims/shims/jpicker/images/Bars.png b/public/webshims/shims/jpicker/images/Bars.png index 6392738a..1244c413 100644 Binary files a/public/webshims/shims/jpicker/images/Bars.png and b/public/webshims/shims/jpicker/images/Bars.png differ diff --git a/public/webshims/shims/jpicker/images/Maps.png b/public/webshims/shims/jpicker/images/Maps.png index 889849bd..3061d1c3 100644 Binary files a/public/webshims/shims/jpicker/images/Maps.png and b/public/webshims/shims/jpicker/images/Maps.png differ diff --git a/public/webshims/shims/jpicker/images/NoColor.png b/public/webshims/shims/jpicker/images/NoColor.png index 5dc47670..1b6469f4 100644 Binary files a/public/webshims/shims/jpicker/images/NoColor.png and b/public/webshims/shims/jpicker/images/NoColor.png differ diff --git a/public/webshims/shims/jpicker/images/bar-opacity.png b/public/webshims/shims/jpicker/images/bar-opacity.png index 4769813e..01b3d90c 100644 Binary files a/public/webshims/shims/jpicker/images/bar-opacity.png and b/public/webshims/shims/jpicker/images/bar-opacity.png differ diff --git a/public/webshims/shims/jpicker/images/map-opacity.png b/public/webshims/shims/jpicker/images/map-opacity.png index 9a31e9bf..4d7dd032 100644 Binary files a/public/webshims/shims/jpicker/images/map-opacity.png and b/public/webshims/shims/jpicker/images/map-opacity.png differ diff --git a/public/webshims/shims/jpicker/images/preview-opacity.png b/public/webshims/shims/jpicker/images/preview-opacity.png index 0dd9a2f8..ef9fff49 100644 Binary files a/public/webshims/shims/jpicker/images/preview-opacity.png and b/public/webshims/shims/jpicker/images/preview-opacity.png differ diff --git a/public/webshims/shims/mediacapture.js b/public/webshims/shims/mediacapture.js index a41bef6e..c9476a48 100644 --- a/public/webshims/shims/mediacapture.js +++ b/public/webshims/shims/mediacapture.js @@ -81,6 +81,7 @@ webshim.register('mediacapture', function($, webshim, window, document, undefine resolve(); } })(); + var regImage = /image\/\*|image\/jp/i; var loadPicker = function(){ webshim.ready('WINDOWLOAD', function(){ webshim.loader.loadList(['mediacapture-picker']); @@ -91,10 +92,15 @@ webshim.register('mediacapture', function($, webshim, window, document, undefine var _createPhotoPicker = function(){ if($(this).is('[capture].ws-filereader, .ws-capture') && webshim.implement(this, 'capture')){ - var $wrapper, $customFile; + var $wrapper, $customFile, $button, popover; var $fileinput = $(this); - var $button = $(''); - var popover = webshim.objectCreate(webshim.wsPopover, {}, $.extend({prepareFor: $button})); + var accept = $fileinput.prop('accept') || 'image/*'; + + if(!regImage.test(accept)){return;} + + $button = $('