r225 - in sandbox/nuiton-js-angular: . src/main/resources/META-INF/nuiton-js src/main/resources/nuiton-js-angular src/main/resources/nuiton-js-angular/i18n
Author: echatellier Date: 2013-11-10 12:10:19 +0100 (Sun, 10 Nov 2013) New Revision: 225 Url: http://nuiton.org/projects/nuiton-js/repository/revisions/225 Log: Update to angular 1.2.0 Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-animate.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-cookies.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-loader.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-mocks.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-resource.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-route.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-sanitize.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-touch.js Removed: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/ Modified: sandbox/nuiton-js-angular/generate-extra-group.sh sandbox/nuiton-js-angular/pom.xml sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js Modified: sandbox/nuiton-js-angular/generate-extra-group.sh =================================================================== --- sandbox/nuiton-js-angular/generate-extra-group.sh 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/generate-extra-group.sh 2013-11-10 11:10:19 UTC (rev 225) @@ -3,8 +3,8 @@ # Permet de genere le code XML necessaire pour la declaration des extras # il faut ensuite mettre ce qui est genere dans le fichier META-INF/nuiton-js/nuiton-js-angular.xml # -for t in src/main/resources/nuiton-js-angular/extra/*.js; do +for t in src/main/resources/nuiton-js-angular/angular-*.js; do f=$(basename $t) n=$(basename $t .js) - echo -e " <group name='$n'>\n <js>classpath:nuiton-js-angular/extra/$f</js>\n </group>\n" + echo -e " <group name='$n'>\n <js>classpath:nuiton-js-angular/$f</js>\n </group>\n" done Modified: sandbox/nuiton-js-angular/pom.xml =================================================================== --- sandbox/nuiton-js-angular/pom.xml 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/pom.xml 2013-11-10 11:10:19 UTC (rev 225) @@ -14,7 +14,7 @@ </parent> <artifactId>nuiton-js-angular</artifactId> - <version>1.2.0-rc3-1</version> + <version>1.2.0-1</version> <name>Nuiton JS :: Angular</name> <description>Angular jar packaging</description> @@ -29,9 +29,9 @@ </licenses> <scm> - <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc3-1</connection> - <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc3-1</developerConnection> - <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-1.2.0-rc3-1</url> + <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-1</connection> + <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-1</developerConnection> + <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-1.2.0-1</url> </scm> </project> Modified: sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml 2013-11-10 11:10:19 UTC (rev 225) @@ -26,36 +26,36 @@ <js>classpath:nuiton-js-angular/angular.js</js> </group> - <group name='angular-animate'> - <js>classpath:nuiton-js-angular/extra/angular-animate.js</js> + <group name='angular-animate'> + <js>classpath:nuiton-js-angular/angular-animate.js</js> </group> <group name='angular-cookies'> - <js>classpath:nuiton-js-angular/extra/angular-cookies.js</js> + <js>classpath:nuiton-js-angular/angular-cookies.js</js> </group> <group name='angular-loader'> - <js>classpath:nuiton-js-angular/extra/angular-loader.js</js> + <js>classpath:nuiton-js-angular/angular-loader.js</js> </group> <group name='angular-mocks'> - <js>classpath:nuiton-js-angular/extra/angular-mocks.js</js> + <js>classpath:nuiton-js-angular/angular-mocks.js</js> </group> <group name='angular-resource'> - <js>classpath:nuiton-js-angular/extra/angular-resource.js</js> + <js>classpath:nuiton-js-angular/angular-resource.js</js> </group> <group name='angular-route'> - <js>classpath:nuiton-js-angular/extra/angular-route.js</js> + <js>classpath:nuiton-js-angular/angular-route.js</js> </group> <group name='angular-sanitize'> - <js>classpath:nuiton-js-angular/extra/angular-sanitize.js</js> + <js>classpath:nuiton-js-angular/angular-sanitize.js</js> </group> <group name='angular-touch'> - <js>classpath:nuiton-js-angular/extra/angular-touch.js</js> + <js>classpath:nuiton-js-angular/angular-touch.js</js> </group> <group name='angular-af-na'> Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-animate.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-animate.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-animate.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,1226 @@ +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/* jshint maxlen: false */ + +/** + * @ngdoc overview + * @name ngAnimate + * @description + * + * # ngAnimate + * + * The `ngAnimate` module provides support for JavaScript, CSS3 transition and CSS3 keyframe animation hooks within existing core and custom directives. + * + * {@installModule animate} + * + * <div doc-module-components="ngAnimate"></div> + * + * # Usage + * + * To see animations in action, all that is required is to define the appropriate CSS classes + * or to register a JavaScript animation via the myModule.animation() function. The directives that support animation automatically are: + * `ngRepeat`, `ngInclude`, `ngIf`, `ngSwitch`, `ngShow`, `ngHide`, `ngView` and `ngClass`. Custom directives can take advantage of animation + * by using the `$animate` service. + * + * Below is a more detailed breakdown of the supported animation events provided by pre-existing ng directives: + * + * | Directive | Supported Animations | + * |---------------------------------------------------------- |----------------------------------------------------| + * | {@link ng.directive:ngRepeat#usage_animations ngRepeat} | enter, leave and move | + * | {@link ngRoute.directive:ngView#usage_animations ngView} | enter and leave | + * | {@link ng.directive:ngInclude#usage_animations ngInclude} | enter and leave | + * | {@link ng.directive:ngSwitch#usage_animations ngSwitch} | enter and leave | + * | {@link ng.directive:ngIf#usage_animations ngIf} | enter and leave | + * | {@link ng.directive:ngClass#usage_animations ngClass} | add and remove | + * | {@link ng.directive:ngShow#usage_animations ngShow & ngHide} | add and remove (the ng-hide class value) | + * + * You can find out more information about animations upon visiting each directive page. + * + * Below is an example of how to apply animations to a directive that supports animation hooks: + * + * <pre> + * <style type="text/css"> + * .slide.ng-enter, .slide.ng-leave { + * -webkit-transition:0.5s linear all; + * transition:0.5s linear all; + * } + * + * .slide.ng-enter { } /* starting animations for enter */ + * .slide.ng-enter-active { } /* terminal animations for enter */ + * .slide.ng-leave { } /* starting animations for leave */ + * .slide.ng-leave-active { } /* terminal animations for leave */ + * </style> + * + * <!-- + * the animate service will automatically add .ng-enter and .ng-leave to the element + * to trigger the CSS transition/animations + * --> + * <ANY class="slide" ng-include="..."></ANY> + * </pre> + * + * Keep in mind that if an animation is running, any child elements cannot be animated until the parent element's + * animation has completed. + * + * <h2>CSS-defined Animations</h2> + * The animate service will automatically apply two CSS classes to the animated element and these two CSS classes + * are designed to contain the start and end CSS styling. Both CSS transitions and keyframe animations are supported + * and can be used to play along with this naming structure. + * + * The following code below demonstrates how to perform animations using **CSS transitions** with Angular: + * + * <pre> + * <style type="text/css"> + * /* + * The animate class is apart of the element and the ng-enter class + * is attached to the element once the enter animation event is triggered + * */ + * .reveal-animation.ng-enter { + * -webkit-transition: 1s linear all; /* Safari/Chrome */ + * transition: 1s linear all; /* All other modern browsers and IE10+ */ + * + * /* The animation preparation code */ + * opacity: 0; + * } + * + * /* + * Keep in mind that you want to combine both CSS + * classes together to avoid any CSS-specificity + * conflicts + * */ + * .reveal-animation.ng-enter.ng-enter-active { + * /* The animation code itself */ + * opacity: 1; + * } + * </style> + * + * <div class="view-container"> + * <div ng-view class="reveal-animation"></div> + * </div> + * </pre> + * + * The following code below demonstrates how to perform animations using **CSS animations** with Angular: + * + * <pre> + * <style type="text/css"> + * .reveal-animation.ng-enter { + * -webkit-animation: enter_sequence 1s linear; /* Safari/Chrome */ + * animation: enter_sequence 1s linear; /* IE10+ and Future Browsers */ + * } + * @-webkit-keyframes enter_sequence { + * from { opacity:0; } + * to { opacity:1; } + * } + * @keyframes enter_sequence { + * from { opacity:0; } + * to { opacity:1; } + * } + * </style> + * + * <div class="view-container"> + * <div ng-view class="reveal-animation"></div> + * </div> + * </pre> + * + * Both CSS3 animations and transitions can be used together and the animate service will figure out the correct duration and delay timing. + * + * Upon DOM mutation, the event class is added first (something like `ng-enter`), then the browser prepares itself to add + * the active class (in this case `ng-enter-active`) which then triggers the animation. The animation module will automatically + * detect the CSS code to determine when the animation ends. Once the animation is over then both CSS classes will be + * removed from the DOM. If a browser does not support CSS transitions or CSS animations then the animation will start and end + * immediately resulting in a DOM element that is at its final state. This final state is when the DOM element + * has no CSS transition/animation classes applied to it. + * + * <h3>CSS Staggering Animations</h3> + * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a + * curtain-like effect. The ngAnimate module, as of 1.2.0, supports staggering animations and the stagger effect can be + * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for + * the animation. The style property expected within the stagger class can either be a **transition-delay** or an + * **animation-delay** property (or both if your animation contains both transitions and keyframe animations). + * + * <pre> + * .my-animation.ng-enter { + * /* standard transition code */ + * -webkit-transition: 1s linear all; + * transition: 1s linear all; + * opacity:0; + * } + * .my-animation.ng-enter-stagger { + * /* this will have a 100ms delay between each successive leave animation */ + * -webkit-transition-delay: 0.1s; + * transition-delay: 0.1s; + * + * /* in case the stagger doesn't work then these two values + * must be set to 0 to avoid an accidental CSS inheritance */ + * -webkit-transition-duration: 0s; + * transition-duration: 0s; + * } + * .my-animation.ng-enter.ng-enter-active { + * /* standard transition styles */ + * opacity:1; + * } + * </pre> + * + * Staggering animations work by default in ngRepeat (so long as the CSS class is defiend). Outside of ngRepeat, to use staggering animations + * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this + * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation + * will also be reset if more than 10ms has passed after the last animation has been fired. + * + * The following code will issue the **ng-leave-stagger** event on the element provided: + * + * <pre> + * var kids = parent.children(); + * + * $animate.leave(kids[0]); //stagger index=0 + * $animate.leave(kids[1]); //stagger index=1 + * $animate.leave(kids[2]); //stagger index=2 + * $animate.leave(kids[3]); //stagger index=3 + * $animate.leave(kids[4]); //stagger index=4 + * + * $timeout(function() { + * //stagger has reset itself + * $animate.leave(kids[5]); //stagger index=0 + * $animate.leave(kids[6]); //stagger index=1 + * }, 100, false); + * </pre> + * + * Stagger animations are currently only supported within CSS-defined animations. + * + * <h2>JavaScript-defined Animations</h2> + * In the event that you do not want to use CSS3 transitions or CSS3 animations or if you wish to offer animations on browsers that do not + * yet support CSS transitions/animations, then you can make use of JavaScript animations defined inside of your AngularJS module. + * + * <pre> + * //!annotate="YourApp" Your AngularJS Module|Replace this or ngModule with the module that you used to define your application. + * var ngModule = angular.module('YourApp', []); + * ngModule.animation('.my-crazy-animation', function() { + * return { + * enter: function(element, done) { + * //run the animation here and call done when the animation is complete + * return function(cancelled) { + * //this (optional) function will be called when the animation + * //completes or when the animation is cancelled (the cancelled + * //flag will be set to true if cancelled). + * } + * } + * leave: function(element, done) { }, + * move: function(element, done) { }, + * + * //animation that can be triggered before the class is added + * beforeAddClass: function(element, className, done) { }, + * + * //animation that can be triggered after the class is added + * addClass: function(element, className, done) { }, + * + * //animation that can be triggered before the class is removed + * beforeRemoveClass: function(element, className, done) { }, + * + * //animation that can be triggered after the class is removed + * removeClass: function(element, className, done) { } + * } + * }); + * </pre> + * + * JavaScript-defined animations are created with a CSS-like class selector and a collection of events which are set to run + * a javascript callback function. When an animation is triggered, $animate will look for a matching animation which fits + * the element's CSS class attribute value and then run the matching animation event function (if found). + * In other words, if the CSS classes present on the animated element match any of the JavaScript animations then the callback function + * be executed. It should be also noted that only simple, single class selectors are allowed (compound class selectors are not supported). + * + * Within a JavaScript animation, an object containing various event callback animation functions is expected to be returned. + * As explained above, these callbacks are triggered based on the animation event. Therefore if an enter animation is run, + * and the JavaScript animation is found, then the enter callback will handle that animation (in addition to the CSS keyframe animation + * or transition code that is defined via a stylesheet). + * + */ + +angular.module('ngAnimate', ['ng']) + + /** + * @ngdoc object + * @name ngAnimate.$animateProvider + * @description + * + * The `$animateProvider` allows developers to register JavaScript animation event handlers directly inside of a module. + * When an animation is triggered, the $animate service will query the $animate service to find any animations that match + * the provided name value. + * + * Requires the {@link ngAnimate `ngAnimate`} module to be installed. + * + * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application. + * + */ + .config(['$provide', '$animateProvider', function($provide, $animateProvider) { + var noop = angular.noop; + var forEach = angular.forEach; + var selectors = $animateProvider.$$selectors; + + var ELEMENT_NODE = 1; + var NG_ANIMATE_STATE = '$$ngAnimateState'; + var NG_ANIMATE_CLASS_NAME = 'ng-animate'; + var rootAnimateState = {running: true}; + + $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout', '$rootScope', '$document', + function($delegate, $injector, $sniffer, $rootElement, $timeout, $rootScope, $document) { + + $rootElement.data(NG_ANIMATE_STATE, rootAnimateState); + + // disable animations during bootstrap, but once we bootstrapped, enable animations + $rootScope.$$postDigest(function() { + rootAnimateState.running = false; + }); + + function lookup(name) { + if (name) { + var matches = [], + flagMap = {}, + classes = name.substr(1).split('.'); + + //the empty string value is the default animation + //operation which performs CSS transition and keyframe + //animations sniffing. This is always included for each + //element animation procedure if the browser supports + //transitions and/or keyframe animations + if ($sniffer.transitions || $sniffer.animations) { + classes.push(''); + } + + for(var i=0; i < classes.length; i++) { + var klass = classes[i], + selectorFactoryName = selectors[klass]; + if(selectorFactoryName && !flagMap[klass]) { + matches.push($injector.get(selectorFactoryName)); + flagMap[klass] = true; + } + } + return matches; + } + } + + /** + * @ngdoc object + * @name ngAnimate.$animate + * @function + * + * @description + * The `$animate` service provides animation detection support while performing DOM operations (enter, leave and move) as well as during addClass and removeClass operations. + * When any of these operations are run, the $animate service + * will examine any JavaScript-defined animations (which are defined by using the $animateProvider provider object) + * as well as any CSS-defined animations against the CSS classes present on the element once the DOM operation is run. + * + * The `$animate` service is used behind the scenes with pre-existing directives and animation with these directives + * will work out of the box without any extra configuration. + * + * Requires the {@link ngAnimate `ngAnimate`} module to be installed. + * + * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application. + * + */ + return { + /** + * @ngdoc function + * @name ngAnimate.$animate#enter + * @methodOf ngAnimate.$animate + * @function + * + * @description + * Appends the element to the parentElement element that resides in the document and then runs the enter animation. Once + * the animation is started, the following CSS classes will be present on the element for the duration of the animation: + * + * Below is a breakdown of each step that occurs during enter animation: + * + * | Animation Step | What the element class attribute looks like | + * |----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.enter(...) is called | class="my-animation" | + * | 2. element is inserted into the parentElement element or beside the afterElement element | class="my-animation" | + * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 4. the .ng-enter class is added to the element | class="my-animation ng-animate ng-enter" | + * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-enter" | + * | 6. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-enter" | + * | 7. the .ng-enter-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" | + * | 8. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-enter ng-enter-active" | + * | 9. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 10. The doneCallback() callback is fired (if provided) | class="my-animation" | + * + * @param {jQuery/jqLite element} element the element that will be the focus of the enter animation + * @param {jQuery/jqLite element} parentElement the parent element of the element that will be the focus of the enter animation + * @param {jQuery/jqLite element} afterElement the sibling element (which is the previous element) of the element that will be the focus of the enter animation + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + enter : function(element, parentElement, afterElement, doneCallback) { + this.enabled(false, element); + $delegate.enter(element, parentElement, afterElement); + $rootScope.$$postDigest(function() { + performAnimation('enter', 'ng-enter', element, parentElement, afterElement, noop, doneCallback); + }); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#leave + * @methodOf ngAnimate.$animate + * @function + * + * @description + * Runs the leave animation operation and, upon completion, removes the element from the DOM. Once + * the animation is started, the following CSS classes will be added for the duration of the animation: + * + * Below is a breakdown of each step that occurs during enter animation: + * + * | Animation Step | What the element class attribute looks like | + * |----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.leave(...) is called | class="my-animation" | + * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 3. the .ng-leave class is added to the element | class="my-animation ng-animate ng-leave" | + * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-leave" | + * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-leave" | + * | 6. the .ng-leave-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" | + * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-leave ng-leave-active" | + * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 9. The element is removed from the DOM | ... | + * | 10. The doneCallback() callback is fired (if provided) | ... | + * + * @param {jQuery/jqLite element} element the element that will be the focus of the leave animation + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + leave : function(element, doneCallback) { + cancelChildAnimations(element); + this.enabled(false, element); + $rootScope.$$postDigest(function() { + performAnimation('leave', 'ng-leave', element, null, null, function() { + $delegate.leave(element); + }, doneCallback); + }); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#move + * @methodOf ngAnimate.$animate + * @function + * + * @description + * Fires the move DOM operation. Just before the animation starts, the animate service will either append it into the parentElement container or + * add the element directly after the afterElement element if present. Then the move animation will be run. Once + * the animation is started, the following CSS classes will be added for the duration of the animation: + * + * Below is a breakdown of each step that occurs during move animation: + * + * | Animation Step | What the element class attribute looks like | + * |----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.move(...) is called | class="my-animation" | + * | 2. element is moved into the parentElement element or beside the afterElement element | class="my-animation" | + * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 4. the .ng-move class is added to the element | class="my-animation ng-animate ng-move" | + * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate ng-move" | + * | 6. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate ng-move" | + * | 7. the .ng-move-active and .ng-animate-active classes is added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" | + * | 8. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active ng-move ng-move-active" | + * | 9. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 10. The doneCallback() callback is fired (if provided) | class="my-animation" | + * + * @param {jQuery/jqLite element} element the element that will be the focus of the move animation + * @param {jQuery/jqLite element} parentElement the parentElement element of the element that will be the focus of the move animation + * @param {jQuery/jqLite element} afterElement the sibling element (which is the previous element) of the element that will be the focus of the move animation + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + move : function(element, parentElement, afterElement, doneCallback) { + cancelChildAnimations(element); + this.enabled(false, element); + $delegate.move(element, parentElement, afterElement); + $rootScope.$$postDigest(function() { + performAnimation('move', 'ng-move', element, parentElement, afterElement, noop, doneCallback); + }); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#addClass + * @methodOf ngAnimate.$animate + * + * @description + * Triggers a custom animation event based off the className variable and then attaches the className value to the element as a CSS class. + * Unlike the other animation methods, the animate service will suffix the className value with {@type -add} in order to provide + * the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if no CSS transitions + * or keyframes are defined on the -add or base CSS class). + * + * Below is a breakdown of each step that occurs during addClass animation: + * + * | Animation Step | What the element class attribute looks like | + * |------------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.addClass(element, 'super') is called | class="my-animation" | + * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-animate" | + * | 3. the .super-add class are added to the element | class="my-animation ng-animate super-add" | + * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-animate super-add" | + * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation ng-animate super-add" | + * | 6. the .super, .super-add-active and .ng-animate-active classes are added (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super super-add super-add-active" | + * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation super-add super-add-active" | + * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation super" | + * | 9. The super class is kept on the element | class="my-animation super" | + * | 10. The doneCallback() callback is fired (if provided) | class="my-animation super" | + * + * @param {jQuery/jqLite element} element the element that will be animated + * @param {string} className the CSS class that will be added to the element and then animated + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + addClass : function(element, className, doneCallback) { + performAnimation('addClass', className, element, null, null, function() { + $delegate.addClass(element, className); + }, doneCallback); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#removeClass + * @methodOf ngAnimate.$animate + * + * @description + * Triggers a custom animation event based off the className variable and then removes the CSS class provided by the className value + * from the element. Unlike the other animation methods, the animate service will suffix the className value with {@type -remove} in + * order to provide the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if + * no CSS transitions or keyframes are defined on the -remove or base CSS classes). + * + * Below is a breakdown of each step that occurs during removeClass animation: + * + * | Animation Step | What the element class attribute looks like | + * |-----------------------------------------------------------------------------------------------|---------------------------------------------| + * | 1. $animate.removeClass(element, 'super') is called | class="my-animation super" | + * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation super ng-animate" | + * | 3. the .super-remove class are added to the element | class="my-animation super ng-animate super-remove"| + * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation super ng-animate super-remove" | + * | 5. $animate waits for 10ms (this performs a reflow) | class="my-animation super ng-animate super-remove" | + * | 6. the .super-remove-active and .ng-animate-active classes are added and .super is removed (this triggers the CSS transition/animation) | class="my-animation ng-animate ng-animate-active super-remove super-remove-active" | + * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-animate ng-animate-active super-remove super-remove-active" | + * | 8. The animation ends and all generated CSS classes are removed from the element | class="my-animation" | + * | 9. The doneCallback() callback is fired (if provided) | class="my-animation" | + * + * + * @param {jQuery/jqLite element} element the element that will be animated + * @param {string} className the CSS class that will be animated and then removed from the element + * @param {function()=} doneCallback the callback function that will be called once the animation is complete + */ + removeClass : function(element, className, doneCallback) { + performAnimation('removeClass', className, element, null, null, function() { + $delegate.removeClass(element, className); + }, doneCallback); + }, + + /** + * @ngdoc function + * @name ngAnimate.$animate#enabled + * @methodOf ngAnimate.$animate + * @function + * + * @param {boolean=} value If provided then set the animation on or off. + * @return {boolean} Current animation state. + * + * @description + * Globally enables/disables animations. + * + */ + enabled : function(value, element) { + switch(arguments.length) { + case 2: + if(value) { + cleanup(element); + } else { + var data = element.data(NG_ANIMATE_STATE) || {}; + data.disabled = true; + element.data(NG_ANIMATE_STATE, data); + } + break; + + case 1: + rootAnimateState.disabled = !value; + break; + + default: + value = !rootAnimateState.disabled; + break; + } + return !!value; + } + }; + + /* + all animations call this shared animation triggering function internally. + The animationEvent variable refers to the JavaScript animation event that will be triggered + and the className value is the name of the animation that will be applied within the + CSS code. Element, parentElement and afterElement are provided DOM elements for the animation + and the onComplete callback will be fired once the animation is fully complete. + */ + function performAnimation(animationEvent, className, element, parentElement, afterElement, domOperation, doneCallback) { + var classes = (element.attr('class') || '') + ' ' + className; + var animationLookup = (' ' + classes).replace(/\s+/g,'.'); + if (!parentElement) { + parentElement = afterElement ? afterElement.parent() : element.parent(); + } + + var matches = lookup(animationLookup); + var isClassBased = animationEvent == 'addClass' || animationEvent == 'removeClass'; + var ngAnimateState = element.data(NG_ANIMATE_STATE) || {}; + + //skip the animation if animations are disabled, a parent is already being animated, + //the element is not currently attached to the document body or then completely close + //the animation if any matching animations are not found at all. + //NOTE: IE8 + IE9 should close properly (run closeAnimation()) in case a NO animation is not found. + if (animationsDisabled(element, parentElement) || matches.length === 0) { + domOperation(); + closeAnimation(); + return; + } + + var animations = []; + //only add animations if the currently running animation is not structural + //or if there is no animation running at all + if(!ngAnimateState.running || !(isClassBased && ngAnimateState.structural)) { + forEach(matches, function(animation) { + //add the animation to the queue to if it is allowed to be cancelled + if(!animation.allowCancel || animation.allowCancel(element, animationEvent, className)) { + var beforeFn, afterFn = animation[animationEvent]; + + //Special case for a leave animation since there is no point in performing an + //animation on a element node that has already been removed from the DOM + if(animationEvent == 'leave') { + beforeFn = afterFn; + afterFn = null; //this must be falsy so that the animation is skipped for leave + } else { + beforeFn = animation['before' + animationEvent.charAt(0).toUpperCase() + animationEvent.substr(1)]; + } + animations.push({ + before : beforeFn, + after : afterFn + }); + } + }); + } + + //this would mean that an animation was not allowed so let the existing + //animation do it's thing and close this one early + if(animations.length === 0) { + domOperation(); + fireDoneCallbackAsync(); + return; + } + + if(ngAnimateState.running) { + //if an animation is currently running on the element then lets take the steps + //to cancel that animation and fire any required callbacks + $timeout.cancel(ngAnimateState.closeAnimationTimeout); + cleanup(element); + cancelAnimations(ngAnimateState.animations); + (ngAnimateState.done || noop)(true); + } + + //There is no point in perform a class-based animation if the element already contains + //(on addClass) or doesn't contain (on removeClass) the className being animated. + //The reason why this is being called after the previous animations are cancelled + //is so that the CSS classes present on the element can be properly examined. + if((animationEvent == 'addClass' && element.hasClass(className)) || + (animationEvent == 'removeClass' && !element.hasClass(className))) { + domOperation(); + fireDoneCallbackAsync(); + return; + } + + //the ng-animate class does nothing, but it's here to allow for + //parent animations to find and cancel child animations when needed + element.addClass(NG_ANIMATE_CLASS_NAME); + + element.data(NG_ANIMATE_STATE, { + running:true, + structural:!isClassBased, + animations:animations, + done:onBeforeAnimationsComplete + }); + + //first we run the before animations and when all of those are complete + //then we perform the DOM operation and run the next set of animations + invokeRegisteredAnimationFns(animations, 'before', onBeforeAnimationsComplete); + + function onBeforeAnimationsComplete(cancelled) { + domOperation(); + if(cancelled === true) { + closeAnimation(); + return; + } + + //set the done function to the final done function + //so that the DOM event won't be executed twice by accident + //if the after animation is cancelled as well + var data = element.data(NG_ANIMATE_STATE); + if(data) { + data.done = closeAnimation; + element.data(NG_ANIMATE_STATE, data); + } + invokeRegisteredAnimationFns(animations, 'after', closeAnimation); + } + + function invokeRegisteredAnimationFns(animations, phase, allAnimationFnsComplete) { + var endFnName = phase + 'End'; + forEach(animations, function(animation, index) { + var animationPhaseCompleted = function() { + progress(index, phase); + }; + + //there are no before functions for enter + move since the DOM + //operations happen before the performAnimation method fires + if(phase == 'before' && (animationEvent == 'enter' || animationEvent == 'move')) { + animationPhaseCompleted(); + return; + } + + if(animation[phase]) { + animation[endFnName] = isClassBased ? + animation[phase](element, className, animationPhaseCompleted) : + animation[phase](element, animationPhaseCompleted); + } else { + animationPhaseCompleted(); + } + }); + + function progress(index, phase) { + var phaseCompletionFlag = phase + 'Complete'; + var currentAnimation = animations[index]; + currentAnimation[phaseCompletionFlag] = true; + (currentAnimation[endFnName] || noop)(); + + for(var i=0;i<animations.length;i++) { + if(!animations[i][phaseCompletionFlag]) return; + } + + allAnimationFnsComplete(); + } + } + + function fireDoneCallbackAsync() { + doneCallback && $timeout(doneCallback, 0, false); + } + + function closeAnimation() { + if(!closeAnimation.hasBeenRun) { + closeAnimation.hasBeenRun = true; + var data = element.data(NG_ANIMATE_STATE); + if(data) { + /* only structural animations wait for reflow before removing an + animation, but class-based animations don't. An example of this + failing would be when a parent HTML tag has a ng-class attribute + causing ALL directives below to skip animations during the digest */ + if(isClassBased) { + cleanup(element); + } else { + data.closeAnimationTimeout = $timeout(function() { + cleanup(element); + }, 0, false); + element.data(NG_ANIMATE_STATE, data); + } + } + fireDoneCallbackAsync(); + } + } + } + + function cancelChildAnimations(element) { + var node = element[0]; + if(node.nodeType != ELEMENT_NODE) { + return; + } + + forEach(node.querySelectorAll('.' + NG_ANIMATE_CLASS_NAME), function(element) { + element = angular.element(element); + var data = element.data(NG_ANIMATE_STATE); + if(data) { + cancelAnimations(data.animations); + cleanup(element); + } + }); + } + + function cancelAnimations(animations) { + var isCancelledFlag = true; + forEach(animations, function(animation) { + if(!animations['beforeComplete']) { + (animation.beforeEnd || noop)(isCancelledFlag); + } + if(!animations['afterComplete']) { + (animation.afterEnd || noop)(isCancelledFlag); + } + }); + } + + function cleanup(element) { + if(element[0] == $rootElement[0]) { + if(!rootAnimateState.disabled) { + rootAnimateState.running = false; + rootAnimateState.structural = false; + } + } else { + element.removeClass(NG_ANIMATE_CLASS_NAME); + element.removeData(NG_ANIMATE_STATE); + } + } + + function animationsDisabled(element, parentElement) { + if (rootAnimateState.disabled) return true; + + if(element[0] == $rootElement[0]) { + return rootAnimateState.disabled || rootAnimateState.running; + } + + do { + //the element did not reach the root element which means that it + //is not apart of the DOM. Therefore there is no reason to do + //any animations on it + if(parentElement.length === 0) break; + + var isRoot = parentElement[0] == $rootElement[0]; + var state = isRoot ? rootAnimateState : parentElement.data(NG_ANIMATE_STATE); + var result = state && (!!state.disabled || !!state.running); + if(isRoot || result) { + return result; + } + + if(isRoot) return true; + } + while(parentElement = parentElement.parent()); + + return true; + } + }]); + + $animateProvider.register('', ['$window', '$sniffer', '$timeout', function($window, $sniffer, $timeout) { + // Detect proper transitionend/animationend event names. + var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT; + + // If unprefixed events are not supported but webkit-prefixed are, use the latter. + // Otherwise, just use W3C names, browsers not supporting them at all will just ignore them. + // Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend` + // but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`. + // Register both events in case `window.onanimationend` is not supported because of that, + // do the same for `transitionend` as Safari is likely to exhibit similar behavior. + // Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit + // therefore there is no reason to test anymore for other vendor prefixes: http://caniuse.com/#search=transition + if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) { + CSS_PREFIX = '-webkit-'; + TRANSITION_PROP = 'WebkitTransition'; + TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend'; + } else { + TRANSITION_PROP = 'transition'; + TRANSITIONEND_EVENT = 'transitionend'; + } + + if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) { + CSS_PREFIX = '-webkit-'; + ANIMATION_PROP = 'WebkitAnimation'; + ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend'; + } else { + ANIMATION_PROP = 'animation'; + ANIMATIONEND_EVENT = 'animationend'; + } + + var DURATION_KEY = 'Duration'; + var PROPERTY_KEY = 'Property'; + var DELAY_KEY = 'Delay'; + var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount'; + var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey'; + var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data'; + var NG_ANIMATE_FALLBACK_CLASS_NAME = 'ng-animate-start'; + var NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME = 'ng-animate-active'; + + var lookupCache = {}; + var parentCounter = 0; + + var animationReflowQueue = [], animationTimer, timeOut = false; + function afterReflow(callback) { + animationReflowQueue.push(callback); + $timeout.cancel(animationTimer); + animationTimer = $timeout(function() { + forEach(animationReflowQueue, function(fn) { + fn(); + }); + animationReflowQueue = []; + animationTimer = null; + lookupCache = {}; + }, 10, false); + } + + function applyStyle(node, style) { + var oldStyle = node.getAttribute('style') || ''; + var newStyle = (oldStyle.length > 0 ? '; ' : '') + style; + node.setAttribute('style', newStyle); + return oldStyle; + } + + function getElementAnimationDetails(element, cacheKey) { + var data = cacheKey ? lookupCache[cacheKey] : null; + if(!data) { + var transitionDuration = 0; + var transitionDelay = 0; + var animationDuration = 0; + var animationDelay = 0; + var transitionDelayStyle; + var animationDelayStyle; + var transitionDurationStyle; + var transitionPropertyStyle; + + //we want all the styles defined before and after + forEach(element, function(element) { + if (element.nodeType == ELEMENT_NODE) { + var elementStyles = $window.getComputedStyle(element) || {}; + + transitionDurationStyle = elementStyles[TRANSITION_PROP + DURATION_KEY]; + + transitionDuration = Math.max(parseMaxTime(transitionDurationStyle), transitionDuration); + + transitionPropertyStyle = elementStyles[TRANSITION_PROP + PROPERTY_KEY]; + + transitionDelayStyle = elementStyles[TRANSITION_PROP + DELAY_KEY]; + + transitionDelay = Math.max(parseMaxTime(transitionDelayStyle), transitionDelay); + + animationDelayStyle = elementStyles[ANIMATION_PROP + DELAY_KEY]; + + animationDelay = Math.max(parseMaxTime(animationDelayStyle), animationDelay); + + var aDuration = parseMaxTime(elementStyles[ANIMATION_PROP + DURATION_KEY]); + + if(aDuration > 0) { + aDuration *= parseInt(elementStyles[ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY], 10) || 1; + } + + animationDuration = Math.max(aDuration, animationDuration); + } + }); + data = { + total : 0, + transitionPropertyStyle: transitionPropertyStyle, + transitionDurationStyle: transitionDurationStyle, + transitionDelayStyle: transitionDelayStyle, + transitionDelay: transitionDelay, + transitionDuration: transitionDuration, + animationDelayStyle: animationDelayStyle, + animationDelay: animationDelay, + animationDuration: animationDuration + }; + if(cacheKey) { + lookupCache[cacheKey] = data; + } + } + return data; + } + + function parseMaxTime(str) { + var maxValue = 0; + var values = angular.isString(str) ? + str.split(/\s*,\s*/) : + []; + forEach(values, function(value) { + maxValue = Math.max(parseFloat(value) || 0, maxValue); + }); + return maxValue; + } + + function getCacheKey(element) { + var parentElement = element.parent(); + var parentID = parentElement.data(NG_ANIMATE_PARENT_KEY); + if(!parentID) { + parentElement.data(NG_ANIMATE_PARENT_KEY, ++parentCounter); + parentID = parentCounter; + } + return parentID + '-' + element[0].className; + } + + function animateSetup(element, className) { + var cacheKey = getCacheKey(element); + var eventCacheKey = cacheKey + ' ' + className; + var stagger = {}; + var ii = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0; + + if(ii > 0) { + var staggerClassName = className + '-stagger'; + var staggerCacheKey = cacheKey + ' ' + staggerClassName; + var applyClasses = !lookupCache[staggerCacheKey]; + + applyClasses && element.addClass(staggerClassName); + + stagger = getElementAnimationDetails(element, staggerCacheKey); + + applyClasses && element.removeClass(staggerClassName); + } + + element.addClass(className); + + var timings = getElementAnimationDetails(element, eventCacheKey); + + /* there is no point in performing a reflow if the animation + timeout is empty (this would cause a flicker bug normally + in the page. There is also no point in performing an animation + that only has a delay and no duration */ + var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration); + if(maxDuration === 0) { + element.removeClass(className); + return false; + } + + var node = element[0]; + //temporarily disable the transition so that the enter styles + //don't animate twice (this is here to avoid a bug in Chrome/FF). + var activeClassName = ''; + if(timings.transitionDuration > 0) { + element.addClass(NG_ANIMATE_FALLBACK_CLASS_NAME); + activeClassName += NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME + ' '; + node.style[TRANSITION_PROP + PROPERTY_KEY] = 'none'; + } + + forEach(className.split(' '), function(klass, i) { + activeClassName += (i > 0 ? ' ' : '') + klass + '-active'; + }); + + element.data(NG_ANIMATE_CSS_DATA_KEY, { + className : className, + activeClassName : activeClassName, + maxDuration : maxDuration, + classes : className + ' ' + activeClassName, + timings : timings, + stagger : stagger, + ii : ii + }); + + return true; + } + + function animateRun(element, className, activeAnimationComplete) { + var data = element.data(NG_ANIMATE_CSS_DATA_KEY); + if(!element.hasClass(className) || !data) { + activeAnimationComplete(); + return; + } + + var node = element[0]; + var timings = data.timings; + var stagger = data.stagger; + var maxDuration = data.maxDuration; + var activeClassName = data.activeClassName; + var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * 1000; + var startTime = Date.now(); + var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT; + var formerStyle; + var ii = data.ii; + + var applyFallbackStyle, style = ''; + if(timings.transitionDuration > 0) { + node.style[TRANSITION_PROP + PROPERTY_KEY] = ''; + + var propertyStyle = timings.transitionPropertyStyle; + if(propertyStyle.indexOf('all') == -1) { + applyFallbackStyle = true; + var fallbackProperty = $sniffer.msie ? '-ms-zoom' : 'clip'; + style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ', ' + fallbackProperty + '; '; + style += CSS_PREFIX + 'transition-duration: ' + timings.transitionDurationStyle + ', ' + timings.transitionDuration + 's; '; + } + } + + if(ii > 0) { + if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) { + var delayStyle = timings.transitionDelayStyle; + if(applyFallbackStyle) { + delayStyle += ', ' + timings.transitionDelay + 's'; + } + + style += CSS_PREFIX + 'transition-delay: ' + + prepareStaggerDelay(delayStyle, stagger.transitionDelay, ii) + '; '; + } + + if(stagger.animationDelay > 0 && stagger.animationDuration === 0) { + style += CSS_PREFIX + 'animation-delay: ' + + prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, ii) + '; '; + } + } + + if(style.length > 0) { + formerStyle = applyStyle(node, style); + } + + element.on(css3AnimationEvents, onAnimationProgress); + element.addClass(activeClassName); + + // This will automatically be called by $animate so + // there is no need to attach this internally to the + // timeout done method. + return function onEnd(cancelled) { + element.off(css3AnimationEvents, onAnimationProgress); + element.removeClass(activeClassName); + animateClose(element, className); + if(formerStyle != null) { + formerStyle.length > 0 ? + node.setAttribute('style', formerStyle) : + node.removeAttribute('style'); + } + }; + + function onAnimationProgress(event) { + event.stopPropagation(); + var ev = event.originalEvent || event; + var timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now(); + /* $manualTimeStamp is a mocked timeStamp value which is set + * within browserTrigger(). This is only here so that tests can + * mock animations properly. Real events fallback to event.timeStamp, + * or, if they don't, then a timeStamp is automatically created for them. + * We're checking to see if the timeStamp surpasses the expected delay, + * but we're using elapsedTime instead of the timeStamp on the 2nd + * pre-condition since animations sometimes close off early */ + if(Math.max(timeStamp - startTime, 0) >= maxDelayTime && ev.elapsedTime >= maxDuration) { + activeAnimationComplete(); + } + } + } + + function prepareStaggerDelay(delayStyle, staggerDelay, index) { + var style = ''; + forEach(delayStyle.split(','), function(val, i) { + style += (i > 0 ? ',' : '') + + (index * staggerDelay + parseInt(val, 10)) + 's'; + }); + return style; + } + + function animateBefore(element, className) { + if(animateSetup(element, className)) { + return function(cancelled) { + cancelled && animateClose(element, className); + }; + } + } + + function animateAfter(element, className, afterAnimationComplete) { + if(element.data(NG_ANIMATE_CSS_DATA_KEY)) { + return animateRun(element, className, afterAnimationComplete); + } else { + animateClose(element, className); + afterAnimationComplete(); + } + } + + function animate(element, className, animationComplete) { + //If the animateSetup function doesn't bother returning a + //cancellation function then it means that there is no animation + //to perform at all + var preReflowCancellation = animateBefore(element, className); + if(!preReflowCancellation) { + animationComplete(); + return; + } + + //There are two cancellation functions: one is before the first + //reflow animation and the second is during the active state + //animation. The first function will take care of removing the + //data from the element which will not make the 2nd animation + //happen in the first place + var cancel = preReflowCancellation; + afterReflow(function() { + //once the reflow is complete then we point cancel to + //the new cancellation function which will remove all of the + //animation properties from the active animation + cancel = animateAfter(element, className, animationComplete); + }); + + return function(cancelled) { + (cancel || noop)(cancelled); + }; + } + + function animateClose(element, className) { + element.removeClass(className); + element.removeClass(NG_ANIMATE_FALLBACK_CLASS_NAME); + element.removeData(NG_ANIMATE_CSS_DATA_KEY); + } + + return { + allowCancel : function(element, animationEvent, className) { + //always cancel the current animation if it is a + //structural animation + var oldClasses = (element.data(NG_ANIMATE_CSS_DATA_KEY) || {}).classes; + if(!oldClasses || ['enter','leave','move'].indexOf(animationEvent) >= 0) { + return true; + } + + var parentElement = element.parent(); + var clone = angular.element(element[0].cloneNode()); + + //make the element super hidden and override any CSS style values + clone.attr('style','position:absolute; top:-9999px; left:-9999px'); + clone.removeAttr('id'); + clone.html(''); + + forEach(oldClasses.split(' '), function(klass) { + clone.removeClass(klass); + }); + + var suffix = animationEvent == 'addClass' ? '-add' : '-remove'; + clone.addClass(suffixClasses(className, suffix)); + parentElement.append(clone); + + var timings = getElementAnimationDetails(clone); + clone.remove(); + + return Math.max(timings.transitionDuration, timings.animationDuration) > 0; + }, + + enter : function(element, animationCompleted) { + return animate(element, 'ng-enter', animationCompleted); + }, + + leave : function(element, animationCompleted) { + return animate(element, 'ng-leave', animationCompleted); + }, + + move : function(element, animationCompleted) { + return animate(element, 'ng-move', animationCompleted); + }, + + beforeAddClass : function(element, className, animationCompleted) { + var cancellationMethod = animateBefore(element, suffixClasses(className, '-add')); + if(cancellationMethod) { + afterReflow(animationCompleted); + return cancellationMethod; + } + animationCompleted(); + }, + + addClass : function(element, className, animationCompleted) { + return animateAfter(element, suffixClasses(className, '-add'), animationCompleted); + }, + + beforeRemoveClass : function(element, className, animationCompleted) { + var cancellationMethod = animateBefore(element, suffixClasses(className, '-remove')); + if(cancellationMethod) { + afterReflow(animationCompleted); + return cancellationMethod; + } + animationCompleted(); + }, + + removeClass : function(element, className, animationCompleted) { + return animateAfter(element, suffixClasses(className, '-remove'), animationCompleted); + } + }; + + function suffixClasses(classes, suffix) { + var className = ''; + classes = angular.isArray(classes) ? classes : classes.split(/\s+/); + forEach(classes, function(klass, i) { + if(klass && klass.length > 0) { + className += (i > 0 ? ' ' : '') + klass + suffix; + } + }); + return className; + } + }]); + }]); + + +})(window, window.angular); Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-cookies.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-cookies.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-cookies.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,202 @@ +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/** + * @ngdoc overview + * @name ngCookies + * @description + * + * # ngCookies + * + * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies. + * + * {@installModule cookies} + * + * <div doc-module-components="ngCookies"></div> + * + * See {@link ngCookies.$cookies `$cookies`} and + * {@link ngCookies.$cookieStore `$cookieStore`} for usage. + */ + + +angular.module('ngCookies', ['ng']). + /** + * @ngdoc object + * @name ngCookies.$cookies + * @requires $browser + * + * @description + * Provides read/write access to browser's cookies. + * + * Only a simple Object is exposed and by adding or removing properties to/from + * this object, new cookies are created/deleted at the end of current $eval. + * + * Requires the {@link ngCookies `ngCookies`} module to be installed. + * + * @example + <doc:example> + <doc:source> + <script> + function ExampleController($cookies) { + // Retrieving a cookie + var favoriteCookie = $cookies.myFavorite; + // Setting a cookie + $cookies.myFavorite = 'oatmeal'; + } + </script> + </doc:source> + </doc:example> + */ + factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) { + var cookies = {}, + lastCookies = {}, + lastBrowserCookies, + runEval = false, + copy = angular.copy, + isUndefined = angular.isUndefined; + + //creates a poller fn that copies all cookies from the $browser to service & inits the service + $browser.addPollFn(function() { + var currentCookies = $browser.cookies(); + if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl + lastBrowserCookies = currentCookies; + copy(currentCookies, lastCookies); + copy(currentCookies, cookies); + if (runEval) $rootScope.$apply(); + } + })(); + + runEval = true; + + //at the end of each eval, push cookies + //TODO: this should happen before the "delayed" watches fire, because if some cookies are not + // strings or browser refuses to store some cookies, we update the model in the push fn. + $rootScope.$watch(push); + + return cookies; + + + /** + * Pushes all the cookies from the service to the browser and verifies if all cookies were + * stored. + */ + function push() { + var name, + value, + browserCookies, + updated; + + //delete any cookies deleted in $cookies + for (name in lastCookies) { + if (isUndefined(cookies[name])) { + $browser.cookies(name, undefined); + } + } + + //update all cookies updated in $cookies + for(name in cookies) { + value = cookies[name]; + if (!angular.isString(value)) { + if (angular.isDefined(lastCookies[name])) { + cookies[name] = lastCookies[name]; + } else { + delete cookies[name]; + } + } else if (value !== lastCookies[name]) { + $browser.cookies(name, value); + updated = true; + } + } + + //verify what was actually stored + if (updated){ + updated = false; + browserCookies = $browser.cookies(); + + for (name in cookies) { + if (cookies[name] !== browserCookies[name]) { + //delete or reset all cookies that the browser dropped from $cookies + if (isUndefined(browserCookies[name])) { + delete cookies[name]; + } else { + cookies[name] = browserCookies[name]; + } + updated = true; + } + } + } + } + }]). + + + /** + * @ngdoc object + * @name ngCookies.$cookieStore + * @requires $cookies + * + * @description + * Provides a key-value (string-object) storage, that is backed by session cookies. + * Objects put or retrieved from this storage are automatically serialized or + * deserialized by angular's toJson/fromJson. + * + * Requires the {@link ngCookies `ngCookies`} module to be installed. + * + * @example + */ + factory('$cookieStore', ['$cookies', function($cookies) { + + return { + /** + * @ngdoc method + * @name ngCookies.$cookieStore#get + * @methodOf ngCookies.$cookieStore + * + * @description + * Returns the value of given cookie key + * + * @param {string} key Id to use for lookup. + * @returns {Object} Deserialized cookie value. + */ + get: function(key) { + var value = $cookies[key]; + return value ? angular.fromJson(value) : value; + }, + + /** + * @ngdoc method + * @name ngCookies.$cookieStore#put + * @methodOf ngCookies.$cookieStore + * + * @description + * Sets a value for given cookie key + * + * @param {string} key Id for the `value`. + * @param {Object} value Value to be stored. + */ + put: function(key, value) { + $cookies[key] = angular.toJson(value); + }, + + /** + * @ngdoc method + * @name ngCookies.$cookieStore#remove + * @methodOf ngCookies.$cookieStore + * + * @description + * Remove given cookie + * + * @param {string} key Id of the key-value pair to delete. + */ + remove: function(key) { + delete $cookies[key]; + } + }; + + }]); + + +})(window, window.angular); Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-loader.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-loader.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-loader.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,323 @@ +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + */ + +( + +/** + * @ngdoc interface + * @name angular.Module + * @description + * + * Interface for configuring angular {@link angular.module modules}. + */ + +function setupModuleLoader(window) { + + var $injectorMinErr = minErr('$injector'); + + function ensure(obj, name, factory) { + return obj[name] || (obj[name] = factory()); + } + + return ensure(ensure(window, 'angular', Object), 'module', function() { + /** @type {Object.<string, angular.Module>} */ + var modules = {}; + + /** + * @ngdoc function + * @name angular.module + * @description + * + * The `angular.module` is a global place for creating, registering and retrieving Angular + * modules. + * All modules (angular core or 3rd party) that should be available to an application must be + * registered using this mechanism. + * + * When passed two or more arguments, a new module is created. If passed only one argument, an + * existing module (the name passed as the first argument to `module`) is retrieved. + * + * + * # Module + * + * A module is a collection of services, directives, filters, and configuration information. + * `angular.module` is used to configure the {@link AUTO.$injector $injector}. + * + * <pre> + * // Create a new module + * var myModule = angular.module('myModule', []); + * + * // register a new service + * myModule.value('appName', 'MyCoolApp'); + * + * // configure existing services inside initialization blocks. + * myModule.config(function($locationProvider) {'use strict'; + * // Configure existing providers + * $locationProvider.hashPrefix('!'); + * }); + * </pre> + * + * Then you can create an injector and load your modules like this: + * + * <pre> + * var injector = angular.injector(['ng', 'MyModule']) + * </pre> + * + * However it's more likely that you'll just use + * {@link ng.directive:ngApp ngApp} or + * {@link angular.bootstrap} to simplify this process for you. + * + * @param {!string} name The name of the module to create or retrieve. + * @param {Array.<string>=} requires If specified then new module is being created. If + * unspecified then the the module is being retrieved for further configuration. + * @param {Function} configFn Optional configuration function for the module. Same as + * {@link angular.Module#methods_config Module#config()}. + * @returns {module} new module with the {@link angular.Module} api. + */ + return function module(name, requires, configFn) { + assertNotHasOwnProperty(name, 'module'); + if (requires && modules.hasOwnProperty(name)) { + modules[name] = null; + } + return ensure(modules, name, function() { + if (!requires) { + throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + + "the module name or forgot to load it. If registering a module ensure that you " + + "specify the dependencies as the second argument.", name); + } + + /** @type {!Array.<Array.<*>>} */ + var invokeQueue = []; + + /** @type {!Array.<Function>} */ + var runBlocks = []; + + var config = invokeLater('$injector', 'invoke'); + + /** @type {angular.Module} */ + var moduleInstance = { + // Private state + _invokeQueue: invokeQueue, + _runBlocks: runBlocks, + + /** + * @ngdoc property + * @name angular.Module#requires + * @propertyOf angular.Module + * @returns {Array.<string>} List of module names which must be loaded before this module. + * @description + * Holds the list of modules which the injector will load before the current module is + * loaded. + */ + requires: requires, + + /** + * @ngdoc property + * @name angular.Module#name + * @propertyOf angular.Module + * @returns {string} Name of the module. + * @description + */ + name: name, + + + /** + * @ngdoc method + * @name angular.Module#provider + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} providerType Construction function for creating new instance of the + * service. + * @description + * See {@link AUTO.$provide#provider $provide.provider()}. + */ + provider: invokeLater('$provide', 'provider'), + + /** + * @ngdoc method + * @name angular.Module#factory + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} providerFunction Function for creating new instance of the service. + * @description + * See {@link AUTO.$provide#factory $provide.factory()}. + */ + factory: invokeLater('$provide', 'factory'), + + /** + * @ngdoc method + * @name angular.Module#service + * @methodOf angular.Module + * @param {string} name service name + * @param {Function} constructor A constructor function that will be instantiated. + * @description + * See {@link AUTO.$provide#service $provide.service()}. + */ + service: invokeLater('$provide', 'service'), + + /** + * @ngdoc method + * @name angular.Module#value + * @methodOf angular.Module + * @param {string} name service name + * @param {*} object Service instance object. + * @description + * See {@link AUTO.$provide#value $provide.value()}. + */ + value: invokeLater('$provide', 'value'), + + /** + * @ngdoc method + * @name angular.Module#constant + * @methodOf angular.Module + * @param {string} name constant name + * @param {*} object Constant value. + * @description + * Because the constant are fixed, they get applied before other provide methods. + * See {@link AUTO.$provide#constant $provide.constant()}. + */ + constant: invokeLater('$provide', 'constant', 'unshift'), + + /** + * @ngdoc method + * @name angular.Module#animation + * @methodOf angular.Module + * @param {string} name animation name + * @param {Function} animationFactory Factory function for creating new instance of an + * animation. + * @description + * + * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. + * + * + * Defines an animation hook that can be later used with + * {@link ngAnimate.$animate $animate} service and directives that use this service. + * + * <pre> + * module.animation('.animation-name', function($inject1, $inject2) { + * return { + * eventName : function(element, done) { + * //code to run the animation + * //once complete, then run done() + * return function cancellationFunction(element) { + * //code to cancel the animation + * } + * } + * } + * }) + * </pre> + * + * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and + * {@link ngAnimate ngAnimate module} for more information. + */ + animation: invokeLater('$animateProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#filter + * @methodOf angular.Module + * @param {string} name Filter name. + * @param {Function} filterFactory Factory function for creating new instance of filter. + * @description + * See {@link ng.$filterProvider#register $filterProvider.register()}. + */ + filter: invokeLater('$filterProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#controller + * @methodOf angular.Module + * @param {string|Object} name Controller name, or an object map of controllers where the + * keys are the names and the values are the constructors. + * @param {Function} constructor Controller constructor function. + * @description + * See {@link ng.$controllerProvider#register $controllerProvider.register()}. + */ + controller: invokeLater('$controllerProvider', 'register'), + + /** + * @ngdoc method + * @name angular.Module#directive + * @methodOf angular.Module + * @param {string|Object} name Directive name, or an object map of directives where the + * keys are the names and the values are the factories. + * @param {Function} directiveFactory Factory function for creating new instance of + * directives. + * @description + * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}. + */ + directive: invokeLater('$compileProvider', 'directive'), + + /** + * @ngdoc method + * @name angular.Module#config + * @methodOf angular.Module + * @param {Function} configFn Execute this function on module load. Useful for service + * configuration. + * @description + * Use this method to register work which needs to be performed on module loading. + */ + config: config, + + /** + * @ngdoc method + * @name angular.Module#run + * @methodOf angular.Module + * @param {Function} initializationFn Execute this function after injector creation. + * Useful for application initialization. + * @description + * Use this method to register work which should be performed when the injector is done + * loading all modules. + */ + run: function(block) { + runBlocks.push(block); + return this; + } + }; + + if (configFn) { + config(configFn); + } + + return moduleInstance; + + /** + * @param {string} provider + * @param {string} method + * @param {String=} insertMethod + * @returns {angular.Module} + */ + function invokeLater(provider, method, insertMethod) { + return function() { + invokeQueue[insertMethod || 'push']([provider, method, arguments]); + return moduleInstance; + }; + } + }); + }; + }); + +} + +)(window); + +/** + * Closure compiler type information + * + * @typedef { { + * requires: !Array.<string>, + * invokeQueue: !Array.<Array.<*>>, + * + * service: function(string, Function):angular.Module, + * factory: function(string, Function):angular.Module, + * value: function(string, *):angular.Module, + * + * filter: function(string, Function):angular.Module, + * + * init: function(Function):angular.Module + * } } + */ +angular.Module; + Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-mocks.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-mocks.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-mocks.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,2130 @@ +'use strict'; + +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + * + * TODO(vojta): wrap whole file into closure during build + */ + +/** + * @ngdoc overview + * @name angular.mock + * @description + * + * Namespace from 'angular-mocks.js' which contains testing related code. + */ +angular.mock = {}; + +/** + * ! This is a private undocumented service ! + * + * @name ngMock.$browser + * + * @description + * This service is a mock implementation of {@link ng.$browser}. It provides fake + * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr, + * cookies, etc... + * + * The api of this service is the same as that of the real {@link ng.$browser $browser}, except + * that there are several helper methods available which can be used in tests. + */ +angular.mock.$BrowserProvider = function() { + this.$get = function() { + return new angular.mock.$Browser(); + }; +}; + +angular.mock.$Browser = function() { + var self = this; + + this.isMock = true; + self.$$url = "http://server/"; + self.$$lastUrl = self.$$url; // used by url polling fn + self.pollFns = []; + + // TODO(vojta): remove this temporary api + self.$$completeOutstandingRequest = angular.noop; + self.$$incOutstandingRequestCount = angular.noop; + + + // register url polling fn + + self.onUrlChange = function(listener) { + self.pollFns.push( + function() { + if (self.$$lastUrl != self.$$url) { + self.$$lastUrl = self.$$url; + listener(self.$$url); + } + } + ); + + return listener; + }; + + self.cookieHash = {}; + self.lastCookieHash = {}; + self.deferredFns = []; + self.deferredNextId = 0; + + self.defer = function(fn, delay) { + delay = delay || 0; + self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId}); + self.deferredFns.sort(function(a,b){ return a.time - b.time;}); + return self.deferredNextId++; + }; + + + /** + * @name ngMock.$browser#defer.now + * @propertyOf ngMock.$browser + * + * @description + * Current milliseconds mock time. + */ + self.defer.now = 0; + + + self.defer.cancel = function(deferId) { + var fnIndex; + + angular.forEach(self.deferredFns, function(fn, index) { + if (fn.id === deferId) fnIndex = index; + }); + + if (fnIndex !== undefined) { + self.deferredFns.splice(fnIndex, 1); + return true; + } + + return false; + }; + + + /** + * @name ngMock.$browser#defer.flush + * @methodOf ngMock.$browser + * + * @description + * Flushes all pending requests and executes the defer callbacks. + * + * @param {number=} number of milliseconds to flush. See {@link #defer.now} + */ + self.defer.flush = function(delay) { + if (angular.isDefined(delay)) { + self.defer.now += delay; + } else { + if (self.deferredFns.length) { + self.defer.now = self.deferredFns[self.deferredFns.length-1].time; + } else { + throw new Error('No deferred tasks to be flushed'); + } + } + + while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) { + self.deferredFns.shift().fn(); + } + }; + + self.$$baseHref = ''; + self.baseHref = function() { + return this.$$baseHref; + }; +}; +angular.mock.$Browser.prototype = { + +/** + * @name ngMock.$browser#poll + * @methodOf ngMock.$browser + * + * @description + * run all fns in pollFns + */ + poll: function poll() { + angular.forEach(this.pollFns, function(pollFn){ + pollFn(); + }); + }, + + addPollFn: function(pollFn) { + this.pollFns.push(pollFn); + return pollFn; + }, + + url: function(url, replace) { + if (url) { + this.$$url = url; + return this; + } + + return this.$$url; + }, + + cookies: function(name, value) { + if (name) { + if (angular.isUndefined(value)) { + delete this.cookieHash[name]; + } else { + if (angular.isString(value) && //strings only + value.length <= 4096) { //strict cookie storage limits + this.cookieHash[name] = value; + } + } + } else { + if (!angular.equals(this.cookieHash, this.lastCookieHash)) { + this.lastCookieHash = angular.copy(this.cookieHash); + this.cookieHash = angular.copy(this.cookieHash); + } + return this.cookieHash; + } + }, + + notifyWhenNoOutstandingRequests: function(fn) { + fn(); + } +}; + + +/** + * @ngdoc object + * @name ngMock.$exceptionHandlerProvider + * + * @description + * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors + * passed into the `$exceptionHandler`. + */ + +/** + * @ngdoc object + * @name ngMock.$exceptionHandler + * + * @description + * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed + * into it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration + * information. + * + * + * <pre> + * describe('$exceptionHandlerProvider', function() { + * + * it('should capture log messages and exceptions', function() { + * + * module(function($exceptionHandlerProvider) { + * $exceptionHandlerProvider.mode('log'); + * }); + * + * inject(function($log, $exceptionHandler, $timeout) { + * $timeout(function() { $log.log(1); }); + * $timeout(function() { $log.log(2); throw 'banana peel'; }); + * $timeout(function() { $log.log(3); }); + * expect($exceptionHandler.errors).toEqual([]); + * expect($log.assertEmpty()); + * $timeout.flush(); + * expect($exceptionHandler.errors).toEqual(['banana peel']); + * expect($log.log.logs).toEqual([[1], [2], [3]]); + * }); + * }); + * }); + * </pre> + */ + +angular.mock.$ExceptionHandlerProvider = function() { + var handler; + + /** + * @ngdoc method + * @name ngMock.$exceptionHandlerProvider#mode + * @methodOf ngMock.$exceptionHandlerProvider + * + * @description + * Sets the logging mode. + * + * @param {string} mode Mode of operation, defaults to `rethrow`. + * + * - `rethrow`: If any errors are passed into the handler in tests, it typically + * means that there is a bug in the application or test, so this mock will + * make these tests fail. + * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` + * mode stores an array of errors in `$exceptionHandler.errors`, to allow later + * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and + * {@link ngMock.$log#reset reset()} + */ + this.mode = function(mode) { + switch(mode) { + case 'rethrow': + handler = function(e) { + throw e; + }; + break; + case 'log': + var errors = []; + + handler = function(e) { + if (arguments.length == 1) { + errors.push(e); + } else { + errors.push([].slice.call(arguments, 0)); + } + }; + + handler.errors = errors; + break; + default: + throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!"); + } + }; + + this.$get = function() { + return handler; + }; + + this.mode('rethrow'); +}; + + +/** + * @ngdoc service + * @name ngMock.$log + * + * @description + * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays + * (one array per logging level). These arrays are exposed as `logs` property of each of the + * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`. + * + */ +angular.mock.$LogProvider = function() { + var debug = true; + + function concat(array1, array2, index) { + return array1.concat(Array.prototype.slice.call(array2, index)); + } + + this.debugEnabled = function(flag) { + if (angular.isDefined(flag)) { + debug = flag; + return this; + } else { + return debug; + } + }; + + this.$get = function () { + var $log = { + log: function() { $log.log.logs.push(concat([], arguments, 0)); }, + warn: function() { $log.warn.logs.push(concat([], arguments, 0)); }, + info: function() { $log.info.logs.push(concat([], arguments, 0)); }, + error: function() { $log.error.logs.push(concat([], arguments, 0)); }, + debug: function() { + if (debug) { + $log.debug.logs.push(concat([], arguments, 0)); + } + } + }; + + /** + * @ngdoc method + * @name ngMock.$log#reset + * @methodOf ngMock.$log + * + * @description + * Reset all of the logging arrays to empty. + */ + $log.reset = function () { + /** + * @ngdoc property + * @name ngMock.$log#log.logs + * @propertyOf ngMock.$log + * + * @description + * Array of messages logged using {@link ngMock.$log#log}. + * + * @example + * <pre> + * $log.log('Some Log'); + * var first = $log.log.logs.unshift(); + * </pre> + */ + $log.log.logs = []; + /** + * @ngdoc property + * @name ngMock.$log#info.logs + * @propertyOf ngMock.$log + * + * @description + * Array of messages logged using {@link ngMock.$log#info}. + * + * @example + * <pre> + * $log.info('Some Info'); + * var first = $log.info.logs.unshift(); + * </pre> + */ + $log.info.logs = []; + /** + * @ngdoc property + * @name ngMock.$log#warn.logs + * @propertyOf ngMock.$log + * + * @description + * Array of messages logged using {@link ngMock.$log#warn}. + * + * @example + * <pre> + * $log.warn('Some Warning'); + * var first = $log.warn.logs.unshift(); + * </pre> + */ + $log.warn.logs = []; + /** + * @ngdoc property + * @name ngMock.$log#error.logs + * @propertyOf ngMock.$log + * + * @description + * Array of messages logged using {@link ngMock.$log#error}. + * + * @example + * <pre> + * $log.log('Some Error'); + * var first = $log.error.logs.unshift(); + * </pre> + */ + $log.error.logs = []; + /** + * @ngdoc property + * @name ngMock.$log#debug.logs + * @propertyOf ngMock.$log + * + * @description + * Array of messages logged using {@link ngMock.$log#debug}. + * + * @example + * <pre> + * $log.debug('Some Error'); + * var first = $log.debug.logs.unshift(); + * </pre> + */ + $log.debug.logs = []; + }; + + /** + * @ngdoc method + * @name ngMock.$log#assertEmpty + * @methodOf ngMock.$log + * + * @description + * Assert that the all of the logging methods have no logged messages. If messages present, an + * exception is thrown. + */ + $log.assertEmpty = function() { + var errors = []; + angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) { + angular.forEach($log[logLevel].logs, function(log) { + angular.forEach(log, function (logItem) { + errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + + (logItem.stack || '')); + }); + }); + }); + if (errors.length) { + errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or "+ + "an expected log message was not checked and removed:"); + errors.push(''); + throw new Error(errors.join('\n---------\n')); + } + }; + + $log.reset(); + return $log; + }; +}; + + +/** + * @ngdoc service + * @name ngMock.$interval + * + * @description + * Mock implementation of the $interval service. + * + * Use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to + * move forward by `millis` milliseconds and trigger any functions scheduled to run in that + * time. + * + * @param {function()} fn A function that should be called repeatedly. + * @param {number} delay Number of milliseconds between each function call. + * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat + * indefinitely. + * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise + * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block. + * @returns {promise} A promise which will be notified on each iteration. + */ +angular.mock.$IntervalProvider = function() { + this.$get = ['$rootScope', '$q', + function($rootScope, $q) { + var repeatFns = [], + nextRepeatId = 0, + now = 0; + + var $interval = function(fn, delay, count, invokeApply) { + var deferred = $q.defer(), + promise = deferred.promise, + iteration = 0, + skipApply = (angular.isDefined(invokeApply) && !invokeApply); + + count = (angular.isDefined(count)) ? count : 0, + promise.then(null, null, fn); + + promise.$$intervalId = nextRepeatId; + + function tick() { + deferred.notify(iteration++); + + if (count > 0 && iteration >= count) { + var fnIndex; + deferred.resolve(iteration); + + angular.forEach(repeatFns, function(fn, index) { + if (fn.id === promise.$$intervalId) fnIndex = index; + }); + + if (fnIndex !== undefined) { + repeatFns.splice(fnIndex, 1); + } + } + + if (!skipApply) $rootScope.$apply(); + } + + repeatFns.push({ + nextTime:(now + delay), + delay: delay, + fn: tick, + id: nextRepeatId, + deferred: deferred + }); + repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); + + nextRepeatId++; + return promise; + }; + + $interval.cancel = function(promise) { + var fnIndex; + + angular.forEach(repeatFns, function(fn, index) { + if (fn.id === promise.$$intervalId) fnIndex = index; + }); + + if (fnIndex !== undefined) { + repeatFns[fnIndex].deferred.reject('canceled'); + repeatFns.splice(fnIndex, 1); + return true; + } + + return false; + }; + + /** + * @ngdoc method + * @name ngMock.$interval#flush + * @methodOf ngMock.$interval + * @description + * + * Runs interval tasks scheduled to be run in the next `millis` milliseconds. + * + * @param {number=} millis maximum timeout amount to flush up until. + * + * @return {number} The amount of time moved forward. + */ + $interval.flush = function(millis) { + now += millis; + while (repeatFns.length && repeatFns[0].nextTime <= now) { + var task = repeatFns[0]; + task.fn(); + task.nextTime += task.delay; + repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); + } + return millis; + }; + + return $interval; + }]; +}; + + +/* jshint -W101 */ +/* The R_ISO8061_STR regex is never going to fit into the 100 char limit! + * This directive should go inside the anonymous function but a bug in JSHint means that it would + * not be enacted early enough to prevent the warning. + */ +(function() { + var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; + + function jsonStringToDate(string) { + var match; + if (match = string.match(R_ISO8061_STR)) { + var date = new Date(0), + tzHour = 0, + tzMin = 0; + if (match[9]) { + tzHour = int(match[9] + match[10]); + tzMin = int(match[9] + match[11]); + } + date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3])); + date.setUTCHours(int(match[4]||0) - tzHour, + int(match[5]||0) - tzMin, + int(match[6]||0), + int(match[7]||0)); + return date; + } + return string; + } + + function int(str) { + return parseInt(str, 10); + } + + function padNumber(num, digits, trim) { + var neg = ''; + if (num < 0) { + neg = '-'; + num = -num; + } + num = '' + num; + while(num.length < digits) num = '0' + num; + if (trim) + num = num.substr(num.length - digits); + return neg + num; + } + + + /** + * @ngdoc object + * @name angular.mock.TzDate + * @description + * + * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`. + * + * Mock of the Date type which has its timezone specified via constructor arg. + * + * The main purpose is to create Date-like instances with timezone fixed to the specified timezone + * offset, so that we can test code that depends on local timezone settings without dependency on + * the time zone settings of the machine where the code is running. + * + * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored) + * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC* + * + * @example + * !!!! WARNING !!!!! + * This is not a complete Date object so only methods that were implemented can be called safely. + * To make matters worse, TzDate instances inherit stuff from Date via a prototype. + * + * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is + * incomplete we might be missing some non-standard methods. This can result in errors like: + * "Date.prototype.foo called on incompatible Object". + * + * <pre> + * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z'); + * newYearInBratislava.getTimezoneOffset() => -60; + * newYearInBratislava.getFullYear() => 2010; + * newYearInBratislava.getMonth() => 0; + * newYearInBratislava.getDate() => 1; + * newYearInBratislava.getHours() => 0; + * newYearInBratislava.getMinutes() => 0; + * newYearInBratislava.getSeconds() => 0; + * </pre> + * + */ + angular.mock.TzDate = function (offset, timestamp) { + var self = new Date(0); + if (angular.isString(timestamp)) { + var tsStr = timestamp; + + self.origDate = jsonStringToDate(timestamp); + + timestamp = self.origDate.getTime(); + if (isNaN(timestamp)) + throw { + name: "Illegal Argument", + message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string" + }; + } else { + self.origDate = new Date(timestamp); + } + + var localOffset = new Date(timestamp).getTimezoneOffset(); + self.offsetDiff = localOffset*60*1000 - offset*1000*60*60; + self.date = new Date(timestamp + self.offsetDiff); + + self.getTime = function() { + return self.date.getTime() - self.offsetDiff; + }; + + self.toLocaleDateString = function() { + return self.date.toLocaleDateString(); + }; + + self.getFullYear = function() { + return self.date.getFullYear(); + }; + + self.getMonth = function() { + return self.date.getMonth(); + }; + + self.getDate = function() { + return self.date.getDate(); + }; + + self.getHours = function() { + return self.date.getHours(); + }; + + self.getMinutes = function() { + return self.date.getMinutes(); + }; + + self.getSeconds = function() { + return self.date.getSeconds(); + }; + + self.getMilliseconds = function() { + return self.date.getMilliseconds(); + }; + + self.getTimezoneOffset = function() { + return offset * 60; + }; + + self.getUTCFullYear = function() { + return self.origDate.getUTCFullYear(); + }; + + self.getUTCMonth = function() { + return self.origDate.getUTCMonth(); + }; + + self.getUTCDate = function() { + return self.origDate.getUTCDate(); + }; + + self.getUTCHours = function() { + return self.origDate.getUTCHours(); + }; + + self.getUTCMinutes = function() { + return self.origDate.getUTCMinutes(); + }; + + self.getUTCSeconds = function() { + return self.origDate.getUTCSeconds(); + }; + + self.getUTCMilliseconds = function() { + return self.origDate.getUTCMilliseconds(); + }; + + self.getDay = function() { + return self.date.getDay(); + }; + + // provide this method only on browsers that already have it + if (self.toISOString) { + self.toISOString = function() { + return padNumber(self.origDate.getUTCFullYear(), 4) + '-' + + padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' + + padNumber(self.origDate.getUTCDate(), 2) + 'T' + + padNumber(self.origDate.getUTCHours(), 2) + ':' + + padNumber(self.origDate.getUTCMinutes(), 2) + ':' + + padNumber(self.origDate.getUTCSeconds(), 2) + '.' + + padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'; + }; + } + + //hide all methods not implemented in this mock that the Date prototype exposes + var unimplementedMethods = ['getUTCDay', + 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', + 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', + 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', + 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString', + 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf']; + + angular.forEach(unimplementedMethods, function(methodName) { + self[methodName] = function() { + throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock"); + }; + }); + + return self; + }; + + //make "tzDateInstance instanceof Date" return true + angular.mock.TzDate.prototype = Date.prototype; +})(); +/* jshint +W101 */ + +angular.mock.animate = angular.module('mock.animate', ['ng']) + + .config(['$provide', function($provide) { + + $provide.decorator('$animate', function($delegate) { + var animate = { + queue : [], + enabled : $delegate.enabled, + flushNext : function(name) { + var tick = animate.queue.shift(); + + if (!tick) throw new Error('No animation to be flushed'); + if(tick.method !== name) { + throw new Error('The next animation is not "' + name + + '", but is "' + tick.method + '"'); + } + tick.fn(); + return tick; + } + }; + + angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) { + animate[method] = function() { + var params = arguments; + animate.queue.push({ + method : method, + params : params, + element : angular.isElement(params[0]) && params[0], + parent : angular.isElement(params[1]) && params[1], + after : angular.isElement(params[2]) && params[2], + fn : function() { + $delegate[method].apply($delegate, params); + } + }); + }; + }); + + return animate; + }); + + }]); + + +/** + * @ngdoc function + * @name angular.mock.dump + * @description + * + * *NOTE*: this is not an injectable instance, just a globally available function. + * + * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for + * debugging. + * + * This method is also available on window, where it can be used to display objects on debug + * console. + * + * @param {*} object - any object to turn into string. + * @return {string} a serialized string of the argument + */ +angular.mock.dump = function(object) { + return serialize(object); + + function serialize(object) { + var out; + + if (angular.isElement(object)) { + object = angular.element(object); + out = angular.element('<div></div>'); + angular.forEach(object, function(element) { + out.append(angular.element(element).clone()); + }); + out = out.html(); + } else if (angular.isArray(object)) { + out = []; + angular.forEach(object, function(o) { + out.push(serialize(o)); + }); + out = '[ ' + out.join(', ') + ' ]'; + } else if (angular.isObject(object)) { + if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) { + out = serializeScope(object); + } else if (object instanceof Error) { + out = object.stack || ('' + object.name + ': ' + object.message); + } else { + // TODO(i): this prevents methods being logged, + // we should have a better way to serialize objects + out = angular.toJson(object, true); + } + } else { + out = String(object); + } + + return out; + } + + function serializeScope(scope, offset) { + offset = offset || ' '; + var log = [offset + 'Scope(' + scope.$id + '): {']; + for ( var key in scope ) { + if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) { + log.push(' ' + key + ': ' + angular.toJson(scope[key])); + } + } + var child = scope.$$childHead; + while(child) { + log.push(serializeScope(child, offset + ' ')); + child = child.$$nextSibling; + } + log.push('}'); + return log.join('\n' + offset); + } +}; + +/** + * @ngdoc object + * @name ngMock.$httpBackend + * @description + * Fake HTTP backend implementation suitable for unit testing applications that use the + * {@link ng.$http $http service}. + * + * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less + * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}. + * + * During unit testing, we want our unit tests to run quickly and have no external dependencies so + * we don’t want to send {@link https://developer.mozilla.org/en/xmlhttprequest XHR} or + * {@link http://en.wikipedia.org/wiki/JSONP JSONP} requests to a real server. All we really need is + * to verify whether a certain request has been sent or not, or alternatively just let the + * application make requests, respond with pre-trained responses and assert that the end result is + * what we expect it to be. + * + * This mock implementation can be used to respond with static or dynamic responses via the + * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc). + * + * When an Angular application needs some data from a server, it calls the $http service, which + * sends the request to a real server using $httpBackend service. With dependency injection, it is + * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify + * the requests and respond with some testing data without sending a request to real server. + * + * There are two ways to specify what test data should be returned as http responses by the mock + * backend when the code under test makes http requests: + * + * - `$httpBackend.expect` - specifies a request expectation + * - `$httpBackend.when` - specifies a backend definition + * + * + * # Request Expectations vs Backend Definitions + * + * Request expectations provide a way to make assertions about requests made by the application and + * to define responses for those requests. The test will fail if the expected requests are not made + * or they are made in the wrong order. + * + * Backend definitions allow you to define a fake backend for your application which doesn't assert + * if a particular request was made or not, it just returns a trained response if a request is made. + * The test will pass whether or not the request gets made during testing. + * + * + * <table class="table"> + * <tr><th width="220px"></th><th>Request expectations</th><th>Backend definitions</th></tr> + * <tr> + * <th>Syntax</th> + * <td>.expect(...).respond(...)</td> + * <td>.when(...).respond(...)</td> + * </tr> + * <tr> + * <th>Typical usage</th> + * <td>strict unit tests</td> + * <td>loose (black-box) unit testing</td> + * </tr> + * <tr> + * <th>Fulfills multiple requests</th> + * <td>NO</td> + * <td>YES</td> + * </tr> + * <tr> + * <th>Order of requests matters</th> + * <td>YES</td> + * <td>NO</td> + * </tr> + * <tr> + * <th>Request required</th> + * <td>YES</td> + * <td>NO</td> + * </tr> + * <tr> + * <th>Response required</th> + * <td>optional (see below)</td> + * <td>YES</td> + * </tr> + * </table> + * + * In cases where both backend definitions and request expectations are specified during unit + * testing, the request expectations are evaluated first. + * + * If a request expectation has no response specified, the algorithm will search your backend + * definitions for an appropriate response. + * + * If a request didn't match any expectation or if the expectation doesn't have the response + * defined, the backend definitions are evaluated in sequential order to see if any of them match + * the request. The response from the first matched definition is returned. + * + * + * # Flushing HTTP requests + * + * The $httpBackend used in production, always responds to requests with responses asynchronously. + * If we preserved this behavior in unit testing, we'd have to create async unit tests, which are + * hard to write, follow and maintain. At the same time the testing mock, can't respond + * synchronously because that would change the execution of the code under test. For this reason the + * mock $httpBackend has a `flush()` method, which allows the test to explicitly flush pending + * requests and thus preserving the async api of the backend, while allowing the test to execute + * synchronously. + * + * + * # Unit testing with mock $httpBackend + * The following code shows how to setup and use the mock backend in unit testing a controller. + * First we create the controller under test + * + <pre> + // The controller code + function MyController($scope, $http) { + var authToken; + + $http.get('/auth.py').success(function(data, status, headers) { + authToken = headers('A-Token'); + $scope.user = data; + }); + + $scope.saveMessage = function(message) { + var headers = { 'Authorization': authToken }; + $scope.status = 'Saving...'; + + $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) { + $scope.status = ''; + }).error(function() { + $scope.status = 'ERROR!'; + }); + }; + } + </pre> + * + * Now we setup the mock backend and create the test specs. + * + <pre> + // testing controller + describe('MyController', function() { + var $httpBackend, $rootScope, createController; + + beforeEach(inject(function($injector) { + // Set up the mock http service responses + $httpBackend = $injector.get('$httpBackend'); + // backend definition common for all tests + $httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'}); + + // Get hold of a scope (i.e. the root scope) + $rootScope = $injector.get('$rootScope'); + // The $controller service is used to create instances of controllers + var $controller = $injector.get('$controller'); + + createController = function() { + return $controller('MyController', {'$scope' : $rootScope }); + }; + })); + + + afterEach(function() { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + + it('should fetch authentication token', function() { + $httpBackend.expectGET('/auth.py'); + var controller = createController(); + $httpBackend.flush(); + }); + + + it('should send msg to server', function() { + var controller = createController(); + $httpBackend.flush(); + + // now you don’t care about the authentication, but + // the controller will still send the request and + // $httpBackend will respond without you having to + // specify the expectation and response for this request + + $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, ''); + $rootScope.saveMessage('message content'); + expect($rootScope.status).toBe('Saving...'); + $httpBackend.flush(); + expect($rootScope.status).toBe(''); + }); + + + it('should send auth header', function() { + var controller = createController(); + $httpBackend.flush(); + + $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) { + // check if the header was send, if it wasn't the expectation won't + // match the request and the test will fail + return headers['Authorization'] == 'xxx'; + }).respond(201, ''); + + $rootScope.saveMessage('whatever'); + $httpBackend.flush(); + }); + }); + </pre> + */ +angular.mock.$HttpBackendProvider = function() { + this.$get = ['$rootScope', createHttpBackendMock]; +}; + +/** + * General factory function for $httpBackend mock. + * Returns instance for unit testing (when no arguments specified): + * - passing through is disabled + * - auto flushing is disabled + * + * Returns instance for e2e testing (when `$delegate` and `$browser` specified): + * - passing through (delegating request to real backend) is enabled + * - auto flushing is enabled + * + * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified) + * @param {Object=} $browser Auto-flushing enabled if specified + * @return {Object} Instance of $httpBackend mock + */ +function createHttpBackendMock($rootScope, $delegate, $browser) { + var definitions = [], + expectations = [], + responses = [], + responsesPush = angular.bind(responses, responses.push); + + function createResponse(status, data, headers) { + if (angular.isFunction(status)) return status; + + return function() { + return angular.isNumber(status) + ? [status, data, headers] + : [200, status, data]; + }; + } + + // TODO(vojta): change params to: method, url, data, headers, callback + function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) { + var xhr = new MockXhr(), + expectation = expectations[0], + wasExpected = false; + + function prettyPrint(data) { + return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp) + ? data + : angular.toJson(data); + } + + function wrapResponse(wrapped) { + if (!$browser && timeout && timeout.then) timeout.then(handleTimeout); + + return handleResponse; + + function handleResponse() { + var response = wrapped.response(method, url, data, headers); + xhr.$$respHeaders = response[2]; + callback(response[0], response[1], xhr.getAllResponseHeaders()); + } + + function handleTimeout() { + for (var i = 0, ii = responses.length; i < ii; i++) { + if (responses[i] === handleResponse) { + responses.splice(i, 1); + callback(-1, undefined, ''); + break; + } + } + } + } + + if (expectation && expectation.match(method, url)) { + if (!expectation.matchData(data)) + throw new Error('Expected ' + expectation + ' with different data\n' + + 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data); + + if (!expectation.matchHeaders(headers)) + throw new Error('Expected ' + expectation + ' with different headers\n' + + 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' + + prettyPrint(headers)); + + expectations.shift(); + + if (expectation.response) { + responses.push(wrapResponse(expectation)); + return; + } + wasExpected = true; + } + + var i = -1, definition; + while ((definition = definitions[++i])) { + if (definition.match(method, url, data, headers || {})) { + if (definition.response) { + // if $browser specified, we do auto flush all requests + ($browser ? $browser.defer : responsesPush)(wrapResponse(definition)); + } else if (definition.passThrough) { + $delegate(method, url, data, callback, headers, timeout, withCredentials); + } else throw new Error('No response defined !'); + return; + } + } + throw wasExpected ? + new Error('No response defined !') : + new Error('Unexpected request: ' + method + ' ' + url + '\n' + + (expectation ? 'Expected ' + expectation : 'No more request expected')); + } + + /** + * @ngdoc method + * @name ngMock.$httpBackend#when + * @methodOf ngMock.$httpBackend + * @description + * Creates a new backend definition. + * + * @param {string} method HTTP method. + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives + * data string and returns true if the data is as expected. + * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header + * object and returns true if the headers match the current definition. + * @returns {requestHandler} Returns an object with `respond` method that controls how a matched + * request is handled. + * + * - respond – + * `{function([status,] data[, headers])|function(function(method, url, data, headers)}` + * – The respond method takes a set of static data to be returned or a function that can return + * an array containing response status (number), response data (string) and response headers + * (Object). + */ + $httpBackend.when = function(method, url, data, headers) { + var definition = new MockHttpExpectation(method, url, data, headers), + chain = { + respond: function(status, data, headers) { + definition.response = createResponse(status, data, headers); + } + }; + + if ($browser) { + chain.passThrough = function() { + definition.passThrough = true; + }; + } + + definitions.push(definition); + return chain; + }; + + /** + * @ngdoc method + * @name ngMock.$httpBackend#whenGET + * @methodOf ngMock.$httpBackend + * @description + * Creates a new backend definition for GET requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#whenHEAD + * @methodOf ngMock.$httpBackend + * @description + * Creates a new backend definition for HEAD requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#whenDELETE + * @methodOf ngMock.$httpBackend + * @description + * Creates a new backend definition for DELETE requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#whenPOST + * @methodOf ngMock.$httpBackend + * @description + * Creates a new backend definition for POST requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives + * data string and returns true if the data is as expected. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#whenPUT + * @methodOf ngMock.$httpBackend + * @description + * Creates a new backend definition for PUT requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives + * data string and returns true if the data is as expected. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#whenJSONP + * @methodOf ngMock.$httpBackend + * @description + * Creates a new backend definition for JSONP requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + createShortMethods('when'); + + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expect + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation. + * + * @param {string} method HTTP method. + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header + * object and returns true if the headers match the current expectation. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + * + * - respond – + * `{function([status,] data[, headers])|function(function(method, url, data, headers)}` + * – The respond method takes a set of static data to be returned or a function that can return + * an array containing response status (number), response data (string) and response headers + * (Object). + */ + $httpBackend.expect = function(method, url, data, headers) { + var expectation = new MockHttpExpectation(method, url, data, headers); + expectations.push(expectation); + return { + respond: function(status, data, headers) { + expectation.response = createResponse(status, data, headers); + } + }; + }; + + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expectGET + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation for GET requests. For more info see `expect()`. + * + * @param {string|RegExp} url HTTP url. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. See #expect for more info. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expectHEAD + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation for HEAD requests. For more info see `expect()`. + * + * @param {string|RegExp} url HTTP url. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expectDELETE + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation for DELETE requests. For more info see `expect()`. + * + * @param {string|RegExp} url HTTP url. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expectPOST + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation for POST requests. For more info see `expect()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expectPUT + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation for PUT requests. For more info see `expect()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expectPATCH + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation for PATCH requests. For more info see `expect()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that + * receives data string and returns true if the data is as expected, or Object if request body + * is in JSON format. + * @param {Object=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + + /** + * @ngdoc method + * @name ngMock.$httpBackend#expectJSONP + * @methodOf ngMock.$httpBackend + * @description + * Creates a new request expectation for JSONP requests. For more info see `expect()`. + * + * @param {string|RegExp} url HTTP url. + * @returns {requestHandler} Returns an object with `respond` method that control how a matched + * request is handled. + */ + createShortMethods('expect'); + + + /** + * @ngdoc method + * @name ngMock.$httpBackend#flush + * @methodOf ngMock.$httpBackend + * @description + * Flushes all pending requests using the trained responses. + * + * @param {number=} count Number of responses to flush (in the order they arrived). If undefined, + * all pending requests will be flushed. If there are no pending requests when the flush method + * is called an exception is thrown (as this typically a sign of programming error). + */ + $httpBackend.flush = function(count) { + $rootScope.$digest(); + if (!responses.length) throw new Error('No pending request to flush !'); + + if (angular.isDefined(count)) { + while (count--) { + if (!responses.length) throw new Error('No more pending request to flush !'); + responses.shift()(); + } + } else { + while (responses.length) { + responses.shift()(); + } + } + $httpBackend.verifyNoOutstandingExpectation(); + }; + + + /** + * @ngdoc method + * @name ngMock.$httpBackend#verifyNoOutstandingExpectation + * @methodOf ngMock.$httpBackend + * @description + * Verifies that all of the requests defined via the `expect` api were made. If any of the + * requests were not made, verifyNoOutstandingExpectation throws an exception. + * + * Typically, you would call this method following each test case that asserts requests using an + * "afterEach" clause. + * + * <pre> + * afterEach($httpBackend.verifyNoOutstandingExpectation); + * </pre> + */ + $httpBackend.verifyNoOutstandingExpectation = function() { + $rootScope.$digest(); + if (expectations.length) { + throw new Error('Unsatisfied requests: ' + expectations.join(', ')); + } + }; + + + /** + * @ngdoc method + * @name ngMock.$httpBackend#verifyNoOutstandingRequest + * @methodOf ngMock.$httpBackend + * @description + * Verifies that there are no outstanding requests that need to be flushed. + * + * Typically, you would call this method following each test case that asserts requests using an + * "afterEach" clause. + * + * <pre> + * afterEach($httpBackend.verifyNoOutstandingRequest); + * </pre> + */ + $httpBackend.verifyNoOutstandingRequest = function() { + if (responses.length) { + throw new Error('Unflushed requests: ' + responses.length); + } + }; + + + /** + * @ngdoc method + * @name ngMock.$httpBackend#resetExpectations + * @methodOf ngMock.$httpBackend + * @description + * Resets all request expectations, but preserves all backend definitions. Typically, you would + * call resetExpectations during a multiple-phase test when you want to reuse the same instance of + * $httpBackend mock. + */ + $httpBackend.resetExpectations = function() { + expectations.length = 0; + responses.length = 0; + }; + + return $httpBackend; + + + function createShortMethods(prefix) { + angular.forEach(['GET', 'DELETE', 'JSONP'], function(method) { + $httpBackend[prefix + method] = function(url, headers) { + return $httpBackend[prefix](method, url, undefined, headers); + }; + }); + + angular.forEach(['PUT', 'POST', 'PATCH'], function(method) { + $httpBackend[prefix + method] = function(url, data, headers) { + return $httpBackend[prefix](method, url, data, headers); + }; + }); + } +} + +function MockHttpExpectation(method, url, data, headers) { + + this.data = data; + this.headers = headers; + + this.match = function(m, u, d, h) { + if (method != m) return false; + if (!this.matchUrl(u)) return false; + if (angular.isDefined(d) && !this.matchData(d)) return false; + if (angular.isDefined(h) && !this.matchHeaders(h)) return false; + return true; + }; + + this.matchUrl = function(u) { + if (!url) return true; + if (angular.isFunction(url.test)) return url.test(u); + return url == u; + }; + + this.matchHeaders = function(h) { + if (angular.isUndefined(headers)) return true; + if (angular.isFunction(headers)) return headers(h); + return angular.equals(headers, h); + }; + + this.matchData = function(d) { + if (angular.isUndefined(data)) return true; + if (data && angular.isFunction(data.test)) return data.test(d); + if (data && angular.isFunction(data)) return data(d); + if (data && !angular.isString(data)) return angular.toJson(data) == d; + return data == d; + }; + + this.toString = function() { + return method + ' ' + url; + }; +} + +function MockXhr() { + + // hack for testing $http, $httpBackend + MockXhr.$$lastInstance = this; + + this.open = function(method, url, async) { + this.$$method = method; + this.$$url = url; + this.$$async = async; + this.$$reqHeaders = {}; + this.$$respHeaders = {}; + }; + + this.send = function(data) { + this.$$data = data; + }; + + this.setRequestHeader = function(key, value) { + this.$$reqHeaders[key] = value; + }; + + this.getResponseHeader = function(name) { + // the lookup must be case insensitive, + // that's why we try two quick lookups first and full scan last + var header = this.$$respHeaders[name]; + if (header) return header; + + name = angular.lowercase(name); + header = this.$$respHeaders[name]; + if (header) return header; + + header = undefined; + angular.forEach(this.$$respHeaders, function(headerVal, headerName) { + if (!header && angular.lowercase(headerName) == name) header = headerVal; + }); + return header; + }; + + this.getAllResponseHeaders = function() { + var lines = []; + + angular.forEach(this.$$respHeaders, function(value, key) { + lines.push(key + ': ' + value); + }); + return lines.join('\n'); + }; + + this.abort = angular.noop; +} + + +/** + * @ngdoc function + * @name ngMock.$timeout + * @description + * + * This service is just a simple decorator for {@link ng.$timeout $timeout} service + * that adds a "flush" and "verifyNoPendingTasks" methods. + */ + +angular.mock.$TimeoutDecorator = function($delegate, $browser) { + + /** + * @ngdoc method + * @name ngMock.$timeout#flush + * @methodOf ngMock.$timeout + * @description + * + * Flushes the queue of pending tasks. + * + * @param {number=} delay maximum timeout amount to flush up until + */ + $delegate.flush = function(delay) { + $browser.defer.flush(delay); + }; + + /** + * @ngdoc method + * @name ngMock.$timeout#flushNext + * @methodOf ngMock.$timeout + * @description + * + * Flushes the next timeout in the queue and compares it to the provided delay + * + * @param {number=} expectedDelay the delay value that will be asserted against the delay of the + * next timeout function + */ + $delegate.flushNext = function(expectedDelay) { + $browser.defer.flushNext(expectedDelay); + }; + + /** + * @ngdoc method + * @name ngMock.$timeout#verifyNoPendingTasks + * @methodOf ngMock.$timeout + * @description + * + * Verifies that there are no pending tasks that need to be flushed. + */ + $delegate.verifyNoPendingTasks = function() { + if ($browser.deferredFns.length) { + throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' + + formatPendingTasksAsString($browser.deferredFns)); + } + }; + + function formatPendingTasksAsString(tasks) { + var result = []; + angular.forEach(tasks, function(task) { + result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}'); + }); + + return result.join(', '); + } + + return $delegate; +}; + +/** + * + */ +angular.mock.$RootElementProvider = function() { + this.$get = function() { + return angular.element('<div ng-app></div>'); + }; +}; + +/** + * @ngdoc overview + * @name ngMock + * @description + * + * # ngMock + * + * The `ngMock` module providers support to inject and mock Angular services into unit tests. + * In addition, ngMock also extends various core ng services such that they can be + * inspected and controlled in a synchronous manner within test code. + * + * {@installModule mocks} + * + * <div doc-module-components="ngMock"></div> + * + */ +angular.module('ngMock', ['ng']).provider({ + $browser: angular.mock.$BrowserProvider, + $exceptionHandler: angular.mock.$ExceptionHandlerProvider, + $log: angular.mock.$LogProvider, + $interval: angular.mock.$IntervalProvider, + $httpBackend: angular.mock.$HttpBackendProvider, + $rootElement: angular.mock.$RootElementProvider +}).config(['$provide', function($provide) { + $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); +}]); + +/** + * @ngdoc overview + * @name ngMockE2E + * @description + * + * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing. + * Currently there is only one mock present in this module - + * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock. + */ +angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { + $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator); +}]); + +/** + * @ngdoc object + * @name ngMockE2E.$httpBackend + * @description + * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of + * applications that use the {@link ng.$http $http service}. + * + * *Note*: For fake http backend implementation suitable for unit testing please see + * {@link ngMock.$httpBackend unit-testing $httpBackend mock}. + * + * This implementation can be used to respond with static or dynamic responses via the `when` api + * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the + * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch + * templates from a webserver). + * + * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application + * is being developed with the real backend api replaced with a mock, it is often desirable for + * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch + * templates or static files from the webserver). To configure the backend with this behavior + * use the `passThrough` request handler of `when` instead of `respond`. + * + * Additionally, we don't want to manually have to flush mocked out requests like we do during unit + * testing. For this reason the e2e $httpBackend automatically flushes mocked out requests + * automatically, closely simulating the behavior of the XMLHttpRequest object. + * + * To setup the application to run with this http backend, you have to create a module that depends + * on the `ngMockE2E` and your application modules and defines the fake backend: + * + * <pre> + * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']); + * myAppDev.run(function($httpBackend) { + * phones = [{name: 'phone1'}, {name: 'phone2'}]; + * + * // returns the current list of phones + * $httpBackend.whenGET('/phones').respond(phones); + * + * // adds a new phone to the phones array + * $httpBackend.whenPOST('/phones').respond(function(method, url, data) { + * phones.push(angular.fromJson(data)); + * }); + * $httpBackend.whenGET(/^\/templates\//).passThrough(); + * //... + * }); + * </pre> + * + * Afterwards, bootstrap your app with this new module. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#when + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition. + * + * @param {string} method HTTP method. + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header + * object and returns true if the headers match the current definition. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + * + * - respond – + * `{function([status,] data[, headers])|function(function(method, url, data, headers)}` + * – The respond method takes a set of static data to be returned or a function that can return + * an array containing response status (number), response data (string) and response headers + * (Object). + * - passThrough – `{function()}` – Any request matching a backend definition with `passThrough` + * handler, will be pass through to the real backend (an XHR request will be made to the + * server. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#whenGET + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition for GET requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#whenHEAD + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition for HEAD requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#whenDELETE + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition for DELETE requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#whenPOST + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition for POST requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#whenPUT + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition for PUT requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#whenPATCH + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition for PATCH requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @param {(string|RegExp)=} data HTTP request body. + * @param {(Object|function(Object))=} headers HTTP headers. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + */ + +/** + * @ngdoc method + * @name ngMockE2E.$httpBackend#whenJSONP + * @methodOf ngMockE2E.$httpBackend + * @description + * Creates a new backend definition for JSONP requests. For more info see `when()`. + * + * @param {string|RegExp} url HTTP url. + * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that + * control how a matched request is handled. + */ +angular.mock.e2e = {}; +angular.mock.e2e.$httpBackendDecorator = + ['$rootScope', '$delegate', '$browser', createHttpBackendMock]; + + +angular.mock.clearDataCache = function() { + var key, + cache = angular.element.cache; + + for(key in cache) { + if (Object.prototype.hasOwnProperty.call(cache,key)) { + var handle = cache[key].handle; + + handle && angular.element(handle.elem).off(); + delete cache[key]; + } + } +}; + + + +(window.jasmine || window.mocha) && (function(window) { + + var currentSpec = null; + + beforeEach(function() { + currentSpec = this; + }); + + afterEach(function() { + var injector = currentSpec.$injector; + + currentSpec.$injector = null; + currentSpec.$modules = null; + currentSpec = null; + + if (injector) { + injector.get('$rootElement').off(); + injector.get('$browser').pollFns.length = 0; + } + + angular.mock.clearDataCache(); + + // clean up jquery's fragment cache + angular.forEach(angular.element.fragments, function(val, key) { + delete angular.element.fragments[key]; + }); + + MockXhr.$$lastInstance = null; + + angular.forEach(angular.callbacks, function(val, key) { + delete angular.callbacks[key]; + }); + angular.callbacks.counter = 0; + }); + + function isSpecRunning() { + return currentSpec && (window.mocha || currentSpec.queue.running); + } + + /** + * @ngdoc function + * @name angular.mock.module + * @description + * + * *NOTE*: This function is also published on window for easy access.<br> + * + * This function registers a module configuration code. It collects the configuration information + * which will be used when the injector is created by {@link angular.mock.inject inject}. + * + * See {@link angular.mock.inject inject} for usage example + * + * @param {...(string|Function|Object)} fns any number of modules which are represented as string + * aliases or as anonymous module initialization functions. The modules are used to + * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an + * object literal is passed they will be register as values in the module, the key being + * the module name and the value being what is returned. + */ + window.module = angular.mock.module = function() { + var moduleFns = Array.prototype.slice.call(arguments, 0); + return isSpecRunning() ? workFn() : workFn; + ///////////////////// + function workFn() { + if (currentSpec.$injector) { + throw new Error('Injector already created, can not register a module!'); + } else { + var modules = currentSpec.$modules || (currentSpec.$modules = []); + angular.forEach(moduleFns, function(module) { + if (angular.isObject(module) && !angular.isArray(module)) { + modules.push(function($provide) { + angular.forEach(module, function(value, key) { + $provide.value(key, value); + }); + }); + } else { + modules.push(module); + } + }); + } + } + }; + + /** + * @ngdoc function + * @name angular.mock.inject + * @description + * + * *NOTE*: This function is also published on window for easy access.<br> + * + * The inject function wraps a function into an injectable function. The inject() creates new + * instance of {@link AUTO.$injector $injector} per test, which is then used for + * resolving references. + * + * + * ## Resolving References (Underscore Wrapping) + * Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this + * in multiple `it()` clauses. To be able to do this we must assign the reference to a variable + * that is declared in the scope of the `describe()` block. Since we would, most likely, want + * the variable to have the same name of the reference we have a problem, since the parameter + * to the `inject()` function would hide the outer variable. + * + * To help with this, the injected parameters can, optionally, be enclosed with underscores. + * These are ignored by the injector when the reference name is resolved. + * + * For example, the parameter `_myService_` would be resolved as the reference `myService`. + * Since it is available in the function body as _myService_, we can then assign it to a variable + * defined in an outer scope. + * + * ``` + * // Defined out reference variable outside + * var myService; + * + * // Wrap the parameter in underscores + * beforeEach( inject( function(_myService_){ + * myService = _myService_; + * })); + * + * // Use myService in a series of tests. + * it('makes use of myService', function() { + * myService.doStuff(); + * }); + * + * ``` + * + * See also {@link angular.mock.module angular.mock.module} + * + * ## Example + * Example of what a typical jasmine tests looks like with the inject method. + * <pre> + * + * angular.module('myApplicationModule', []) + * .value('mode', 'app') + * .value('version', 'v1.0.1'); + * + * + * describe('MyApp', function() { + * + * // You need to load modules that you want to test, + * // it loads only the "ng" module by default. + * beforeEach(module('myApplicationModule')); + * + * + * // inject() is used to inject arguments of all given functions + * it('should provide a version', inject(function(mode, version) { + * expect(version).toEqual('v1.0.1'); + * expect(mode).toEqual('app'); + * })); + * + * + * // The inject and module method can also be used inside of the it or beforeEach + * it('should override a version and test the new version is injected', function() { + * // module() takes functions or strings (module aliases) + * module(function($provide) { + * $provide.value('version', 'overridden'); // override version here + * }); + * + * inject(function(version) { + * expect(version).toEqual('overridden'); + * }); + * }); + * }); + * + * </pre> + * + * @param {...Function} fns any number of functions which will be injected using the injector. + */ + window.inject = angular.mock.inject = function() { + var blockFns = Array.prototype.slice.call(arguments, 0); + var errorForStack = new Error('Declaration Location'); + return isSpecRunning() ? workFn() : workFn; + ///////////////////// + function workFn() { + var modules = currentSpec.$modules || []; + + modules.unshift('ngMock'); + modules.unshift('ng'); + var injector = currentSpec.$injector; + if (!injector) { + injector = currentSpec.$injector = angular.injector(modules); + } + for(var i = 0, ii = blockFns.length; i < ii; i++) { + try { + /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */ + injector.invoke(blockFns[i] || angular.noop, this); + /* jshint +W040 */ + } catch (e) { + if(e.stack && errorForStack) e.stack += '\n' + errorForStack.stack; + throw e; + } finally { + errorForStack = null; + } + } + } + }; +})(window); \ No newline at end of file Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-resource.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-resource.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-resource.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,578 @@ +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +var $resourceMinErr = angular.$$minErr('$resource'); + +/** + * @ngdoc overview + * @name ngResource + * @description + * + * # ngResource + * + * The `ngResource` module provides interaction support with RESTful services + * via the $resource service. + * + * {@installModule resource} + * + * <div doc-module-components="ngResource"></div> + * + * See {@link ngResource.$resource `$resource`} for usage. + */ + +/** + * @ngdoc object + * @name ngResource.$resource + * @requires $http + * + * @description + * A factory which creates a resource object that lets you interact with + * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. + * + * The returned resource object has action methods which provide high-level behaviors without + * the need to interact with the low level {@link ng.$http $http} service. + * + * Requires the {@link ngResource `ngResource`} module to be installed. + * + * @param {string} url A parametrized URL template with parameters prefixed by `:` as in + * `/user/:username`. If you are using a URL with a port number (e.g. + * `http://example.com:8080/api`), it will be respected. + * + * If you are using a url with a suffix, just add the suffix, like this: + * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')` + * or even `$resource('http://example.com/resource/:resource_id.:format')` + * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be + * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you + * can escape it with `/\.`. + * + * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in + * `actions` methods. If any of the parameter value is a function, it will be executed every time + * when a param value needs to be obtained for a request (unless the param was overridden). + * + * Each key value in the parameter object is first bound to url template if present and then any + * excess keys are appended to the url search query after the `?`. + * + * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in + * URL `/path/greet?salutation=Hello`. + * + * If the parameter value is prefixed with `@` then the value of that parameter is extracted from + * the data object (useful for non-GET operations). + * + * @param {Object.<Object>=} actions Hash with declaration of custom action that should extend the + * default set of resource actions. The declaration should be created in the format of {@link + * ng.$http#usage_parameters $http.config}: + * + * {action1: {method:?, params:?, isArray:?, headers:?, ...}, + * action2: {method:?, params:?, isArray:?, headers:?, ...}, + * ...} + * + * Where: + * + * - **`action`** – {string} – The name of action. This name becomes the name of the method on + * your resource object. + * - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, + * `DELETE`, and `JSONP`. + * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of + * the parameter value is a function, it will be executed every time when a param value needs to + * be obtained for a request (unless the param was overridden). + * - **`url`** – {string} – action specific `url` override. The url templating is supported just + * like for the resource-level urls. + * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, + * see `returns` section. + * - **`transformRequest`** – + * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` – + * transform function or an array of such functions. The transform function takes the http + * request body and headers and returns its transformed (typically serialized) version. + * - **`transformResponse`** – + * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` – + * transform function or an array of such functions. The transform function takes the http + * response body and headers and returns its transformed (typically deserialized) version. + * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the + * GET request, otherwise if a cache instance built with + * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for + * caching. + * - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that + * should abort the request when resolved. + * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the + * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5 + * requests with credentials} for more information. + * - **`responseType`** - `{string}` - see {@link + * https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}. + * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods - + * `response` and `responseError`. Both `response` and `responseError` interceptors get called + * with `http response` object. See {@link ng.$http $http interceptors}. + * + * @returns {Object} A resource "class" object with methods for the default set of resource actions + * optionally extended with custom `actions`. The default set contains these actions: + * + * { 'get': {method:'GET'}, + * 'save': {method:'POST'}, + * 'query': {method:'GET', isArray:true}, + * 'remove': {method:'DELETE'}, + * 'delete': {method:'DELETE'} }; + * + * Calling these methods invoke an {@link ng.$http} with the specified http method, + * destination and parameters. When the data is returned from the server then the object is an + * instance of the resource class. The actions `save`, `remove` and `delete` are available on it + * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create, + * read, update, delete) on server-side data like this: + * <pre> + var User = $resource('/user/:userId', {userId:'@id'}); + var user = User.get({userId:123}, function() { + user.abc = true; + user.$save(); + }); + </pre> + * + * It is important to realize that invoking a $resource object method immediately returns an + * empty reference (object or array depending on `isArray`). Once the data is returned from the + * server the existing reference is populated with the actual data. This is a useful trick since + * usually the resource is assigned to a model which is then rendered by the view. Having an empty + * object results in no rendering, once the data arrives from the server then the object is + * populated with the data and the view automatically re-renders itself showing the new data. This + * means that in most case one never has to write a callback function for the action methods. + * + * The action methods on the class object or instance object can be invoked with the following + * parameters: + * + * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])` + * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` + * - non-GET instance actions: `instance.$action([parameters], [success], [error])` + * + * Success callback is called with (value, responseHeaders) arguments. Error callback is called + * with (httpResponse) argument. + * + * Class actions return empty instance (with additional properties below). + * Instance actions return promise of the action. + * + * The Resource instances and collection have these additional properties: + * + * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this + * instance or collection. + * + * On success, the promise is resolved with the same resource instance or collection object, + * updated with data from server. This makes it easy to use in + * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view + * rendering until the resource(s) are loaded. + * + * On failure, the promise is resolved with the {@link ng.$http http response} object, without + * the `resource` property. + * + * - `$resolved`: `true` after first server interaction is completed (either with success or + * rejection), `false` before that. Knowing if the Resource has been resolved is useful in + * data-binding. + * + * @example + * + * # Credit card resource + * + * <pre> + // Define CreditCard class + var CreditCard = $resource('/user/:userId/card/:cardId', + {userId:123, cardId:'@id'}, { + charge: {method:'POST', params:{charge:true}} + }); + + // We can retrieve a collection from the server + var cards = CreditCard.query(function() { + // GET: /user/123/card + // server returns: [ {id:456, number:'1234', name:'Smith'} ]; + + var card = cards[0]; + // each item is an instance of CreditCard + expect(card instanceof CreditCard).toEqual(true); + card.name = "J. Smith"; + // non GET methods are mapped onto the instances + card.$save(); + // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'} + // server returns: {id:456, number:'1234', name: 'J. Smith'}; + + // our custom method is mapped as well. + card.$charge({amount:9.99}); + // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'} + }); + + // we can create an instance as well + var newCard = new CreditCard({number:'0123'}); + newCard.name = "Mike Smith"; + newCard.$save(); + // POST: /user/123/card {number:'0123', name:'Mike Smith'} + // server returns: {id:789, number:'01234', name: 'Mike Smith'}; + expect(newCard.id).toEqual(789); + * </pre> + * + * The object returned from this function execution is a resource "class" which has "static" method + * for each action in the definition. + * + * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and + * `headers`. + * When the data is returned from the server then the object is an instance of the resource type and + * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD + * operations (create, read, update, delete) on server-side data. + + <pre> + var User = $resource('/user/:userId', {userId:'@id'}); + var user = User.get({userId:123}, function() { + user.abc = true; + user.$save(); + }); + </pre> + * + * It's worth noting that the success callback for `get`, `query` and other methods gets passed + * in the response that came from the server as well as $http header getter function, so one + * could rewrite the above example and get access to http headers as: + * + <pre> + var User = $resource('/user/:userId', {userId:'@id'}); + User.get({userId:123}, function(u, getResponseHeaders){ + u.abc = true; + u.$save(function(u, putResponseHeaders) { + //u => saved user object + //putResponseHeaders => $http header getter + }); + }); + </pre> + + * # Buzz client + + Let's look at what a buzz client created with the `$resource` service looks like: + <doc:example> + <doc:source jsfiddle="false"> + <script> + function BuzzController($resource) { + this.userId = 'googlebuzz'; + this.Activity = $resource( + 'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityI...', + {alt:'json', callback:'JSON_CALLBACK'}, + { + get:{method:'JSONP', params:{visibility:'@self'}}, + replies: {method:'JSONP', params:{visibility:'@self', comments:'@comments'}} + } + ); + } + + BuzzController.prototype = { + fetch: function() { + this.activities = this.Activity.get({userId:this.userId}); + }, + expandReplies: function(activity) { + activity.replies = this.Activity.replies({userId:this.userId, activityId:activity.id}); + } + }; + BuzzController.$inject = ['$resource']; + </script> + + <div ng-controller="BuzzController"> + <input ng-model="userId"/> + <button ng-click="fetch()">fetch</button> + <hr/> + <div ng-repeat="item in activities.data.items"> + <h1 style="font-size: 15px;"> + <img src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/> + <a href="{{item.actor.profileUrl}}">{{item.actor.name}}</a> + <a href ng-click="expandReplies(item)" style="float: right;">Expand replies: + {{item.links.replies[0].count}}</a> + </h1> + {{item.object.content | html}} + <div ng-repeat="reply in item.replies.data.items" style="margin-left: 20px;"> + <img src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/> + <a href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>: {{reply.content | html}} + </div> + </div> + </div> + </doc:source> + <doc:scenario> + </doc:scenario> + </doc:example> + */ +angular.module('ngResource', ['ng']). + factory('$resource', ['$http', '$parse', '$q', function($http, $parse, $q) { + var DEFAULT_ACTIONS = { + 'get': {method:'GET'}, + 'save': {method:'POST'}, + 'query': {method:'GET', isArray:true}, + 'remove': {method:'DELETE'}, + 'delete': {method:'DELETE'} + }; + var noop = angular.noop, + forEach = angular.forEach, + extend = angular.extend, + copy = angular.copy, + isFunction = angular.isFunction, + getter = function(obj, path) { + return $parse(path)(obj); + }; + + /** + * We need our custom method because encodeURIComponent is too aggressive and doesn't follow + * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path + * segments: + * segment = *pchar + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * pct-encoded = "%" HEXDIG HEXDIG + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriSegment(val) { + return encodeUriQuery(val, true). + replace(/%26/gi, '&'). + replace(/%3D/gi, '='). + replace(/%2B/gi, '+'); + } + + + /** + * This method is intended for encoding *key* or *value* parts of query component. We need a + * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't + * have to be encoded per http://tools.ietf.org/html/rfc3986: + * query = *( pchar / "/" / "?" ) + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * pct-encoded = "%" HEXDIG HEXDIG + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + */ + function encodeUriQuery(val, pctEncodeSpaces) { + return encodeURIComponent(val). + replace(/%40/gi, '@'). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); + } + + function Route(template, defaults) { + this.template = template; + this.defaults = defaults || {}; + this.urlParams = {}; + } + + Route.prototype = { + setUrlParams: function(config, params, actionUrl) { + var self = this, + url = actionUrl || self.template, + val, + encodedVal; + + var urlParams = self.urlParams = {}; + forEach(url.split(/\W/), function(param){ + if (param === 'hasOwnProperty') { + throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name."); + } + if (!(new RegExp("^\\d+$").test(param)) && param && + (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { + urlParams[param] = true; + } + }); + url = url.replace(/\\:/g, ':'); + + params = params || {}; + forEach(self.urlParams, function(_, urlParam){ + val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; + if (angular.isDefined(val) && val !== null) { + encodedVal = encodeUriSegment(val); + url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), encodedVal + "$1"); + } else { + url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match, + leadingSlashes, tail) { + if (tail.charAt(0) == '/') { + return tail; + } else { + return leadingSlashes + tail; + } + }); + } + }); + + // strip trailing slashes and set the url + url = url.replace(/\/+$/, ''); + // then replace collapse `/.` if found in the last URL path segment before the query + // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x` + url = url.replace(/\/\.(?=\w+($|\?))/, '.'); + // replace escaped `/\.` with `/.` + config.url = url.replace(/\/\\\./, '/.'); + + + // set params - delegate param encoding to $http + forEach(params, function(value, key){ + if (!self.urlParams[key]) { + config.params = config.params || {}; + config.params[key] = value; + } + }); + } + }; + + + function resourceFactory(url, paramDefaults, actions) { + var route = new Route(url); + + actions = extend({}, DEFAULT_ACTIONS, actions); + + function extractParams(data, actionParams){ + var ids = {}; + actionParams = extend({}, paramDefaults, actionParams); + forEach(actionParams, function(value, key){ + if (isFunction(value)) { value = value(); } + ids[key] = value && value.charAt && value.charAt(0) == '@' ? + getter(data, value.substr(1)) : value; + }); + return ids; + } + + function defaultResponseInterceptor(response) { + return response.resource; + } + + function Resource(value){ + copy(value || {}, this); + } + + forEach(actions, function(action, name) { + var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method); + + Resource[name] = function(a1, a2, a3, a4) { + var params = {}, data, success, error; + + /* jshint -W086 */ /* (purposefully fall through case statements) */ + switch(arguments.length) { + case 4: + error = a4; + success = a3; + //fallthrough + case 3: + case 2: + if (isFunction(a2)) { + if (isFunction(a1)) { + success = a1; + error = a2; + break; + } + + success = a2; + error = a3; + //fallthrough + } else { + params = a1; + data = a2; + success = a3; + break; + } + case 1: + if (isFunction(a1)) success = a1; + else if (hasBody) data = a1; + else params = a1; + break; + case 0: break; + default: + throw $resourceMinErr('badargs', + "Expected up to 4 arguments [params, data, success, error], got {0} arguments", + arguments.length); + } + /* jshint +W086 */ /* (purposefully fall through case statements) */ + + var isInstanceCall = data instanceof Resource; + var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data)); + var httpConfig = {}; + var responseInterceptor = action.interceptor && action.interceptor.response || + defaultResponseInterceptor; + var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || + undefined; + + forEach(action, function(value, key) { + if (key != 'params' && key != 'isArray' && key != 'interceptor') { + httpConfig[key] = copy(value); + } + }); + + if (hasBody) httpConfig.data = data; + route.setUrlParams(httpConfig, + extend({}, extractParams(data, action.params || {}), params), + action.url); + + var promise = $http(httpConfig).then(function(response) { + var data = response.data, + promise = value.$promise; + + if (data) { + // Need to convert action.isArray to boolean in case it is undefined + // jshint -W018 + if ( angular.isArray(data) !== (!!action.isArray) ) { + throw $resourceMinErr('badcfg', 'Error in resource configuration. Expected ' + + 'response to contain an {0} but got an {1}', + action.isArray?'array':'object', angular.isArray(data)?'array':'object'); + } + // jshint +W018 + if (action.isArray) { + value.length = 0; + forEach(data, function(item) { + value.push(new Resource(item)); + }); + } else { + copy(data, value); + value.$promise = promise; + } + } + + value.$resolved = true; + + response.resource = value; + + return response; + }, function(response) { + value.$resolved = true; + + (error||noop)(response); + + return $q.reject(response); + }); + + promise = promise.then( + function(response) { + var value = responseInterceptor(response); + (success||noop)(value, response.headers); + return value; + }, + responseErrorInterceptor); + + if (!isInstanceCall) { + // we are creating instance / collection + // - set the initial promise + // - return the instance / collection + value.$promise = promise; + value.$resolved = false; + + return value; + } + + // instance call + return promise; + }; + + + Resource.prototype['$' + name] = function(params, success, error) { + if (isFunction(params)) { + error = success; success = params; params = {}; + } + var result = Resource[name](params, this, success, error); + return result.$promise || result; + }; + }); + + Resource.bind = function(additionalParamDefaults){ + return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions); + }; + + return Resource; + } + + return resourceFactory; + }]); + + +})(window, window.angular); Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-route.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-route.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-route.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,880 @@ +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/** + * @ngdoc overview + * @name ngRoute + * @description + * + * # ngRoute + * + * The `ngRoute` module provides routing and deeplinking services and directives for angular apps. + * + * {@installModule route} + * + * <div doc-module-components="ngRoute"></div> + */ + /* global -ngRouteModule */ +var ngRouteModule = angular.module('ngRoute', ['ng']). + provider('$route', $RouteProvider); + +/** + * @ngdoc object + * @name ngRoute.$routeProvider + * @function + * + * @description + * + * Used for configuring routes. See {@link ngRoute.$route $route} for an example. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + */ +function $RouteProvider(){ + function inherit(parent, extra) { + return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra); + } + + var routes = {}; + + /** + * @ngdoc method + * @name ngRoute.$routeProvider#when + * @methodOf ngRoute.$routeProvider + * + * @param {string} path Route path (matched against `$location.path`). If `$location.path` + * contains redundant trailing slash or is missing one, the route will still match and the + * `$location.path` will be updated to add or drop the trailing slash to exactly match the + * route definition. + * + * * `path` can contain named groups starting with a colon (`:name`). All characters up + * to the next slash are matched and stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain named groups starting with a colon and ending with a star (`:name*`). + * All characters are eagerly stored in `$routeParams` under the given `name` + * when the route matches. + * * `path` can contain optional named groups with a question mark (`:name?`). + * + * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match + * `/color/brown/largecode/code/with/slashs/edit` and extract: + * + * * `color: brown` + * * `largecode: code/with/slashs`. + * + * + * @param {Object} route Mapping information to be assigned to `$route.current` on route + * match. + * + * Object properties: + * + * - `controller` – `{(string|function()=}` – Controller fn that should be associated with + * newly created scope or the name of a {@link angular.Module#controller registered + * controller} if passed as a string. + * - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be + * published to scope under the `controllerAs` name. + * - `template` – `{string=|function()=}` – html template as a string or a function that + * returns an html template as a string which should be used by {@link + * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives. + * This property takes precedence over `templateUrl`. + * + * If `template` is a function, it will be called with the following parameters: + * + * - `{Array.<Object>}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html + * template that should be used by {@link ngRoute.directive:ngView ngView}. + * + * If `templateUrl` is a function, it will be called with the following parameters: + * + * - `{Array.<Object>}` - route parameters extracted from the current + * `$location.path()` by applying the current route + * + * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should + * be injected into the controller. If any of these dependencies are promises, the router + * will wait for them all to be resolved or one to be rejected before the controller is + * instantiated. + * If all the promises are resolved successfully, the values of the resolved promises are + * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is + * fired. If any of the promises are rejected the + * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object + * is: + * + * - `key` – `{string}`: a name of a dependency to be injected into the controller. + * - `factory` - `{string|function}`: If `string` then it is an alias for a service. + * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected} + * and the return value is treated as the dependency. If the result is a promise, it is + * resolved before its value is injected into the controller. Be aware that + * `ngRoute.$routeParams` will still refer to the previous route within these resolve + * functions. Use `$route.current.params` to access the new route parameters, instead. + * + * - `redirectTo` – {(string|function())=} – value to update + * {@link ng.$location $location} path with and trigger route redirection. + * + * If `redirectTo` is a function, it will be called with the following parameters: + * + * - `{Object.<string>}` - route parameters extracted from the current + * `$location.path()` by applying the current route templateUrl. + * - `{string}` - current `$location.path()` + * - `{Object}` - current `$location.search()` + * + * The custom `redirectTo` function is expected to return a string which will be used + * to update `$location.path()` and `$location.search()`. + * + * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()` + * or `$location.hash()` changes. + * + * If the option is set to `false` and url in the browser changes, then + * `$routeUpdate` event is broadcasted on the root scope. + * + * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive + * + * If the option is set to `true`, then the particular route can be matched without being + * case sensitive + * + * @returns {Object} self + * + * @description + * Adds a new route definition to the `$route` service. + */ + this.when = function(path, route) { + routes[path] = angular.extend( + {reloadOnSearch: true}, + route, + path && pathRegExp(path, route) + ); + + // create redirection for trailing slashes + if (path) { + var redirectPath = (path[path.length-1] == '/') + ? path.substr(0, path.length-1) + : path +'/'; + + routes[redirectPath] = angular.extend( + {redirectTo: path}, + pathRegExp(redirectPath, route) + ); + } + + return this; + }; + + /** + * @param path {string} path + * @param opts {Object} options + * @return {?Object} + * + * @description + * Normalizes the given path, returning a regular expression + * and the original path. + * + * Inspired by pathRexp in visionmedia/express/lib/utils.js. + */ + function pathRegExp(path, opts) { + var insensitive = opts.caseInsensitiveMatch, + ret = { + originalPath: path, + regexp: path + }, + keys = ret.keys = []; + + path = path + .replace(/([().])/g, '\\$1') + .replace(/(\/)?:(\w+)([\?|\*])?/g, function(_, slash, key, option){ + var optional = option === '?' ? option : null; + var star = option === '*' ? option : null; + keys.push({ name: key, optional: !!optional }); + slash = slash || ''; + return '' + + (optional ? '' : slash) + + '(?:' + + (optional ? slash : '') + + (star && '(.+?)' || '([^/]+)') + + (optional || '') + + ')' + + (optional || ''); + }) + .replace(/([\/$\*])/g, '\\$1'); + + ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : ''); + return ret; + } + + /** + * @ngdoc method + * @name ngRoute.$routeProvider#otherwise + * @methodOf ngRoute.$routeProvider + * + * @description + * Sets route definition that will be used on route change when no other route definition + * is matched. + * + * @param {Object} params Mapping information to be assigned to `$route.current`. + * @returns {Object} self + */ + this.otherwise = function(params) { + this.when(null, params); + return this; + }; + + + this.$get = ['$rootScope', + '$location', + '$routeParams', + '$q', + '$injector', + '$http', + '$templateCache', + '$sce', + function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) { + + /** + * @ngdoc object + * @name ngRoute.$route + * @requires $location + * @requires $routeParams + * + * @property {Object} current Reference to the current route definition. + * The route definition contains: + * + * - `controller`: The controller constructor as define in route definition. + * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for + * controller instantiation. The `locals` contain + * the resolved values of the `resolve` map. Additionally the `locals` also contain: + * + * - `$scope` - The current route scope. + * - `$template` - The current route template HTML. + * + * @property {Array.<Object>} routes Array of all configured routes. + * + * @description + * `$route` is used for deep-linking URLs to controllers and views (HTML partials). + * It watches `$location.url()` and tries to map the path to an existing route definition. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API. + * + * The `$route` service is typically used in conjunction with the + * {@link ngRoute.directive:ngView `ngView`} directive and the + * {@link ngRoute.$routeParams `$routeParams`} service. + * + * @example + This example shows how changing the URL hash causes the `$route` to match a route against the + URL, and the `ngView` pulls in the partial. + + Note that this example is using {@link ng.directive:script inlined templates} + to get it working on jsfiddle as well. + + <example module="ngViewExample" deps="angular-route.js"> + <file name="index.html"> + <div ng-controller="MainCntl"> + Choose: + <a href="Book/Moby">Moby</a> | + <a href="Book/Moby/ch/1">Moby: Ch1</a> | + <a href="Book/Gatsby">Gatsby</a> | + <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> | + <a href="Book/Scarlet">Scarlet Letter</a><br/> + + <div ng-view></div> + <hr /> + + <pre>$location.path() = {{$location.path()}}</pre> + <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre> + <pre>$route.current.params = {{$route.current.params}}</pre> + <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre> + <pre>$routeParams = {{$routeParams}}</pre> + </div> + </file> + + <file name="book.html"> + controller: {{name}}<br /> + Book Id: {{params.bookId}}<br /> + </file> + + <file name="chapter.html"> + controller: {{name}}<br /> + Book Id: {{params.bookId}}<br /> + Chapter Id: {{params.chapterId}} + </file> + + <file name="script.js"> + angular.module('ngViewExample', ['ngRoute']) + + .config(function($routeProvider, $locationProvider) { + $routeProvider.when('/Book/:bookId', { + templateUrl: 'book.html', + controller: BookCntl, + resolve: { + // I will cause a 1 second delay + delay: function($q, $timeout) { + var delay = $q.defer(); + $timeout(delay.resolve, 1000); + return delay.promise; + } + } + }); + $routeProvider.when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: ChapterCntl + }); + + // configure html5 to get links working on jsfiddle + $locationProvider.html5Mode(true); + }); + + function MainCntl($scope, $route, $routeParams, $location) { + $scope.$route = $route; + $scope.$location = $location; + $scope.$routeParams = $routeParams; + } + + function BookCntl($scope, $routeParams) { + $scope.name = "BookCntl"; + $scope.params = $routeParams; + } + + function ChapterCntl($scope, $routeParams) { + $scope.name = "ChapterCntl"; + $scope.params = $routeParams; + } + </file> + + <file name="scenario.js"> + it('should load and compile correct template', function() { + element('a:contains("Moby: Ch1")').click(); + var content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: ChapterCntl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element('a:contains("Scarlet")').click(); + sleep(2); // promises are not part of scenario waiting + content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: BookCntl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + </file> + </example> + */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeChangeStart + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * Broadcasted before a route change. At this point the route services starts + * resolving all of the dependencies needed for the route change to occurs. + * Typically this involves fetching the view template as well as any dependencies + * defined in `resolve` route property. Once all of the dependencies are resolved + * `$routeChangeSuccess` is fired. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} next Future route information. + * @param {Route} current Current route information. + */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeChangeSuccess + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * Broadcasted after a route dependencies are resolved. + * {@link ngRoute.directive:ngView ngView} listens for the directive + * to instantiate the controller and render the view. + * + * @param {Object} angularEvent Synthetic event object. + * @param {Route} current Current route information. + * @param {Route|Undefined} previous Previous route information, or undefined if current is + * first route entered. + */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeChangeError + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * Broadcasted if any of the resolve promises are rejected. + * + * @param {Object} angularEvent Synthetic event object + * @param {Route} current Current route information. + * @param {Route} previous Previous route information. + * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise. + */ + + /** + * @ngdoc event + * @name ngRoute.$route#$routeUpdate + * @eventOf ngRoute.$route + * @eventType broadcast on root scope + * @description + * + * The `reloadOnSearch` property has been set to false, and we are reusing the same + * instance of the Controller. + */ + + var forceReload = false, + $route = { + routes: routes, + + /** + * @ngdoc method + * @name ngRoute.$route#reload + * @methodOf ngRoute.$route + * + * @description + * Causes `$route` service to reload the current route even if + * {@link ng.$location $location} hasn't changed. + * + * As a result of that, {@link ngRoute.directive:ngView ngView} + * creates new scope, reinstantiates the controller. + */ + reload: function() { + forceReload = true; + $rootScope.$evalAsync(updateRoute); + } + }; + + $rootScope.$on('$locationChangeSuccess', updateRoute); + + return $route; + + ///////////////////////////////////////////////////// + + /** + * @param on {string} current url + * @param route {Object} route regexp to match the url against + * @return {?Object} + * + * @description + * Check if the route matches the current url. + * + * Inspired by match in + * visionmedia/express/lib/router/router.js. + */ + function switchRouteMatcher(on, route) { + var keys = route.keys, + params = {}; + + if (!route.regexp) return null; + + var m = route.regexp.exec(on); + if (!m) return null; + + for (var i = 1, len = m.length; i < len; ++i) { + var key = keys[i - 1]; + + var val = 'string' == typeof m[i] + ? decodeURIComponent(m[i]) + : m[i]; + + if (key && val) { + params[key.name] = val; + } + } + return params; + } + + function updateRoute() { + var next = parseRoute(), + last = $route.current; + + if (next && last && next.$$route === last.$$route + && angular.equals(next.pathParams, last.pathParams) + && !next.reloadOnSearch && !forceReload) { + last.params = next.params; + angular.copy(last.params, $routeParams); + $rootScope.$broadcast('$routeUpdate', last); + } else if (next || last) { + forceReload = false; + $rootScope.$broadcast('$routeChangeStart', next, last); + $route.current = next; + if (next) { + if (next.redirectTo) { + if (angular.isString(next.redirectTo)) { + $location.path(interpolate(next.redirectTo, next.params)).search(next.params) + .replace(); + } else { + $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search())) + .replace(); + } + } + } + + $q.when(next). + then(function() { + if (next) { + var locals = angular.extend({}, next.resolve), + template, templateUrl; + + angular.forEach(locals, function(value, key) { + locals[key] = angular.isString(value) ? + $injector.get(value) : $injector.invoke(value); + }); + + if (angular.isDefined(template = next.template)) { + if (angular.isFunction(template)) { + template = template(next.params); + } + } else if (angular.isDefined(templateUrl = next.templateUrl)) { + if (angular.isFunction(templateUrl)) { + templateUrl = templateUrl(next.params); + } + templateUrl = $sce.getTrustedResourceUrl(templateUrl); + if (angular.isDefined(templateUrl)) { + next.loadedTemplateUrl = templateUrl; + template = $http.get(templateUrl, {cache: $templateCache}). + then(function(response) { return response.data; }); + } + } + if (angular.isDefined(template)) { + locals['$template'] = template; + } + return $q.all(locals); + } + }). + // after route change + then(function(locals) { + if (next == $route.current) { + if (next) { + next.locals = locals; + angular.copy(next.params, $routeParams); + } + $rootScope.$broadcast('$routeChangeSuccess', next, last); + } + }, function(error) { + if (next == $route.current) { + $rootScope.$broadcast('$routeChangeError', next, last, error); + } + }); + } + } + + + /** + * @returns the current active route, by matching it against the URL + */ + function parseRoute() { + // Match a route + var params, match; + angular.forEach(routes, function(route, path) { + if (!match && (params = switchRouteMatcher($location.path(), route))) { + match = inherit(route, { + params: angular.extend({}, $location.search(), params), + pathParams: params}); + match.$$route = route; + } + }); + // No route matched; fallback to "otherwise" route + return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}}); + } + + /** + * @returns interpolation of the redirect path with the parameters + */ + function interpolate(string, params) { + var result = []; + angular.forEach((string||'').split(':'), function(segment, i) { + if (i === 0) { + result.push(segment); + } else { + var segmentMatch = segment.match(/(\w+)(.*)/); + var key = segmentMatch[1]; + result.push(params[key]); + result.push(segmentMatch[2] || ''); + delete params[key]; + } + }); + return result.join(''); + } + }]; +} + +ngRouteModule.provider('$routeParams', $RouteParamsProvider); + + +/** + * @ngdoc object + * @name ngRoute.$routeParams + * @requires $route + * + * @description + * The `$routeParams` service allows you to retrieve the current set of route parameters. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * The route parameters are a combination of {@link ng.$location `$location`}'s + * {@link ng.$location#methods_search `search()`} and {@link ng.$location#methods_path `path()`}. + * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched. + * + * In case of parameter name collision, `path` params take precedence over `search` params. + * + * The service guarantees that the identity of the `$routeParams` object will remain unchanged + * (but its properties will likely change) even when a route change occurs. + * + * Note that the `$routeParams` are only updated *after* a route change completes successfully. + * This means that you cannot rely on `$routeParams` being correct in route resolve functions. + * Instead you can use `$route.current.params` to access the new route's parameters. + * + * @example + * <pre> + * // Given: + * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby + * // Route: /Chapter/:chapterId/Section/:sectionId + * // + * // Then + * $routeParams ==> {chapterId:1, sectionId:2, search:'moby'} + * </pre> + */ +function $RouteParamsProvider() { + this.$get = function() { return {}; }; +} + +ngRouteModule.directive('ngView', ngViewFactory); + +/** + * @ngdoc directive + * @name ngRoute.directive:ngView + * @restrict ECA + * + * @description + * # Overview + * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by + * including the rendered template of the current route into the main layout (`index.html`) file. + * Every time the current route changes, the included view changes with it according to the + * configuration of the `$route` service. + * + * Requires the {@link ngRoute `ngRoute`} module to be installed. + * + * @animations + * enter - animation is used to bring new content into the browser. + * leave - animation is used to animate existing content away. + * + * The enter and leave animation occur concurrently. + * + * @scope + * @priority 400 + * @example + <example module="ngViewExample" deps="angular-route.js" animations="true"> + <file name="index.html"> + <div ng-controller="MainCntl as main"> + Choose: + <a href="Book/Moby">Moby</a> | + <a href="Book/Moby/ch/1">Moby: Ch1</a> | + <a href="Book/Gatsby">Gatsby</a> | + <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> | + <a href="Book/Scarlet">Scarlet Letter</a><br/> + + <div class="view-animate-container"> + <div ng-view class="view-animate"></div> + </div> + <hr /> + + <pre>$location.path() = {{main.$location.path()}}</pre> + <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre> + <pre>$route.current.params = {{main.$route.current.params}}</pre> + <pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre> + <pre>$routeParams = {{main.$routeParams}}</pre> + </div> + </file> + + <file name="book.html"> + <div> + controller: {{book.name}}<br /> + Book Id: {{book.params.bookId}}<br /> + </div> + </file> + + <file name="chapter.html"> + <div> + controller: {{chapter.name}}<br /> + Book Id: {{chapter.params.bookId}}<br /> + Chapter Id: {{chapter.params.chapterId}} + </div> + </file> + + <file name="animations.css"> + .view-animate-container { + position:relative; + height:100px!important; + position:relative; + background:white; + border:1px solid black; + height:40px; + overflow:hidden; + } + + .view-animate { + padding:10px; + } + + .view-animate.ng-enter, .view-animate.ng-leave { + -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + + display:block; + width:100%; + border-left:1px solid black; + + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + padding:10px; + } + + .view-animate.ng-enter { + left:100%; + } + .view-animate.ng-enter.ng-enter-active { + left:0; + } + .view-animate.ng-leave.ng-leave-active { + left:-100%; + } + </file> + + <file name="script.js"> + angular.module('ngViewExample', ['ngRoute', 'ngAnimate'], + function($routeProvider, $locationProvider) { + $routeProvider.when('/Book/:bookId', { + templateUrl: 'book.html', + controller: BookCntl, + controllerAs: 'book' + }); + $routeProvider.when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: ChapterCntl, + controllerAs: 'chapter' + }); + + // configure html5 to get links working on jsfiddle + $locationProvider.html5Mode(true); + }); + + function MainCntl($route, $routeParams, $location) { + this.$route = $route; + this.$location = $location; + this.$routeParams = $routeParams; + } + + function BookCntl($routeParams) { + this.name = "BookCntl"; + this.params = $routeParams; + } + + function ChapterCntl($routeParams) { + this.name = "ChapterCntl"; + this.params = $routeParams; + } + </file> + + <file name="scenario.js"> + it('should load and compile correct template', function() { + element('a:contains("Moby: Ch1")').click(); + var content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: ChapterCntl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element('a:contains("Scarlet")').click(); + content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: BookCntl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + </file> + </example> + */ + + +/** + * @ngdoc event + * @name ngRoute.directive:ngView#$viewContentLoaded + * @eventOf ngRoute.directive:ngView + * @eventType emit on the current ngView scope + * @description + * Emitted every time the ngView content is reloaded. + */ +ngViewFactory.$inject = ['$route', '$anchorScroll', '$compile', '$controller', '$animate']; +function ngViewFactory( $route, $anchorScroll, $compile, $controller, $animate) { + return { + restrict: 'ECA', + terminal: true, + priority: 400, + transclude: 'element', + compile: function(element, attr, linker) { + return function(scope, $element, attr) { + var currentScope, + currentElement, + autoScrollExp = attr.autoscroll, + onloadExp = attr.onload || ''; + + scope.$on('$routeChangeSuccess', update); + update(); + + function cleanupLastView() { + if (currentScope) { + currentScope.$destroy(); + currentScope = null; + } + if(currentElement) { + $animate.leave(currentElement); + currentElement = null; + } + } + + function update() { + var locals = $route.current && $route.current.locals, + template = locals && locals.$template; + + if (template) { + var newScope = scope.$new(); + linker(newScope, function(clone) { + clone.html(template); + $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () { + if (angular.isDefined(autoScrollExp) + && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }); + + cleanupLastView(); + + var link = $compile(clone.contents()), + current = $route.current; + + currentScope = current.scope = newScope; + currentElement = clone; + + if (current.controller) { + locals.$scope = currentScope; + var controller = $controller(current.controller, locals); + if (current.controllerAs) { + currentScope[current.controllerAs] = controller; + } + clone.data('$ngControllerController', controller); + clone.children().data('$ngControllerController', controller); + } + + link(currentScope); + currentScope.$emit('$viewContentLoaded'); + currentScope.$eval(onloadExp); + }); + } else { + cleanupLastView(); + } + } + }; + } + }; +} + + +})(window, window.angular); Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-sanitize.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-sanitize.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-sanitize.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,577 @@ +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +var $sanitizeMinErr = angular.$$minErr('$sanitize'); + +/** + * @ngdoc overview + * @name ngSanitize + * @description + * + * # ngSanitize + * + * The `ngSanitize` module provides functionality to sanitize HTML. + * + * {@installModule sanitize} + * + * <div doc-module-components="ngSanitize"></div> + * + * See {@link ngSanitize.$sanitize `$sanitize`} for usage. + */ + +/* + * HTML Parser By Misko Hevery (misko@hevery.com) + * based on: HTML Parser By John Resig (ejohn.org) + * Original code by Erik Arvidsson, Mozilla Public License + * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js + * + * // Use like so: + * htmlParser(htmlString, { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * }); + * + */ + + +/** + * @ngdoc service + * @name ngSanitize.$sanitize + * @function + * + * @description + * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are + * then serialized back to properly escaped html string. This means that no unsafe input can make + * it into the returned string, however, since our parser is more strict than a typical browser + * parser, it's possible that some obscure input, which would be recognized as valid HTML by a + * browser, won't make it through the sanitizer. + * + * @param {string} html Html input. + * @returns {string} Sanitized html. + * + * @example + <doc:example module="ngSanitize"> + <doc:source> + <script> + function Ctrl($scope, $sce) { + $scope.snippet = + '<p style="color:blue">an html\n' + + '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' + + 'snippet</p>'; + $scope.deliberatelyTrustDangerousSnippet = function() { + return $sce.trustAsHtml($scope.snippet); + }; + } + </script> + <div ng-controller="Ctrl"> + Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea> + <table> + <tr> + <td>Directive</td> + <td>How</td> + <td>Source</td> + <td>Rendered</td> + </tr> + <tr id="bind-html-with-sanitize"> + <td>ng-bind-html</td> + <td>Automatically uses $sanitize</td> + <td><pre><div ng-bind-html="snippet"><br/></div></pre></td> + <td><div ng-bind-html="snippet"></div></td> + </tr> + <tr id="bind-html-with-trust"> + <td>ng-bind-html</td> + <td>Bypass $sanitize by explicitly trusting the dangerous value</td> + <td> + <pre><div ng-bind-html="deliberatelyTrustDangerousSnippet()"> +</div></pre> + </td> + <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td> + </tr> + <tr id="bind-default"> + <td>ng-bind</td> + <td>Automatically escapes</td> + <td><pre><div ng-bind="snippet"><br/></div></pre></td> + <td><div ng-bind="snippet"></div></td> + </tr> + </table> + </div> + </doc:source> + <doc:scenario> + it('should sanitize the html snippet by default', function() { + expect(using('#bind-html-with-sanitize').element('div').html()). + toBe('<p>an html\n<em>click here</em>\nsnippet</p>'); + }); + + it('should inline raw snippet if bound to a trusted value', function() { + expect(using('#bind-html-with-trust').element("div").html()). + toBe("<p style=\"color:blue\">an html\n" + + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + + "snippet</p>"); + }); + + it('should escape snippet without any filter', function() { + expect(using('#bind-default').element('div').html()). + toBe("<p style=\"color:blue\">an html\n" + + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + + "snippet</p>"); + }); + + it('should update', function() { + input('snippet').enter('new <b onclick="alert(1)">text</b>'); + expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new <b>text</b>'); + expect(using('#bind-html-with-trust').element('div').html()).toBe( + 'new <b onclick="alert(1)">text</b>'); + expect(using('#bind-default').element('div').html()).toBe( + "new <b onclick=\"alert(1)\">text</b>"); + }); + </doc:scenario> + </doc:example> + */ +var $sanitize = function(html) { + var buf = []; + htmlParser(html, htmlSanitizeWriter(buf)); + return buf.join(''); +}; + + +// Regular Expressions for parsing tags and attributes +var START_TAG_REGEXP = + /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, + END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/, + ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, + BEGIN_TAG_REGEXP = /^</, + BEGING_END_TAGE_REGEXP = /^<\s*\//, + COMMENT_REGEXP = /<!--(.*?)-->/g, + DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i, + CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g, + URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/i, + // Match everything outside of normal chars and " (quote character) + NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; + + +// Good source of info about elements and attributes +// http://dev.w3.org/html5/spec/Overview.html#semantics +// http://simon.html5.org/html-elements + +// Safe Void Elements - HTML5 +// http://dev.w3.org/html5/spec/Overview.html#void-elements +var voidElements = makeMap("area,br,col,hr,img,wbr"); + +// Elements that you can, intentionally, leave open (and which close themselves) +// http://dev.w3.org/html5/spec/Overview.html#optional-tags +var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"), + optionalEndTagInlineElements = makeMap("rp,rt"), + optionalEndTagElements = angular.extend({}, + optionalEndTagInlineElements, + optionalEndTagBlockElements); + +// Safe Block Elements - HTML5 +var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," + + "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," + + "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")); + +// Inline Elements - HTML5 +var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," + + "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," + + "samp,small,span,strike,strong,sub,sup,time,tt,u,var")); + + +// Special Elements (can contain anything) +var specialElements = makeMap("script,style"); + +var validElements = angular.extend({}, + voidElements, + blockElements, + inlineElements, + optionalEndTagElements); + +//Attributes that have href and hence need to be sanitized +var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap"); +var validAttrs = angular.extend({}, uriAttrs, makeMap( + 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+ + 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+ + 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+ + 'scope,scrolling,shape,span,start,summary,target,title,type,'+ + 'valign,value,vspace,width')); + +function makeMap(str) { + var obj = {}, items = str.split(','), i; + for (i = 0; i < items.length; i++) obj[items[i]] = true; + return obj; +} + + +/** + * @example + * htmlParser(htmlString, { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * }); + * + * @param {string} html string + * @param {object} handler + */ +function htmlParser( html, handler ) { + var index, chars, match, stack = [], last = html; + stack.last = function() { return stack[ stack.length - 1 ]; }; + + while ( html ) { + chars = true; + + // Make sure we're not in a script or style element + if ( !stack.last() || !specialElements[ stack.last() ] ) { + + // Comment + if ( html.indexOf("<!--") === 0 ) { + // comments containing -- are not allowed unless they terminate the comment + index = html.indexOf("--", 4); + + if ( index >= 0 && html.lastIndexOf("-->", index) === index) { + if (handler.comment) handler.comment( html.substring( 4, index ) ); + html = html.substring( index + 3 ); + chars = false; + } + // DOCTYPE + } else if ( DOCTYPE_REGEXP.test(html) ) { + match = html.match( DOCTYPE_REGEXP ); + + if ( match ) { + html = html.replace( match[0] , ''); + chars = false; + } + // end tag + } else if ( BEGING_END_TAGE_REGEXP.test(html) ) { + match = html.match( END_TAG_REGEXP ); + + if ( match ) { + html = html.substring( match[0].length ); + match[0].replace( END_TAG_REGEXP, parseEndTag ); + chars = false; + } + + // start tag + } else if ( BEGIN_TAG_REGEXP.test(html) ) { + match = html.match( START_TAG_REGEXP ); + + if ( match ) { + html = html.substring( match[0].length ); + match[0].replace( START_TAG_REGEXP, parseStartTag ); + chars = false; + } + } + + if ( chars ) { + index = html.indexOf("<"); + + var text = index < 0 ? html : html.substring( 0, index ); + html = index < 0 ? "" : html.substring( index ); + + if (handler.chars) handler.chars( decodeEntities(text) ); + } + + } else { + html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'), + function(all, text){ + text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1"); + + if (handler.chars) handler.chars( decodeEntities(text) ); + + return ""; + }); + + parseEndTag( "", stack.last() ); + } + + if ( html == last ) { + throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " + + "of html: {0}", html); + } + last = html; + } + + // Clean up any remaining tags + parseEndTag(); + + function parseStartTag( tag, tagName, rest, unary ) { + tagName = angular.lowercase(tagName); + if ( blockElements[ tagName ] ) { + while ( stack.last() && inlineElements[ stack.last() ] ) { + parseEndTag( "", stack.last() ); + } + } + + if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) { + parseEndTag( "", tagName ); + } + + unary = voidElements[ tagName ] || !!unary; + + if ( !unary ) + stack.push( tagName ); + + var attrs = {}; + + rest.replace(ATTR_REGEXP, + function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) { + var value = doubleQuotedValue + || singleQuotedValue + || unquotedValue + || ''; + + attrs[name] = decodeEntities(value); + }); + if (handler.start) handler.start( tagName, attrs, unary ); + } + + function parseEndTag( tag, tagName ) { + var pos = 0, i; + tagName = angular.lowercase(tagName); + if ( tagName ) + // Find the closest opened tag of the same type + for ( pos = stack.length - 1; pos >= 0; pos-- ) + if ( stack[ pos ] == tagName ) + break; + + if ( pos >= 0 ) { + // Close all the open elements, up the stack + for ( i = stack.length - 1; i >= pos; i-- ) + if (handler.end) handler.end( stack[ i ] ); + + // Remove the open elements from the stack + stack.length = pos; + } + } +} + +/** + * decodes all entities into regular string + * @param value + * @returns {string} A string with decoded entities. + */ +var hiddenPre=document.createElement("pre"); +function decodeEntities(value) { + hiddenPre.innerHTML=value.replace(/</g,"<"); + return hiddenPre.innerText || hiddenPre.textContent || ''; +} + +/** + * Escapes all potentially dangerous characters, so that the + * resulting string can be safely inserted into attribute or + * element text. + * @param value + * @returns escaped text + */ +function encodeEntities(value) { + return value. + replace(/&/g, '&'). + replace(NON_ALPHANUMERIC_REGEXP, function(value){ + return '' + value.charCodeAt(0) + ';'; + }). + replace(/</g, '<'). + replace(/>/g, '>'); +} + +/** + * create an HTML/XML writer which writes to buffer + * @param {Array} buf use buf.jain('') to get out sanitized html string + * @returns {object} in the form of { + * start: function(tag, attrs, unary) {}, + * end: function(tag) {}, + * chars: function(text) {}, + * comment: function(text) {} + * } + */ +function htmlSanitizeWriter(buf){ + var ignore = false; + var out = angular.bind(buf, buf.push); + return { + start: function(tag, attrs, unary){ + tag = angular.lowercase(tag); + if (!ignore && specialElements[tag]) { + ignore = tag; + } + if (!ignore && validElements[tag] === true) { + out('<'); + out(tag); + angular.forEach(attrs, function(value, key){ + var lkey=angular.lowercase(key); + if (validAttrs[lkey]===true && (uriAttrs[lkey]!==true || value.match(URI_REGEXP))) { + out(' '); + out(key); + out('="'); + out(encodeEntities(value)); + out('"'); + } + }); + out(unary ? '/>' : '>'); + } + }, + end: function(tag){ + tag = angular.lowercase(tag); + if (!ignore && validElements[tag] === true) { + out('</'); + out(tag); + out('>'); + } + if (tag == ignore) { + ignore = false; + } + }, + chars: function(chars){ + if (!ignore) { + out(encodeEntities(chars)); + } + } + }; +} + + +// define ngSanitize module and register $sanitize service +angular.module('ngSanitize', []).value('$sanitize', $sanitize); + +/* global htmlSanitizeWriter: false */ + +/** + * @ngdoc filter + * @name ngSanitize.filter:linky + * @function + * + * @description + * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and + * plain email address links. + * + * Requires the {@link ngSanitize `ngSanitize`} module to be installed. + * + * @param {string} text Input text. + * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in. + * @returns {string} Html-linkified text. + * + * @usage + <span ng-bind-html="linky_expression | linky"></span> + * + * @example + <doc:example module="ngSanitize"> + <doc:source> + <script> + function Ctrl($scope) { + $scope.snippet = + 'Pretty text with some links:\n'+ + 'http://angularjs.org/,\n'+ + 'mailto:us@somewhere.org,\n'+ + 'another@somewhere.org,\n'+ + 'and one more: ftp://127.0.0.1/.'; + $scope.snippetWithTarget = 'http://angularjs.org/'; + } + </script> + <div ng-controller="Ctrl"> + Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea> + <table> + <tr> + <td>Filter</td> + <td>Source</td> + <td>Rendered</td> + </tr> + <tr id="linky-filter"> + <td>linky filter</td> + <td> + <pre><div ng-bind-html="snippet | linky"><br></div></pre> + </td> + <td> + <div ng-bind-html="snippet | linky"></div> + </td> + </tr> + <tr id="linky-target"> + <td>linky target</td> + <td> + <pre><div ng-bind-html="snippetWithTarget | linky:'_blank'"><br></div></pre> + </td> + <td> + <div ng-bind-html="snippetWithTarget | linky:'_blank'"></div> + </td> + </tr> + <tr id="escaped-html"> + <td>no filter</td> + <td><pre><div ng-bind="snippet"><br></div></pre></td> + <td><div ng-bind="snippet"></div></td> + </tr> + </table> + </doc:source> + <doc:scenario> + it('should linkify the snippet with urls', function() { + expect(using('#linky-filter').binding('snippet | linky')). + toBe('Pretty text with some links: ' + + '<a href="http://angularjs.org/">http://angularjs.org/</a>, ;' + + '<a href="mailto:us@somewhere.org">us@somewhere.org</a>, ' + + '<a href="mailto:another@somewhere.org">another@somewhere.org</a>, ' + + 'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.'); + }); + + it ('should not linkify snippet without the linky filter', function() { + expect(using('#escaped-html').binding('snippet')). + toBe("Pretty text with some links:\n" + + "http://angularjs.org/,\n" + + "mailto:us@somewhere.org,\n" + + "another@somewhere.org,\n" + + "and one more: ftp://127.0.0.1/."); + }); + + it('should update', function() { + input('snippet').enter('new http://link.'); + expect(using('#linky-filter').binding('snippet | linky')). + toBe('new <a href="http://link">http://link</a>.'); + expect(using('#escaped-html').binding('snippet')).toBe('new http://link.'); + }); + + it('should work with the target property', function() { + expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")). + toBe('<a target="_blank" href="http://angularjs.org/">http://angularjs.org/</a>'); + }); + </doc:scenario> + </doc:example> + */ +angular.module('ngSanitize').filter('linky', function() { + var LINKY_URL_REGEXP = + /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/, + MAILTO_REGEXP = /^mailto:/; + + return function(text, target) { + if (!text) return text; + var match; + var raw = text; + var html = []; + // TODO(vojta): use $sanitize instead + var writer = htmlSanitizeWriter(html); + var url; + var i; + var properties = {}; + if (angular.isDefined(target)) { + properties.target = target; + } + while ((match = raw.match(LINKY_URL_REGEXP))) { + // We can not end in these as they are sometimes found at the end of the sentence + url = match[0]; + // if we did not match ftp/http/mailto then assume mailto + if (match[2] == match[3]) url = 'mailto:' + url; + i = match.index; + writer.chars(raw.substr(0, i)); + properties.href = url; + writer.start('a', properties); + writer.chars(match[0].replace(MAILTO_REGEXP, '')); + writer.end('a'); + raw = raw.substring(i + match[0].length); + } + writer.chars(raw); + return html.join(''); + }; +}); + + +})(window, window.angular); Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-touch.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-touch.js (rev 0) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular-touch.js 2013-11-10 11:10:19 UTC (rev 225) @@ -0,0 +1,563 @@ +/** %%Ignore-License + * @license AngularJS v1.2.0 + * (c) 2010-2012 Google, Inc. http://angularjs.org + * License: MIT + */ +(function(window, angular, undefined) {'use strict'; + +/** + * @ngdoc overview + * @name ngTouch + * @description + * + * # ngTouch + * + * The `ngTouch` module provides touch events and other helpers for touch-enabled devices. + * The implementation is based on jQuery Mobile touch event handling + * ([jquerymobile.com](http://jquerymobile.com/)). + * + * {@installModule touch} + * + * See {@link ngTouch.$swipe `$swipe`} for usage. + * + * <div doc-module-components="ngTouch"></div> + * + */ + +// define ngTouch module +/* global -ngTouch */ +var ngTouch = angular.module('ngTouch', []); + +/* global ngTouch: false */ + + /** + * @ngdoc object + * @name ngTouch.$swipe + * + * @description + * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe + * behavior, to make implementing swipe-related directives more convenient. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by + * `ngCarousel` in a separate component. + * + * # Usage + * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element + * which is to be watched for swipes, and an object with four handler functions. See the + * documentation for `bind` below. + */ + +ngTouch.factory('$swipe', [function() { + // The total distance in any direction before we make the call on swipe vs. scroll. + var MOVE_BUFFER_RADIUS = 10; + + function getCoordinates(event) { + var touches = event.touches && event.touches.length ? event.touches : [event]; + var e = (event.changedTouches && event.changedTouches[0]) || + (event.originalEvent && event.originalEvent.changedTouches && + event.originalEvent.changedTouches[0]) || + touches[0].originalEvent || touches[0]; + + return { + x: e.clientX, + y: e.clientY + }; + } + + return { + /** + * @ngdoc method + * @name ngTouch.$swipe#bind + * @methodOf ngTouch.$swipe + * + * @description + * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an + * object containing event handlers. + * + * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end` + * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`. + * + * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is + * watching for `touchmove` or `mousemove` events. These events are ignored until the total + * distance moved in either dimension exceeds a small threshold. + * + * Once this threshold is exceeded, either the horizontal or vertical delta is greater. + * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow. + * - If the vertical distance is greater, this is a scroll, and we let the browser take over. + * A `cancel` event is sent. + * + * `move` is called on `mousemove` and `touchmove` after the above logic has determined that + * a swipe is in progress. + * + * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`. + * + * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling + * as described above. + * + */ + bind: function(element, eventHandlers) { + // Absolute total movement, used to control swipe vs. scroll. + var totalX, totalY; + // Coordinates of the start position. + var startCoords; + // Last event's position. + var lastPos; + // Whether a swipe is active. + var active = false; + + element.on('touchstart mousedown', function(event) { + startCoords = getCoordinates(event); + active = true; + totalX = 0; + totalY = 0; + lastPos = startCoords; + eventHandlers['start'] && eventHandlers['start'](startCoords, event); + }); + + element.on('touchcancel', function(event) { + active = false; + eventHandlers['cancel'] && eventHandlers['cancel'](event); + }); + + element.on('touchmove mousemove', function(event) { + if (!active) return; + + // Android will send a touchcancel if it thinks we're starting to scroll. + // So when the total distance (+ or - or both) exceeds 10px in either direction, + // we either: + // - On totalX > totalY, we send preventDefault() and treat this as a swipe. + // - On totalY > totalX, we let the browser handle it as a scroll. + + if (!startCoords) return; + var coords = getCoordinates(event); + + totalX += Math.abs(coords.x - lastPos.x); + totalY += Math.abs(coords.y - lastPos.y); + + lastPos = coords; + + if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) { + return; + } + + // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll. + if (totalY > totalX) { + // Allow native scrolling to take over. + active = false; + eventHandlers['cancel'] && eventHandlers['cancel'](event); + return; + } else { + // Prevent the browser from scrolling. + event.preventDefault(); + eventHandlers['move'] && eventHandlers['move'](coords, event); + } + }); + + element.on('touchend mouseup', function(event) { + if (!active) return; + active = false; + eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event); + }); + } + }; +}]); + +/* global ngTouch: false */ + +/** + * @ngdoc directive + * @name ngTouch.directive:ngClick + * + * @description + * A more powerful replacement for the default ngClick designed to be used on touchscreen + * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending + * the click event. This version handles them immediately, and then prevents the + * following click event from propagating. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * This directive can fall back to using an ordinary click event, and so works on desktop + * browsers as well as mobile. + * + * This directive also sets the CSS class `ng-click-active` while the element is being held + * down (by a mouse click or touch) so you can restyle the depressed element if you wish. + * + * @element ANY + * @param {expression} ngClick {@link guide/expression Expression} to evaluate + * upon tap. (Event object is available as `$event`) + * + * @example + <doc:example> + <doc:source> + <button ng-click="count = count + 1" ng-init="count=0"> + Increment + </button> + count: {{ count }} + </doc:source> + </doc:example> + */ + +ngTouch.config(['$provide', function($provide) { + $provide.decorator('ngClickDirective', ['$delegate', function($delegate) { + // drop the default ngClick directive + $delegate.shift(); + return $delegate; + }]); +}]); + +ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement', + function($parse, $timeout, $rootElement) { + var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag. + var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers. + var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click + var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks. + + var ACTIVE_CLASS_NAME = 'ng-click-active'; + var lastPreventedTime; + var touchCoordinates; + + + // TAP EVENTS AND GHOST CLICKS + // + // Why tap events? + // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're + // double-tapping, and then fire a click event. + // + // This delay sucks and makes mobile apps feel unresponsive. + // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when + // the user has tapped on something. + // + // What happens when the browser then generates a click event? + // The browser, of course, also detects the tap and fires a click after a delay. This results in + // tapping/clicking twice. So we do "clickbusting" to prevent it. + // + // How does it work? + // We attach global touchstart and click handlers, that run during the capture (early) phase. + // So the sequence for a tap is: + // - global touchstart: Sets an "allowable region" at the point touched. + // - element's touchstart: Starts a touch + // (- touchmove or touchcancel ends the touch, no click follows) + // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold + // too long) and fires the user's tap handler. The touchend also calls preventGhostClick(). + // - preventGhostClick() removes the allowable region the global touchstart created. + // - The browser generates a click event. + // - The global click handler catches the click, and checks whether it was in an allowable region. + // - If preventGhostClick was called, the region will have been removed, the click is busted. + // - If the region is still there, the click proceeds normally. Therefore clicks on links and + // other elements without ngTap on them work normally. + // + // This is an ugly, terrible hack! + // Yeah, tell me about it. The alternatives are using the slow click events, or making our users + // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular + // encapsulates this ugly logic away from the user. + // + // Why not just put click handlers on the element? + // We do that too, just to be sure. The problem is that the tap event might have caused the DOM + // to change, so that the click fires in the same position but something else is there now. So + // the handlers are global and care only about coordinates and not elements. + + // Checks if the coordinates are close enough to be within the region. + function hit(x1, y1, x2, y2) { + return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD; + } + + // Checks a list of allowable regions against a click location. + // Returns true if the click should be allowed. + // Splices out the allowable region from the list after it has been used. + function checkAllowableRegions(touchCoordinates, x, y) { + for (var i = 0; i < touchCoordinates.length; i += 2) { + if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) { + touchCoordinates.splice(i, i + 2); + return true; // allowable region + } + } + return false; // No allowable region; bust it. + } + + // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick + // was called recently. + function onClick(event) { + if (Date.now() - lastPreventedTime > PREVENT_DURATION) { + return; // Too old. + } + + var touches = event.touches && event.touches.length ? event.touches : [event]; + var x = touches[0].clientX; + var y = touches[0].clientY; + // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label + // and on the input element). Depending on the exact browser, this second click we don't want + // to bust has either (0,0) or negative coordinates. + if (x < 1 && y < 1) { + return; // offscreen + } + + // Look for an allowable region containing this click. + // If we find one, that means it was created by touchstart and not removed by + // preventGhostClick, so we don't bust it. + if (checkAllowableRegions(touchCoordinates, x, y)) { + return; + } + + // If we didn't find an allowable region, bust the click. + event.stopPropagation(); + event.preventDefault(); + + // Blur focused form elements + event.target && event.target.blur(); + } + + + // Global touchstart handler that creates an allowable region for a click event. + // This allowable region can be removed by preventGhostClick if we want to bust it. + function onTouchStart(event) { + var touches = event.touches && event.touches.length ? event.touches : [event]; + var x = touches[0].clientX; + var y = touches[0].clientY; + touchCoordinates.push(x, y); + + $timeout(function() { + // Remove the allowable region. + for (var i = 0; i < touchCoordinates.length; i += 2) { + if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) { + touchCoordinates.splice(i, i + 2); + return; + } + } + }, PREVENT_DURATION, false); + } + + // On the first call, attaches some event handlers. Then whenever it gets called, it creates a + // zone around the touchstart where clicks will get busted. + function preventGhostClick(x, y) { + if (!touchCoordinates) { + $rootElement[0].addEventListener('click', onClick, true); + $rootElement[0].addEventListener('touchstart', onTouchStart, true); + touchCoordinates = []; + } + + lastPreventedTime = Date.now(); + + checkAllowableRegions(touchCoordinates, x, y); + } + + // Actual linking function. + return function(scope, element, attr) { + var clickHandler = $parse(attr.ngClick), + tapping = false, + tapElement, // Used to blur the element after a tap. + startTime, // Used to check if the tap was held too long. + touchStartX, + touchStartY; + + function resetState() { + tapping = false; + element.removeClass(ACTIVE_CLASS_NAME); + } + + element.on('touchstart', function(event) { + tapping = true; + tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement. + // Hack for Safari, which can target text nodes instead of containers. + if(tapElement.nodeType == 3) { + tapElement = tapElement.parentNode; + } + + element.addClass(ACTIVE_CLASS_NAME); + + startTime = Date.now(); + + var touches = event.touches && event.touches.length ? event.touches : [event]; + var e = touches[0].originalEvent || touches[0]; + touchStartX = e.clientX; + touchStartY = e.clientY; + }); + + element.on('touchmove', function(event) { + resetState(); + }); + + element.on('touchcancel', function(event) { + resetState(); + }); + + element.on('touchend', function(event) { + var diff = Date.now() - startTime; + + var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches : + ((event.touches && event.touches.length) ? event.touches : [event]); + var e = touches[0].originalEvent || touches[0]; + var x = e.clientX; + var y = e.clientY; + var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) ); + + if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) { + // Call preventGhostClick so the clickbuster will catch the corresponding click. + preventGhostClick(x, y); + + // Blur the focused element (the button, probably) before firing the callback. + // This doesn't work perfectly on Android Chrome, but seems to work elsewhere. + // I couldn't get anything to work reliably on Android Chrome. + if (tapElement) { + tapElement.blur(); + } + + if (!angular.isDefined(attr.disabled) || attr.disabled === false) { + element.triggerHandler('click', [event]); + } + } + + resetState(); + }); + + // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click + // something else nearby. + element.onclick = function(event) { }; + + // Actual click handler. + // There are three different kinds of clicks, only two of which reach this point. + // - On desktop browsers without touch events, their clicks will always come here. + // - On mobile browsers, the simulated "fast" click will call this. + // - But the browser's follow-up slow click will be "busted" before it reaches this handler. + // Therefore it's safe to use this directive on both mobile and desktop. + element.on('click', function(event, touchend) { + scope.$apply(function() { + clickHandler(scope, {$event: (touchend || event)}); + }); + }); + + element.on('mousedown', function(event) { + element.addClass(ACTIVE_CLASS_NAME); + }); + + element.on('mousemove mouseup', function(event) { + element.removeClass(ACTIVE_CLASS_NAME); + }); + + }; +}]); + +/* global ngTouch: false */ + +/** + * @ngdoc directive + * @name ngTouch.directive:ngSwipeLeft + * + * @description + * Specify custom behavior when an element is swiped to the left on a touchscreen device. + * A leftward swipe is a quick, right-to-left slide of the finger. + * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag + * too. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * @element ANY + * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate + * upon left swipe. (Event object is available as `$event`) + * + * @example + <doc:example> + <doc:source> + <div ng-show="!showActions" ng-swipe-left="showActions = true"> + Some list content, like an email in the inbox + </div> + <div ng-show="showActions" ng-swipe-right="showActions = false"> + <button ng-click="reply()">Reply</button> + <button ng-click="delete()">Delete</button> + </div> + </doc:source> + </doc:example> + */ + +/** + * @ngdoc directive + * @name ngTouch.directive:ngSwipeRight + * + * @description + * Specify custom behavior when an element is swiped to the right on a touchscreen device. + * A rightward swipe is a quick, left-to-right slide of the finger. + * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag + * too. + * + * Requires the {@link ngTouch `ngTouch`} module to be installed. + * + * @element ANY + * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate + * upon right swipe. (Event object is available as `$event`) + * + * @example + <doc:example> + <doc:source> + <div ng-show="!showActions" ng-swipe-left="showActions = true"> + Some list content, like an email in the inbox + </div> + <div ng-show="showActions" ng-swipe-right="showActions = false"> + <button ng-click="reply()">Reply</button> + <button ng-click="delete()">Delete</button> + </div> + </doc:source> + </doc:example> + */ + +function makeSwipeDirective(directiveName, direction, eventName) { + ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) { + // The maximum vertical delta for a swipe should be less than 75px. + var MAX_VERTICAL_DISTANCE = 75; + // Vertical distance should not be more than a fraction of the horizontal distance. + var MAX_VERTICAL_RATIO = 0.3; + // At least a 30px lateral motion is necessary for a swipe. + var MIN_HORIZONTAL_DISTANCE = 30; + + return function(scope, element, attr) { + var swipeHandler = $parse(attr[directiveName]); + + var startCoords, valid; + + function validSwipe(coords) { + // Check that it's within the coordinates. + // Absolute vertical distance must be within tolerances. + // Horizontal distance, we take the current X - the starting X. + // This is negative for leftward swipes and positive for rightward swipes. + // After multiplying by the direction (-1 for left, +1 for right), legal swipes + // (ie. same direction as the directive wants) will have a positive delta and + // illegal ones a negative delta. + // Therefore this delta must be positive, and larger than the minimum. + if (!startCoords) return false; + var deltaY = Math.abs(coords.y - startCoords.y); + var deltaX = (coords.x - startCoords.x) * direction; + return valid && // Short circuit for already-invalidated swipes. + deltaY < MAX_VERTICAL_DISTANCE && + deltaX > 0 && + deltaX > MIN_HORIZONTAL_DISTANCE && + deltaY / deltaX < MAX_VERTICAL_RATIO; + } + + $swipe.bind(element, { + 'start': function(coords, event) { + startCoords = coords; + valid = true; + }, + 'cancel': function(event) { + valid = false; + }, + 'end': function(coords, event) { + if (validSwipe(coords)) { + scope.$apply(function() { + element.triggerHandler(eventName); + swipeHandler(scope, {$event: event}); + }); + } + } + }); + }; + }]); +} + +// Left is negative X-coordinate, right is positive. +makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft'); +makeSwipeDirective('ngSwipeRight', 1, 'swiperight'); + + + +})(window, window.angular); Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,5 +1,5 @@ /** %%Ignore-License - * @license AngularJS v1.2.0-rc.3 + * @license AngularJS v1.2.0 * (c) 2010-2012 Google, Inc. http://angularjs.org * License: MIT */ @@ -79,6 +79,90 @@ }; } +/* We need to tell jshint what variables are being exported */ +/* global + -angular, + -msie, + -jqLite, + -jQuery, + -slice, + -push, + -toString, + -ngMinErr, + -_angular, + -angularModule, + -nodeName_, + -uid, + + -lowercase, + -uppercase, + -manualLowercase, + -manualUppercase, + -nodeName_, + -isArrayLike, + -forEach, + -sortedKeys, + -forEachSorted, + -reverseParams, + -nextUid, + -setHashKey, + -extend, + -int, + -inherit, + -noop, + -identity, + -valueFn, + -isUndefined, + -isDefined, + -isObject, + -isString, + -isNumber, + -isDate, + -isArray, + -isFunction, + -isRegExp, + -isWindow, + -isScope, + -isFile, + -isBoolean, + -trim, + -isElement, + -makeMap, + -map, + -size, + -includes, + -indexOf, + -arrayRemove, + -isLeafNode, + -copy, + -shallowCopy, + -equals, + -csp, + -concat, + -sliceArgs, + -bind, + -toJsonReplacer, + -toJson, + -fromJson, + -toBoolean, + -startingTag, + -tryDecodeURIComponent, + -parseKeyValue, + -toKeyValue, + -encodeUriSegment, + -encodeUriQuery, + -angularInit, + -bootstrap, + -snake_case, + -bindJQuery, + -assertArg, + -assertArgFn, + -assertNotHasOwnProperty, + -getter, + -getBlockElements + +*/ + //////////////////////////////////// /** @@ -106,11 +190,13 @@ var manualLowercase = function(s) { + /* jshint bitwise: false */ return isString(s) ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);}) : s; }; var manualUppercase = function(s) { + /* jshint bitwise: false */ return isString(s) ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);}) : s; @@ -156,7 +242,8 @@ /** * @private * @param {*} obj - * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, String ...) + * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, + * String ...) */ function isArrayLike(obj) { if (obj == null || isWindow(obj)) { @@ -250,7 +337,7 @@ * @returns {function(*, string)} */ function reverseParams(iteratorFn) { - return function(value, key) { iteratorFn(key, value) }; + return function(value, key) { iteratorFn(key, value); }; } /** @@ -609,17 +696,17 @@ * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array. */ function size(obj, ownPropsOnly) { - var size = 0, key; + var count = 0, key; if (isArray(obj) || isString(obj)) { return obj.length; } else if (isObject(obj)){ for (key in obj) if (!ownPropsOnly || obj.hasOwnProperty(key)) - size++; + count++; } - return size; + return count; } @@ -669,9 +756,6 @@ * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned. * * If `source` is identical to 'destination' an exception will be thrown. * - * Note: this function is used to augment the Object type in Angular expressions. See - * {@link ng.$filter} for more information about Angular arrays. - * * @param {*} source The source that will be used to make a copy. * Can be any type, including primitives, `null`, and `undefined`. * @param {(Object|Array)=} destination Destination into which the source is copied. If @@ -716,7 +800,8 @@ */ function copy(source, destination){ if (isWindow(source) || isScope(source)) { - throw ngMinErr('cpws', "Can't copy! Making copies of Window or Scope instances is not supported."); + throw ngMinErr('cpws', + "Can't copy! Making copies of Window or Scope instances is not supported."); } if (!destination) { @@ -733,7 +818,8 @@ } } } else { - if (source === destination) throw ngMinErr('cpi', "Can't copy! Source and destination are identical."); + if (source === destination) throw ngMinErr('cpi', + "Can't copy! Source and destination are identical."); if (isArray(source)) { destination.length = 0; for ( var i = 0; i < source.length; i++) { @@ -777,13 +863,14 @@ * @function * * @description - * Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and - * objects. + * Determines if two objects or two values are equivalent. Supports value types, regular + * expressions, arrays and objects. * * Two objects or values are considered equivalent if at least one of the following is true: * * * Both objects or values pass `===` comparison. - * * Both objects or values are of the same type and all of their properties pass `===` comparison. + * * Both objects or values are of the same type and all of their properties are equal by + * comparing them with `angular.equals`. * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) * * Both values represent the same regular expression (In JavasScript, * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual @@ -839,6 +926,13 @@ } +function csp() { + return (document.securityPolicy && document.securityPolicy.isActive) || + (document.querySelector && + !!(document.querySelector('[ng-csp]') || document.querySelector('[data-ng-csp]'))); +} + + function concat(array1, array2, index) { return array1.concat(slice.call(array2, index)); } @@ -848,6 +942,7 @@ } +/* jshint -W101 */ /** * @ngdoc function * @name angular.bind @@ -856,14 +951,15 @@ * @description * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for * `fn`). You can supply optional `args` that are prebound to the function. This feature is also - * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as distinguished - * from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_applica...). + * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as + * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_applica...). * * @param {Object} self Context which `fn` should be evaluated in. * @param {function()} fn Function to be bound. * @param {...*} args Optional arguments to be prebound to the `fn` function call. * @returns {function()} Function that wraps the `fn` with all the specified bindings. */ +/* jshint +W101 */ function bind(self, fn) { var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : []; if (isFunction(fn) && !(fn instanceof RegExp)) { @@ -1023,10 +1119,12 @@ forEach(obj, function(value, key) { if (isArray(value)) { forEach(value, function(arrayValue) { - parts.push(encodeUriQuery(key, true) + (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true))); + parts.push(encodeUriQuery(key, true) + + (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true))); }); } else { - parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true))); + parts.push(encodeUriQuery(key, true) + + (value === true ? '' : '=' + encodeUriQuery(value, true))); } }); return parts.length ? parts.join('&') : ''; @@ -1088,8 +1186,8 @@ * designates the root of the application and is typically placed * at the root of the page. * - * The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an - * HTML document you must manually bootstrap them using {@link angular.bootstrap}. + * The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in + * an HTML document you must manually bootstrap them using {@link angular.bootstrap}. * Applications cannot be nested. * * In the example below if the `ngApp` directive were not placed @@ -1163,7 +1261,8 @@ * @param {Element} element DOM element which is the root of angular application. * @param {Array<String|Function|Array>=} modules an array of modules to load into the application. * Each item in the array should be the name of a predefined module or a (DI annotated) - * function that will be invoked by the injector as a run block. See: {@link angular.module modules} + * function that will be invoked by the injector as a run block. + * See: {@link angular.module modules} * @returns {AUTO.$injector} Returns the newly created injector for this app. */ function bootstrap(element, modules) { @@ -1187,7 +1286,6 @@ element.data('$injector', injector); compile(element)(scope); }); - animate.enabled(true); }] ); return injector; @@ -1224,14 +1322,16 @@ jqLite = jQuery; extend(jQuery.fn, { scope: JQLitePrototype.scope, + isolateScope: JQLitePrototype.isolateScope, controller: JQLitePrototype.controller, injector: JQLitePrototype.injector, inheritedData: JQLitePrototype.inheritedData }); - // Method signature: JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) - JQLitePatchJQueryRemove('remove', true, true, false); - JQLitePatchJQueryRemove('empty', false, false, false); - JQLitePatchJQueryRemove('html', false, false, true); + // Method signature: + // jqLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) + jqLitePatchJQueryRemove('remove', true, true, false); + jqLitePatchJQueryRemove('empty', false, false, false); + jqLitePatchJQueryRemove('html', false, false, true); } else { jqLite = JQLite; } @@ -1297,6 +1397,28 @@ } /** + * Return the siblings between `startNode` and `endNode`, inclusive + * @param {Object} object with `startNode` and `endNode` properties + * @returns jQlite object containing the elements + */ +function getBlockElements(block) { + if (block.startNode === block.endNode) { + return jqLite(block.startNode); + } + + var element = block.startNode; + var elements = [element]; + + do { + element = element.nextSibling; + if (!element) break; + elements.push(element); + } while (element !== block.endNode); + + return jqLite(elements); +} + +/** * @ngdoc interface * @name angular.Module * @description @@ -1321,7 +1443,8 @@ * @name angular.module * @description * - * The `angular.module` is a global place for creating, registering and retrieving Angular modules. + * The `angular.module` is a global place for creating, registering and retrieving Angular + * modules. * All modules (angular core or 3rd party) that should be available to an application must be * registered using this mechanism. * @@ -1359,10 +1482,10 @@ * {@link angular.bootstrap} to simplify this process for you. * * @param {!string} name The name of the module to create or retrieve. - * @param {Array.<string>=} requires If specified then new module is being created. If unspecified then the - * the module is being retrieved for further configuration. + * @param {Array.<string>=} requires If specified then new module is being created. If + * unspecified then the the module is being retrieved for further configuration. * @param {Function} configFn Optional configuration function for the module. Same as - * {@link angular.Module#config Module#config()}. + * {@link angular.Module#methods_config Module#config()}. * @returns {module} new module with the {@link angular.Module} api. */ return function module(name, requires, configFn) { @@ -1372,9 +1495,9 @@ } return ensure(modules, name, function() { if (!requires) { - throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled the module name " + - "or forgot to load it. If registering a module ensure that you specify the dependencies as the second " + - "argument.", name); + throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + + "the module name or forgot to load it. If registering a module ensure that you " + + "specify the dependencies as the second argument.", name); } /** @type {!Array.<Array.<*>>} */ @@ -1397,7 +1520,8 @@ * @propertyOf angular.Module * @returns {Array.<string>} List of module names which must be loaded before this module. * @description - * Holds the list of modules which the injector will load before the current module is loaded. + * Holds the list of modules which the injector will load before the current module is + * loaded. */ requires: requires, @@ -1416,7 +1540,8 @@ * @name angular.Module#provider * @methodOf angular.Module * @param {string} name service name - * @param {Function} providerType Construction function for creating new instance of the service. + * @param {Function} providerType Construction function for creating new instance of the + * service. * @description * See {@link AUTO.$provide#provider $provide.provider()}. */ @@ -1472,14 +1597,15 @@ * @name angular.Module#animation * @methodOf angular.Module * @param {string} name animation name - * @param {Function} animationFactory Factory function for creating new instance of an animation. + * @param {Function} animationFactory Factory function for creating new instance of an + * animation. * @description * * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. * * - * Defines an animation hook that can be later used with {@link ngAnimate.$animate $animate} service and - * directives that use this service. + * Defines an animation hook that can be later used with + * {@link ngAnimate.$animate $animate} service and directives that use this service. * * <pre> * module.animation('.animation-name', function($inject1, $inject2) { @@ -1532,7 +1658,7 @@ * @param {Function} directiveFactory Factory function for creating new instance of * directives. * @description - * See {@link ng.$compileProvider#directive $compileProvider.directive()}. + * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}. */ directive: invokeLater('$compileProvider', 'directive'), @@ -1579,7 +1705,7 @@ return function() { invokeQueue[insertMethod || 'push']([provider, method, arguments]); return moduleInstance; - } + }; } }); }; @@ -1587,6 +1713,80 @@ } +/* global + angularModule: true, + version: true, + + $LocaleProvider, + $CompileProvider, + + htmlAnchorDirective, + inputDirective, + inputDirective, + formDirective, + scriptDirective, + selectDirective, + styleDirective, + optionDirective, + ngBindDirective, + ngBindHtmlDirective, + ngBindTemplateDirective, + ngClassDirective, + ngClassEvenDirective, + ngClassOddDirective, + ngCspDirective, + ngCloakDirective, + ngControllerDirective, + ngFormDirective, + ngHideDirective, + ngIfDirective, + ngIncludeDirective, + ngInitDirective, + ngNonBindableDirective, + ngPluralizeDirective, + ngRepeatDirective, + ngShowDirective, + ngStyleDirective, + ngSwitchDirective, + ngSwitchWhenDirective, + ngSwitchDefaultDirective, + ngOptionsDirective, + ngTranscludeDirective, + ngModelDirective, + ngListDirective, + ngChangeDirective, + requiredDirective, + requiredDirective, + ngValueDirective, + ngAttributeAliasDirectives, + ngEventDirectives, + + $AnchorScrollProvider, + $AnimateProvider, + $BrowserProvider, + $CacheFactoryProvider, + $ControllerProvider, + $DocumentProvider, + $ExceptionHandlerProvider, + $FilterProvider, + $InterpolateProvider, + $IntervalProvider, + $HttpProvider, + $HttpBackendProvider, + $LocationProvider, + $LogProvider, + $ParseProvider, + $RootScopeProvider, + $QProvider, + $SceProvider, + $SceDelegateProvider, + $SnifferProvider, + $TemplateCacheProvider, + $TimeoutProvider, + $WindowProvider +*/ + + /** * @ngdoc property * @name angular.version @@ -1601,11 +1801,11 @@ * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". */ var version = { - full: '1.2.0-rc.3', // all of these placeholder strings will be replaced by grunt's + full: '1.2.0', // all of these placeholder strings will be replaced by grunt's major: 1, // package task - minor: 2, + minor: "NG_VERSION_MINOR", dot: 0, - codeName: 'ferocious-twitch' + codeName: 'timely-delivery' }; @@ -1631,12 +1831,13 @@ 'isNumber': isNumber, 'isElement': isElement, 'isArray': isArray, - '$$minErr': minErr, 'version': version, 'isDate': isDate, 'lowercase': lowercase, 'uppercase': uppercase, - 'callbacks': {counter: 0} + 'callbacks': {counter: 0}, + '$$minErr': minErr, + '$$csp': csp }); angularModule = setupModuleLoader(window); @@ -1664,7 +1865,6 @@ ngClass: ngClassDirective, ngClassEven: ngClassEvenDirective, ngClassOdd: ngClassOddDirective, - ngCsp: ngCspDirective, ngCloak: ngCloakDirective, ngController: ngControllerDirective, ngForm: ngFormDirective, @@ -1720,6 +1920,14 @@ ]); } +/* global + + -JQLitePrototype, + -addEventListenerFn, + -removeEventListenerFn, + -BOOLEAN_ATTR +*/ + ////////////////////////////////// //JQLite ////////////////////////////////// @@ -1797,6 +2005,9 @@ * - `injector()` - retrieves the injector of the current element or its parent. * - `scope()` - retrieves the {@link api/ng.$rootScope.Scope scope} of the current * element or its parent. + * - `isolateScope()` - retrieves an isolate {@link api/ng.$rootScope.Scope scope} if one is attached directly to the + * current element. This getter should be used only on elements that contain a directive which starts a new isolate + * scope. Calling `scope()` on this element always returns the original non-isolate scope. * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top * parent element is reached. * @@ -1842,13 +2053,14 @@ // ///////////////////////////////////////////// -function JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) { +function jqLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) { var originalJqFn = jQuery.fn[name]; originalJqFn = originalJqFn.$original || originalJqFn; removePatch.$original = originalJqFn; jQuery.fn[name] = removePatch; function removePatch(param) { + // jshint -W040 var list = filterElems && param ? [this.filter(param)] : [this], fireEvent = dispatchThis, set, setIndex, setLength, @@ -1894,30 +2106,30 @@ // http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx div.innerHTML = '<div> </div>' + element; // IE insanity to make NoScope elements work! div.removeChild(div.firstChild); // remove the superfluous div - JQLiteAddNodes(this, div.childNodes); + jqLiteAddNodes(this, div.childNodes); var fragment = jqLite(document.createDocumentFragment()); fragment.append(this); // detach the elements from the temporary DOM div. } else { - JQLiteAddNodes(this, element); + jqLiteAddNodes(this, element); } } -function JQLiteClone(element) { +function jqLiteClone(element) { return element.cloneNode(true); } -function JQLiteDealoc(element){ - JQLiteRemoveData(element); +function jqLiteDealoc(element){ + jqLiteRemoveData(element); for ( var i = 0, children = element.childNodes || []; i < children.length; i++) { - JQLiteDealoc(children[i]); + jqLiteDealoc(children[i]); } } -function JQLiteOff(element, type, fn, unsupported) { +function jqLiteOff(element, type, fn, unsupported) { if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument'); - var events = JQLiteExpandoStore(element, 'events'), - handle = JQLiteExpandoStore(element, 'handle'); + var events = jqLiteExpandoStore(element, 'events'), + handle = jqLiteExpandoStore(element, 'handle'); if (!handle) return; //no listeners registered @@ -1938,7 +2150,7 @@ } } -function JQLiteRemoveData(element, name) { +function jqLiteRemoveData(element, name) { var expandoId = element[jqName], expandoStore = jqCache[expandoId]; @@ -1950,14 +2162,14 @@ if (expandoStore.handle) { expandoStore.events.$destroy && expandoStore.handle({}, '$destroy'); - JQLiteOff(element); + jqLiteOff(element); } delete jqCache[expandoId]; element[jqName] = undefined; // ie does not allow deletion of attributes on elements. } } -function JQLiteExpandoStore(element, key, value) { +function jqLiteExpandoStore(element, key, value) { var expandoId = element[jqName], expandoStore = jqCache[expandoId || -1]; @@ -1972,14 +2184,14 @@ } } -function JQLiteData(element, key, value) { - var data = JQLiteExpandoStore(element, 'data'), +function jqLiteData(element, key, value) { + var data = jqLiteExpandoStore(element, 'data'), isSetter = isDefined(value), keyDefined = !isSetter && isDefined(key), isSimpleGetter = keyDefined && !isObject(key); if (!data && !isSimpleGetter) { - JQLiteExpandoStore(element, 'data', data = {}); + jqLiteExpandoStore(element, 'data', data = {}); } if (isSetter) { @@ -1998,13 +2210,13 @@ } } -function JQLiteHasClass(element, selector) { +function jqLiteHasClass(element, selector) { if (!element.getAttribute) return false; return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " "). indexOf( " " + selector + " " ) > -1); } -function JQLiteRemoveClass(element, cssClasses) { +function jqLiteRemoveClass(element, cssClasses) { if (cssClasses && element.setAttribute) { forEach(cssClasses.split(' '), function(cssClass) { element.setAttribute('class', trim( @@ -2016,7 +2228,7 @@ } } -function JQLiteAddClass(element, cssClasses) { +function jqLiteAddClass(element, cssClasses) { if (cssClasses && element.setAttribute) { var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ') .replace(/[\n\t]/g, " "); @@ -2032,7 +2244,7 @@ } } -function JQLiteAddNodes(root, elements) { +function jqLiteAddNodes(root, elements) { if (elements) { elements = (!elements.nodeName && isDefined(elements.length) && !isWindow(elements)) ? elements @@ -2043,11 +2255,11 @@ } } -function JQLiteController(element, name) { - return JQLiteInheritedData(element, '$' + (name || 'ngController' ) + 'Controller'); +function jqLiteController(element, name) { + return jqLiteInheritedData(element, '$' + (name || 'ngController' ) + 'Controller'); } -function JQLiteInheritedData(element, name, value) { +function jqLiteInheritedData(element, name, value) { element = jqLite(element); // if element is the document object work with the html element instead @@ -2055,9 +2267,13 @@ if(element[0].nodeType == 9) { element = element.find('html'); } + var names = isArray(name) ? name : [name]; while (element.length) { - if ((value = element.data(name)) !== undefined) return value; + + for (var i = 0, ii = names.length; i < ii; i++) { + if ((value = element.data(names[i])) !== undefined) return value; + } element = element.parent(); } } @@ -2081,7 +2297,9 @@ } else { this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9 // we can not use jqLite since we are not done loading and jQuery could be loaded later. + // jshint -W064 JQLite(window).on('load', trigger); // fallback to window.onload for others + // jshint +W064 } }, toString: function() { @@ -2123,24 +2341,30 @@ } forEach({ - data: JQLiteData, - inheritedData: JQLiteInheritedData, + data: jqLiteData, + inheritedData: jqLiteInheritedData, scope: function(element) { - return JQLiteInheritedData(element, '$scope'); + // Can't use jqLiteData here directly so we stay compatible with jQuery! + return jqLite(element).data('$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); }, - controller: JQLiteController , + isolateScope: function(element) { + // Can't use jqLiteData here directly so we stay compatible with jQuery! + return jqLite(element).data('$isolateScope') || jqLite(element).data('$isolateScopeNoTemplate'); + }, + controller: jqLiteController , + injector: function(element) { - return JQLiteInheritedData(element, '$injector'); + return jqLiteInheritedData(element, '$injector'); }, removeAttr: function(element,name) { element.removeAttribute(name); }, - hasClass: JQLiteHasClass, + hasClass: jqLiteHasClass, css: function(element, name, value) { name = camelCase(name); @@ -2216,7 +2440,7 @@ return getText; function getText(element, value) { - var textProp = NODE_TYPE_TEXT_PROPERTY[element.nodeType] + var textProp = NODE_TYPE_TEXT_PROPERTY[element.nodeType]; if (isUndefined(value)) { return textProp ? element[textProp] : ''; } @@ -2245,7 +2469,7 @@ return element.innerHTML; } for (var i = 0, childNodes = element.childNodes; i < childNodes.length; i++) { - JQLiteDealoc(childNodes[i]); + jqLiteDealoc(childNodes[i]); } element.innerHTML = value; } @@ -2256,14 +2480,14 @@ JQLite.prototype[name] = function(arg1, arg2) { var i, key; - // JQLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it + // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it // in a way that survives minification. - if (((fn.length == 2 && (fn !== JQLiteHasClass && fn !== JQLiteController)) ? arg1 : arg2) === undefined) { + if (((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2) === undefined) { if (isObject(arg1)) { // we are a write, but the object properties are the key/values for(i=0; i < this.length; i++) { - if (fn === JQLiteData) { + if (fn === jqLiteData) { // data() takes the whole object in jQuery fn(this[i], arg1); } else { @@ -2278,7 +2502,7 @@ // we are a read, so read the first child. var value = fn.$dv; // Only if we have $dv do we iterate over all, otherwise it is just the first element. - var jj = value == undefined ? Math.min(this.length, 1) : this.length; + var jj = (value === undefined) ? Math.min(this.length, 1) : this.length; for (var j = 0; j < jj; j++) { var nodeValue = fn(this[j], arg1, arg2); value = value ? value + nodeValue : nodeValue; @@ -2324,7 +2548,7 @@ } event.isDefaultPrevented = function() { - return event.defaultPrevented || event.returnValue == false; + return event.defaultPrevented || event.returnValue === false; }; forEach(events[type || event.type], function(fn) { @@ -2355,18 +2579,18 @@ // selector. ////////////////////////////////////////// forEach({ - removeData: JQLiteRemoveData, + removeData: jqLiteRemoveData, - dealoc: JQLiteDealoc, + dealoc: jqLiteDealoc, on: function onFn(element, type, fn, unsupported){ if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters'); - var events = JQLiteExpandoStore(element, 'events'), - handle = JQLiteExpandoStore(element, 'handle'); + var events = jqLiteExpandoStore(element, 'events'), + handle = jqLiteExpandoStore(element, 'handle'); - if (!events) JQLiteExpandoStore(element, 'events', events = {}); - if (!handle) JQLiteExpandoStore(element, 'handle', handle = createEventHandler(element, events)); + if (!events) jqLiteExpandoStore(element, 'events', events = {}); + if (!handle) jqLiteExpandoStore(element, 'handle', handle = createEventHandler(element, events)); forEach(type.split(' '), function(type){ var eventFns = events[type]; @@ -2375,6 +2599,7 @@ if (type == 'mouseenter' || type == 'mouseleave') { var contains = document.body.contains || document.body.compareDocumentPosition ? function( a, b ) { + // jshint bitwise: false var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( @@ -2414,17 +2639,17 @@ addEventListenerFn(element, type, handle); events[type] = []; } - eventFns = events[type] + eventFns = events[type]; } eventFns.push(fn); }); }, - off: JQLiteOff, + off: jqLiteOff, replaceWith: function(element, replaceNode) { var index, parent = element.parentNode; - JQLiteDealoc(element); + jqLiteDealoc(element); forEach(new JQLite(replaceNode), function(node){ if (index) { parent.insertBefore(node, index.nextSibling); @@ -2475,7 +2700,7 @@ }, remove: function(element) { - JQLiteDealoc(element); + jqLiteDealoc(element); var parent = element.parentNode; if (parent) parent.removeChild(element); }, @@ -2488,14 +2713,14 @@ }); }, - addClass: JQLiteAddClass, - removeClass: JQLiteRemoveClass, + addClass: jqLiteAddClass, + removeClass: jqLiteRemoveClass, toggleClass: function(element, selector, condition) { if (isUndefined(condition)) { - condition = !JQLiteHasClass(element, selector); + condition = !jqLiteHasClass(element, selector); } - (condition ? JQLiteAddClass : JQLiteRemoveClass)(element, selector); + (condition ? jqLiteAddClass : jqLiteRemoveClass)(element, selector); }, parent: function(element) { @@ -2520,11 +2745,11 @@ return element.getElementsByTagName(selector); }, - clone: JQLiteClone, + clone: jqLiteClone, triggerHandler: function(element, eventName, eventData) { - var eventFns = (JQLiteExpandoStore(element, 'events') || {})[eventName]; - + var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName]; + eventData = eventData || []; var event = [{ @@ -2543,17 +2768,17 @@ JQLite.prototype[name] = function(arg1, arg2, arg3) { var value; for(var i=0; i < this.length; i++) { - if (value == undefined) { + if (isUndefined(value)) { value = fn(this[i], arg1, arg2, arg3); - if (value !== undefined) { + if (isDefined(value)) { // any function which returns a value needs to be wrapped value = jqLite(value); } } else { - JQLiteAddNodes(value, fn(this[i], arg1, arg2, arg3)); + jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3)); } } - return value == undefined ? this : value; + return isDefined(value) ? value : this; }; // bind legacy bind/unbind to on/off @@ -2742,9 +2967,9 @@ * * ## Inference * - * In JavaScript calling `toString()` on a function returns the function definition. The definition can then be - * parsed and the function arguments can be extracted. *NOTE:* This does not work with minification, and obfuscation - * tools since these tools change the argument names. + * In JavaScript calling `toString()` on a function returns the function definition. The definition + * can then be parsed and the function arguments can be extracted. *NOTE:* This does not work with + * minification, and obfuscation tools since these tools change the argument names. * * ## `$inject` Annotation * By adding a `$inject` property onto a function the injection parameters can be specified. @@ -2776,8 +3001,8 @@ * @param {!function} fn The function to invoke. Function parameters are injected according to the * {@link guide/di $inject Annotation} rules. * @param {Object=} self The `this` for the invoked method. - * @param {Object=} locals Optional object. If preset then any argument names are read from this object first, before - * the `$injector` is consulted. + * @param {Object=} locals Optional object. If preset then any argument names are read from this + * object first, before the `$injector` is consulted. * @returns {*} the value returned by the invoked `fn` function. */ @@ -2798,12 +3023,13 @@ * @name AUTO.$injector#instantiate * @methodOf AUTO.$injector * @description - * Create a new instance of JS type. The method takes a constructor function invokes the new operator and supplies - * all of the arguments to the constructor function as specified by the constructor annotation. + * Create a new instance of JS type. The method takes a constructor function invokes the new + * operator and supplies all of the arguments to the constructor function as specified by the + * constructor annotation. * * @param {function} Type Annotated constructor function. - * @param {Object=} locals Optional object. If preset then any argument names are read from this object first, before - * the `$injector` is consulted. + * @param {Object=} locals Optional object. If preset then any argument names are read from this + * object first, before the `$injector` is consulted. * @returns {Object} new instance of `Type`. */ @@ -2813,14 +3039,16 @@ * @methodOf AUTO.$injector * * @description - * Returns an array of service names which the function is requesting for injection. This API is used by the injector - * to determine which services need to be injected into the function when the function is invoked. There are three - * ways in which the function can be annotated with the needed dependencies. + * Returns an array of service names which the function is requesting for injection. This API is + * used by the injector to determine which services need to be injected into the function when the + * function is invoked. There are three ways in which the function can be annotated with the needed + * dependencies. * * # Argument names * - * The simplest form is to extract the dependencies from the arguments of the function. This is done by converting - * the function into a string using `toString()` method and extracting the argument names. + * The simplest form is to extract the dependencies from the arguments of the function. This is done + * by converting the function into a string using `toString()` method and extracting the argument + * names. * <pre> * // Given * function MyController($scope, $route) { @@ -2831,13 +3059,13 @@ * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); * </pre> * - * This method does not work with code minification / obfuscation. For this reason the following annotation strategies - * are supported. + * This method does not work with code minification / obfuscation. For this reason the following + * annotation strategies are supported. * * # The `$inject` property * - * If a function has an `$inject` property and its value is an array of strings, then the strings represent names of - * services to be injected into the function. + * If a function has an `$inject` property and its value is an array of strings, then the strings + * represent names of services to be injected into the function. * <pre> * // Given * var MyController = function(obfuscatedScope, obfuscatedRoute) { @@ -2852,9 +3080,9 @@ * * # The array notation * - * It is often desirable to inline Injected functions and that's when setting the `$inject` property is very - * inconvenient. In these situations using the array notation to specify the dependencies in a way that survives - * minification is a better choice: + * It is often desirable to inline Injected functions and that's when setting the `$inject` property + * is very inconvenient. In these situations using the array notation to specify the dependencies in + * a way that survives minification is a better choice: * * <pre> * // We wish to write this (not minification / obfuscation safe) @@ -2880,8 +3108,8 @@ * ).toEqual(['$compile', '$rootScope']); * </pre> * - * @param {function|Array.<string|Function>} fn Function for which dependent service names need to be retrieved as described - * above. + * @param {function|Array.<string|Function>} fn Function for which dependent service names need to + * be retrieved as described above. * * @returns {Array.<string>} The names of the services which the function requires. */ @@ -2895,35 +3123,36 @@ * * @description * - * The {@link AUTO.$provide $provide} service has a number of methods for registering components with - * the {@link AUTO.$injector $injector}. Many of these functions are also exposed on {@link angular.Module}. + * The {@link AUTO.$provide $provide} service has a number of methods for registering components + * with the {@link AUTO.$injector $injector}. Many of these functions are also exposed on + * {@link angular.Module}. * * An Angular **service** is a singleton object created by a **service factory**. These **service * factories** are functions which, in turn, are created by a **service provider**. - * The **service providers** are constructor functions. When instantiated they must contain a property - * called `$get`, which holds the **service factory** function. - * + * The **service providers** are constructor functions. When instantiated they must contain a + * property called `$get`, which holds the **service factory** function. + * * When you request a service, the {@link AUTO.$injector $injector} is responsible for finding the * correct **service provider**, instantiating it and then calling its `$get` **service factory** * function to get the instance of the **service**. - * + * * Often services have no configuration options and there is no need to add methods to the service * provider. The provider will be no more than a constructor function with a `$get` property. For * these cases the {@link AUTO.$provide $provide} service has additional helper methods to register * services without specifying a provider. * - * * {@link AUTO.$provide#provider provider(provider)} - registers a **service provider** with the + * * {@link AUTO.$provide#methods_provider provider(provider)} - registers a **service provider** with the * {@link AUTO.$injector $injector} - * * {@link AUTO.$provide#constant constant(obj)} - registers a value/object that can be accessed by + * * {@link AUTO.$provide#methods_constant constant(obj)} - registers a value/object that can be accessed by * providers and services. - * * {@link AUTO.$provide#value value(obj)} - registers a value/object that can only be accessed by + * * {@link AUTO.$provide#methods_value value(obj)} - registers a value/object that can only be accessed by * services, not providers. - * * {@link AUTO.$provide#factory factory(fn)} - registers a service **factory function**, `fn`, that - * will be wrapped in a **service provider** object, whose `$get` property will contain the given - * factory function. - * * {@link AUTO.$provide#service service(class)} - registers a **constructor function**, `class` that - * will be wrapped in a **service provider** object, whose `$get` property will instantiate a new - * object using the given constructor function. + * * {@link AUTO.$provide#methods_factory factory(fn)} - registers a service **factory function**, `fn`, + * that will be wrapped in a **service provider** object, whose `$get` property will contain the + * given factory function. + * * {@link AUTO.$provide#methods_service service(class)} - registers a **constructor function**, `class` that + * that will be wrapped in a **service provider** object, whose `$get` property will instantiate + * a new object using the given constructor function. * * See the individual methods for more information and examples. */ @@ -2934,33 +3163,38 @@ * @methodOf AUTO.$provide * @description * - * Register a **provider function** with the {@link AUTO.$injector $injector}. Provider functions are - * constructor functions, whose instances are responsible for "providing" a factory for a service. - * + * Register a **provider function** with the {@link AUTO.$injector $injector}. Provider functions + * are constructor functions, whose instances are responsible for "providing" a factory for a + * service. + * * Service provider names start with the name of the service they provide followed by `Provider`. - * For example, the {@link ng.$log $log} service has a provider called {@link ng.$logProvider $logProvider}. + * For example, the {@link ng.$log $log} service has a provider called + * {@link ng.$logProvider $logProvider}. * - * Service provider objects can have additional methods which allow configuration of the provider and - * its service. Importantly, you can configure what kind of service is created by the `$get` method, - * or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a method - * {@link ng.$logProvider#debugEnabled debugEnabled} + * Service provider objects can have additional methods which allow configuration of the provider + * and its service. Importantly, you can configure what kind of service is created by the `$get` + * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a + * method {@link ng.$logProvider#debugEnabled debugEnabled} * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the * console or not. * - * @param {string} name The name of the instance. NOTE: the provider will be available under `name + 'Provider'` key. + * @param {string} name The name of the instance. NOTE: the provider will be available under `name + + 'Provider'` key. * @param {(Object|function())} provider If the provider is: * * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using - * {@link AUTO.$injector#invoke $injector.invoke()} when an instance needs to be created. + * {@link AUTO.$injector#invoke $injector.invoke()} when an instance needs to be + * created. * - `Constructor`: a new instance of the provider will be created using - * {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as `object`. + * {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as + * `object`. * * @returns {Object} registered provider instance * @example * * The following example shows how to create a simple event tracking service and register it using - * {@link AUTO.$provide#provider $provide.provider()}. + * {@link AUTO.$provide#methods_provider $provide.provider()}. * * <pre> * // Define the eventTracker provider @@ -3031,16 +3265,16 @@ * Register a **service factory**, which will be called to return the service instance. * This is short for registering a service where its provider consists of only a `$get` property, * which is the given service factory function. - * You should use {@link AUTO.$provide#factory $provide.factor(getFn)} if you do not need to configure - * your service in a provider. + * You should use {@link AUTO.$provide#factory $provide.factory(getFn)} if you do not need to + * configure your service in a provider. * * @param {string} name The name of the instance. - * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand for - * `$provide.provider(name, {$get: $getFn})`. + * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand + * for `$provide.provider(name, {$get: $getFn})`. * @returns {Object} registered provider instance * * @example - * Here is an example of registering a service + * Here is an example of registering a service * <pre> * $provide.factory('ping', ['$http', function($http) { * return function ping() { @@ -3063,11 +3297,12 @@ * @methodOf AUTO.$provide * @description * - * Register a **service constructor**, which will be invoked with `new` to create the service instance. + * Register a **service constructor**, which will be invoked with `new` to create the service + * instance. * This is short for registering a service where its provider's `$get` property is the service * constructor function that will be used to instantiate the service instance. * - * You should use {@link AUTO.$provide#service $provide.service(class)} if you define your service + * You should use {@link AUTO.$provide#methods_service $provide.service(class)} if you define your service * as a type/class. This is common when using {@link http://coffeescript.org CoffeeScript}. * * @param {string} name The name of the instance. @@ -3075,14 +3310,14 @@ * @returns {Object} registered provider instance * * @example - * Here is an example of registering a service using {@link AUTO.$provide#service $provide.service(class)} - * that is defined as a CoffeeScript class. + * Here is an example of registering a service using + * {@link AUTO.$provide#methods_service $provide.service(class)} that is defined as a CoffeeScript class. * <pre> * class Ping * constructor: (@$http)-> * send: ()=> * @$http.get('/ping') - * + * * $provide.service('ping', ['$http', Ping]) * </pre> * You would then inject and use this service like this: @@ -3100,14 +3335,16 @@ * @methodOf AUTO.$provide * @description * - * Register a **value service** with the {@link AUTO.$injector $injector}, such as a string, a number, - * an array, an object or a function. This is short for registering a service where its provider's - * `$get` property is a factory function that takes no arguments and returns the **value service**. + * Register a **value service** with the {@link AUTO.$injector $injector}, such as a string, a + * number, an array, an object or a function. This is short for registering a service where its + * provider's `$get` property is a factory function that takes no arguments and returns the **value + * service**. * - * Value services are similar to constant services, except that they cannot be injected into a module - * configuration function (see {@link angular.Module#config}) but they can be overridden by an Angular + * Value services are similar to constant services, except that they cannot be injected into a + * module configuration function (see {@link angular.Module#config}) but they can be overridden by + * an Angular * {@link AUTO.$provide#decorator decorator}. - * + * * @param {string} name The name of the instance. * @param {*} value The value. * @returns {Object} registered provider instance @@ -3116,9 +3353,9 @@ * Here are some examples of creating value services. * <pre> * $provide.constant('ADMIN_USER', 'admin'); - * + * * $provide.constant('RoleLookup', { admin: 0, writer: 1, reader: 2 }); - * + * * $provide.constant('halfOf', function(value) { * return value / 2; * }); @@ -3132,10 +3369,10 @@ * @methodOf AUTO.$provide * @description * - * Register a **constant service**, such as a string, a number, an array, an object or a function, with - * the {@link AUTO.$injector $injector}. Unlike {@link AUTO.$provide#value value} it can be injected - * into a module configuration function (see {@link angular.Module#config}) and it cannot be - * overridden by an Angular {@link AUTO.$provide#decorator decorator}. + * Register a **constant service**, such as a string, a number, an array, an object or a function, + * with the {@link AUTO.$injector $injector}. Unlike {@link AUTO.$provide#value value} it can be + * injected into a module configuration function (see {@link angular.Module#config}) and it cannot + * be overridden by an Angular {@link AUTO.$provide#decorator decorator}. * * @param {string} name The name of the constant. * @param {*} value The constant value. @@ -3145,9 +3382,9 @@ * Here a some examples of creating constants: * <pre> * $provide.constant('SHARD_HEIGHT', 306); - * + * * $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']); - * + * * $provide.constant('double', function(value) { * return value * 2; * }); @@ -3163,8 +3400,8 @@ * * Register a **service decorator** with the {@link AUTO.$injector $injector}. A service decorator * intercepts the creation of a service, allowing it to override or modify the behaviour of the - * service. The object returned by the decorator may be the original service, or a new service object - * which replaces or wraps and delegates to the original service. + * service. The object returned by the decorator may be the original service, or a new service + * object which replaces or wraps and delegates to the original service. * * @param {string} name The name of the service to decorate. * @param {function()} decorator This function will be invoked when the service needs to be @@ -3229,7 +3466,7 @@ } else { return delegate(key, value); } - } + }; } function provider(name, provider_) { @@ -3251,7 +3488,7 @@ }]); } - function value(name, value) { return factory(name, valueFn(value)); } + function value(name, val) { return factory(name, valueFn(val)); } function constant(name, value) { assertNotHasOwnProperty(name, 'constant'); @@ -3273,17 +3510,17 @@ // Module Loading //////////////////////////////////// function loadModules(modulesToLoad){ - var runBlocks = []; + var runBlocks = [], moduleFn, invokeQueue, i, ii; forEach(modulesToLoad, function(module) { if (loadedModules.get(module)) return; loadedModules.put(module, true); try { if (isString(module)) { - var moduleFn = angularModule(module); + moduleFn = angularModule(module); runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks); - for(var invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { + for(invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) { var invokeArgs = invokeQueue[i], provider = providerInjector.get(invokeArgs[0]); @@ -3301,12 +3538,15 @@ module = module[module.length - 1]; } if (e.message && e.stack && e.stack.indexOf(e.message) == -1) { - // Safari & FF's stack traces don't contain error.message content unlike those of Chrome and IE + // Safari & FF's stack traces don't contain error.message content + // unlike those of Chrome and IE // So if stack doesn't contain message, we create a new string that contains both. // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here. + /* jshint -W022 */ e = e.message + '\n' + e.stack; } - throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}", module, e.stack || e.message || e); + throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}", + module, e.stack || e.message || e); } }); return runBlocks; @@ -3344,7 +3584,8 @@ for(i = 0, length = $inject.length; i < length; i++) { key = $inject[i]; if (typeof key !== 'string') { - throw $injectorMinErr('itkn', 'Incorrect injection token! Expected service name as string, got {0}', key); + throw $injectorMinErr('itkn', + 'Incorrect injection token! Expected service name as string, got {0}', key); } args.push( locals && locals.hasOwnProperty(key) @@ -3369,8 +3610,10 @@ case 6: return fn(args[0], args[1], args[2], args[3], args[4], args[5]); case 7: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); case 8: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); - case 9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); - case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); + case 9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], + args[8]); + case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], + args[8], args[9]); default: return fn.apply(self, args); } } @@ -3385,7 +3628,7 @@ instance = new Constructor(); returnedValue = invoke(Type, instance, locals); - return isObject(returnedValue) ? returnedValue : instance; + return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance; } return { @@ -3400,7 +3643,6 @@ } } - /** * @ngdoc function * @name ng.$anchorScroll @@ -3508,7 +3750,8 @@ * @name ng.$animateProvider * * @description - * Default implementation of $animate that doesn't perform any animations, instead just synchronously performs DOM + * Default implementation of $animate that doesn't perform any animations, instead just + * synchronously performs DOM * updates and calls done() callbacks. * * In order to enable animations the ngAnimate module has to be loaded. @@ -3517,6 +3760,7 @@ */ var $AnimateProvider = ['$provide', function($provide) { + this.$$selectors = {}; @@ -3526,12 +3770,14 @@ * @methodOf ng.$animateProvider * * @description - * Registers a new injectable animation factory function. The factory function produces the animation object which - * contains callback functions for each event that is expected to be animated. + * Registers a new injectable animation factory function. The factory function produces the + * animation object which contains callback functions for each event that is expected to be + * animated. * - * * `eventFn`: `function(Element, doneFunction)` The element to animate, the `doneFunction` must be called once the - * element animation is complete. If a function is returned then the animation service will use this function to - * cancel the animation whenever a cancel event is triggered. + * * `eventFn`: `function(Element, doneFunction)` The element to animate, the `doneFunction` + * must be called once the element animation is complete. If a function is returned then the + * animation service will use this function to cancel the animation whenever a cancel event is + * triggered. * * *<pre> @@ -3547,7 +3793,8 @@ *</pre> * * @param {string} name The name of the animation. - * @param {function} factory The factory function that will be executed to return the animation object. + * @param {function} factory The factory function that will be executed to return the animation + * object. */ this.register = function(name, factory) { var key = name + '-animation'; @@ -3560,36 +3807,39 @@ this.$get = ['$timeout', function($timeout) { /** + * * @ngdoc object * @name ng.$animate + * @description The $animate service provides rudimentary DOM manipulation functions to + * insert, remove and move elements within the DOM, as well as adding and removing classes. + * This service is the core service used by the ngAnimate $animator service which provides + * high-level animation hooks for CSS and JavaScript. * - * @description - * The $animate service provides rudimentary DOM manipulation functions to insert, remove and move elements within - * the DOM, as well as adding and removing classes. This service is the core service used by the ngAnimate $animator - * service which provides high-level animation hooks for CSS and JavaScript. + * $animate is available in the AngularJS core, however, the ngAnimate module must be included + * to enable full out animation support. Otherwise, $animate will only perform simple DOM + * manipulation operations. * - * $animate is available in the AngularJS core, however, the ngAnimate module must be included to enable full out - * animation support. Otherwise, $animate will only perform simple DOM manipulation operations. - * - * To learn more about enabling animation support, click here to visit the {@link ngAnimate ngAnimate module page} - * as well as the {@link ngAnimate.$animate ngAnimate $animate service page}. + * To learn more about enabling animation support, click here to visit the {@link ngAnimate + * ngAnimate module page} as well as the {@link ngAnimate.$animate ngAnimate $animate service + * page}. */ return { /** + * * @ngdoc function * @name ng.$animate#enter * @methodOf ng.$animate * @function - * - * @description - * Inserts the element into the DOM either after the `after` element or within the `parent` element. Once complete, - * the done() callback will be fired (if provided). - * + * @description Inserts the element into the DOM either after the `after` element or within + * the `parent` element. Once complete, the done() callback will be fired (if provided). * @param {jQuery/jqLite element} element the element which will be inserted into the DOM - * @param {jQuery/jqLite element} parent the parent element which will append the element as a child (if the after element is not present) - * @param {jQuery/jqLite element} after the sibling element which will append the element after itself - * @param {function=} done callback function that will be called after the element has been inserted into the DOM + * @param {jQuery/jqLite element} parent the parent element which will append the element as + * a child (if the after element is not present) + * @param {jQuery/jqLite element} after the sibling element which will append the element + * after itself + * @param {function=} done callback function that will be called after the element has been + * inserted into the DOM */ enter : function(element, parent, after, done) { var afterNode = after && after[after.length - 1]; @@ -3603,16 +3853,16 @@ }, /** + * * @ngdoc function * @name ng.$animate#leave * @methodOf ng.$animate * @function - * - * @description - * Removes the element from the DOM. Once complete, the done() callback will be fired (if provided). - * + * @description Removes the element from the DOM. Once complete, the done() callback will be + * fired (if provided). * @param {jQuery/jqLite element} element the element which will be removed from the DOM - * @param {function=} done callback function that will be called after the element has been removed from the DOM + * @param {function=} done callback function that will be called after the element has been + * removed from the DOM */ leave : function(element, done) { element.remove(); @@ -3620,19 +3870,23 @@ }, /** + * * @ngdoc function * @name ng.$animate#move * @methodOf ng.$animate * @function - * - * @description - * Moves the position of the provided element within the DOM to be placed either after the `after` element or inside of the `parent` element. - * Once complete, the done() callback will be fired (if provided). - * - * @param {jQuery/jqLite element} element the element which will be moved around within the DOM - * @param {jQuery/jqLite element} parent the parent element where the element will be inserted into (if the after element is not present) - * @param {jQuery/jqLite element} after the sibling element where the element will be positioned next to - * @param {function=} done the callback function (if provided) that will be fired after the element has been moved to its new position + * @description Moves the position of the provided element within the DOM to be placed + * either after the `after` element or inside of the `parent` element. Once complete, the + * done() callback will be fired (if provided). + * + * @param {jQuery/jqLite element} element the element which will be moved around within the + * DOM + * @param {jQuery/jqLite element} parent the parent element where the element will be + * inserted into (if the after element is not present) + * @param {jQuery/jqLite element} after the sibling element where the element will be + * positioned next to + * @param {function=} done the callback function (if provided) that will be fired after the + * element has been moved to its new position */ move : function(element, parent, after, done) { // Do not remove element before insert. Removing will cause data associated with the @@ -3641,47 +3895,49 @@ }, /** + * * @ngdoc function * @name ng.$animate#addClass * @methodOf ng.$animate * @function - * - * @description - * Adds the provided className CSS class value to the provided element. Once complete, the done() callback will be fired (if provided). - * - * @param {jQuery/jqLite element} element the element which will have the className value added to it + * @description Adds the provided className CSS class value to the provided element. Once + * complete, the done() callback will be fired (if provided). + * @param {jQuery/jqLite element} element the element which will have the className value + * added to it * @param {string} className the CSS class which will be added to the element - * @param {function=} done the callback function (if provided) that will be fired after the className value has been added to the element + * @param {function=} done the callback function (if provided) that will be fired after the + * className value has been added to the element */ addClass : function(element, className, done) { className = isString(className) ? className : isArray(className) ? className.join(' ') : ''; forEach(element, function (element) { - JQLiteAddClass(element, className); + jqLiteAddClass(element, className); }); done && $timeout(done, 0, false); }, /** + * * @ngdoc function * @name ng.$animate#removeClass * @methodOf ng.$animate * @function - * - * @description - * Removes the provided className CSS class value from the provided element. Once complete, the done() callback will be fired (if provided). - * - * @param {jQuery/jqLite element} element the element which will have the className value removed from it + * @description Removes the provided className CSS class value from the provided element. + * Once complete, the done() callback will be fired (if provided). + * @param {jQuery/jqLite element} element the element which will have the className value + * removed from it * @param {string} className the CSS class which will be removed from the element - * @param {function=} done the callback function (if provided) that will be fired after the className value has been removed from the element + * @param {function=} done the callback function (if provided) that will be fired after the + * className value has been removed from the element */ removeClass : function(element, className, done) { className = isString(className) ? className : isArray(className) ? className.join(' ') : ''; forEach(element, function (element) { - JQLiteRemoveClass(element, className); + jqLiteRemoveClass(element, className); }); done && $timeout(done, 0, false); }, @@ -3965,30 +4221,35 @@ * It is not meant to be used directly, use the $cookie service instead. * * The return values vary depending on the arguments that the method was called with as follows: - * <ul> - * <li>cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify it</li> - * <li>cookies(name, value) -> set name to value, if value is undefined delete the cookie</li> - * <li>cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that way)</li> - * </ul> - * + * + * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify + * it + * - cookies(name, value) -> set name to value, if value is undefined delete the cookie + * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that + * way) + * * @returns {Object} Hash of all cookies (if called without any parameter) */ self.cookies = function(name, value) { + /* global escape: false, unescape: false */ var cookieLength, cookieArray, cookie, i, index; if (name) { if (value === undefined) { - rawDocument.cookie = escape(name) + "=;path=" + cookiePath + ";expires=Thu, 01 Jan 1970 00:00:00 GMT"; + rawDocument.cookie = escape(name) + "=;path=" + cookiePath + + ";expires=Thu, 01 Jan 1970 00:00:00 GMT"; } else { if (isString(value)) { - cookieLength = (rawDocument.cookie = escape(name) + '=' + escape(value) + ';path=' + cookiePath).length + 1; + cookieLength = (rawDocument.cookie = escape(name) + '=' + escape(value) + + ';path=' + cookiePath).length + 1; // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum: // - 300 cookies // - 20 cookies per unique domain // - 4096 bytes per cookie if (cookieLength > 4096) { - $log.warn("Cookie '"+ name +"' possibly not set or overflowed because it was too large ("+ + $log.warn("Cookie '"+ name + + "' possibly not set or overflowed because it was too large ("+ cookieLength + " > 4096 bytes)!"); } } @@ -4003,7 +4264,7 @@ cookie = cookieArray[i]; index = cookie.indexOf('='); if (index > 0) { //ignore nameless cookies - var name = unescape(cookie.substring(0, index)); + name = unescape(cookie.substring(0, index)); // the first value that is seen for a cookie is the most // specific one. values for the same cookie name that // follow are for less specific paths. @@ -4053,7 +4314,8 @@ * Cancels a deferred task identified with `deferId`. * * @param {*} deferId Token returned by the `$browser.defer` function. - * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully canceled. + * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully + * canceled. */ self.defer.cancel = function(deferId) { if (pendingDeferIds[deferId]) { @@ -4089,9 +4351,10 @@ * * cache.put("key", "value"); * cache.put("another key", "another value"); + * + * // We've specified no options on creation + * expect(cache.info()).toEqual({id: 'cacheId', size: 2}); * - * expect(cache.info()).toEqual({id: 'cacheId', size: 2}); // Since we've specified no options on creation - * * </pre> * * @@ -4103,7 +4366,8 @@ * @returns {object} Newly created cache object with the following set of methods: * * - `{object}` `info()` — Returns id, size, and options of cache. - * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns it. + * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns + * it. * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss. * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache. * - `{void}` `removeAll()` — Removes all cached values. @@ -4270,9 +4534,9 @@ * @name ng.$templateCache * * @description - * The first time a template is used, it is loaded in the template cache for quick retrieval. You can - * load templates directly into the cache in a `script` tag, or by consuming the `$templateCache` - * service directly. + * The first time a template is used, it is loaded in the template cache for quick retrieval. You + * can load templates directly into the cache in a `script` tag, or by consuming the + * `$templateCache` service directly. * * Adding via the `script` tag: * <pre> @@ -4286,8 +4550,8 @@ * </html> * </pre> * - * **Note:** the `script` tag containing the template does not need to be included in the `head` of the document, but - * it must be below the `ng-app` definition. + * **Note:** the `script` tag containing the template does not need to be included in the `head` of + * the document, but it must be below the `ng-app` definition. * * Adding via the $templateCache service: * @@ -4342,21 +4606,355 @@ * * @description * Compiles a piece of HTML string or DOM into a template and produces a template function, which - * can then be used to link {@link ng.$rootScope.Scope scope} and the template together. + * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together. * - * The compilation is a process of walking the DOM tree and trying to match DOM elements to - * {@link ng.$compileProvider#directive directives}. For each match it - * executes corresponding template function and collects the - * instance functions into a single template function which is then returned. + * The compilation is a process of walking the DOM tree and matching DOM elements to + * {@link ng.$compileProvider#methods_directive directives}. * - * The template function can then be used once to produce the view or as it is the case with - * {@link ng.directive:ngRepeat repeater} many-times, in which - * case each call results in a view that is a DOM clone of the original template. + * <div class="alert alert-warning"> + * **Note:** This document is an in-depth reference of all directive options. + * For a gentle introduction to directives with examples of common use cases, + * see the {@link guide/directive directive guide}. + * </div> * + * ## Comprehensive Directive API + * + * There are many different options for a directive. + * + * The difference resides in the return value of the factory function. + * You can either return a "Directive Definition Object" (see below) that defines the directive properties, + * or just the `postLink` function (all other properties will have the default values). + * + * <div class="alert alert-success"> + * **Best Practice:** It's recommended to use the "directive definition object" form. + * </div> + * + * Here's an example directive declared with a Directive Definition Object: + * + * <pre> + * var myModule = angular.module(...); + * + * myModule.directive('directiveName', function factory(injectables) { + * var directiveDefinitionObject = { + * priority: 0, + * template: '<div></div>', // or // function(tElement, tAttrs) { ... }, + * // or + * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, + * replace: false, + * transclude: false, + * restrict: 'A', + * scope: false, + * controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... }, + * require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'], + * compile: function compile(tElement, tAttrs, transclude) { + * return { + * pre: function preLink(scope, iElement, iAttrs, controller) { ... }, + * post: function postLink(scope, iElement, iAttrs, controller) { ... } + * } + * // or + * // return function postLink( ... ) { ... } + * }, + * // or + * // link: { + * // pre: function preLink(scope, iElement, iAttrs, controller) { ... }, + * // post: function postLink(scope, iElement, iAttrs, controller) { ... } + * // } + * // or + * // link: function postLink( ... ) { ... } + * }; + * return directiveDefinitionObject; + * }); + * </pre> + * + * <div class="alert alert-warning"> + * **Note:** Any unspecified options will use the default value. You can see the default values below. + * </div> + * + * Therefore the above can be simplified as: + * + * <pre> + * var myModule = angular.module(...); + * + * myModule.directive('directiveName', function factory(injectables) { + * var directiveDefinitionObject = { + * link: function postLink(scope, iElement, iAttrs) { ... } + * }; + * return directiveDefinitionObject; + * // or + * // return function postLink(scope, iElement, iAttrs) { ... } + * }); + * </pre> + * + * + * + * ### Directive Definition Object + * + * The directive definition object provides instructions to the {@link api/ng.$compile + * compiler}. The attributes are: + * + * #### `priority` + * When there are multiple directives defined on a single DOM element, sometimes it + * is necessary to specify the order in which the directives are applied. The `priority` is used + * to sort the directives before their `compile` functions get called. Priority is defined as a + * number. Directives with greater numerical `priority` are compiled first. The order of directives with + * the same priority is undefined. The default priority is `0`. + * + * #### `terminal` + * If set to true then the current `priority` will be the last set of directives + * which will execute (any directives at the current priority will still execute + * as the order of execution on same `priority` is undefined). + * + * #### `scope` + * **If set to `true`,** then a new scope will be created for this directive. If multiple directives on the + * same element request a new scope, only one new scope is created. The new scope rule does not + * apply for the root of the template since the root of the template always gets a new scope. + * + * **If set to `{}` (object hash),** then a new "isolate" scope is created. The 'isolate' scope differs from + * normal scope in that it does not prototypically inherit from the parent scope. This is useful + * when creating reusable components, which should not accidentally read or modify data in the + * parent scope. + * + * The 'isolate' scope takes an object hash which defines a set of local scope properties + * derived from the parent scope. These local properties are useful for aliasing values for + * templates. Locals definition is a hash of local scope property to its source: + * + * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is + * always a string since DOM attributes are strings. If no `attr` name is specified then the + * attribute name is assumed to be the same as the local name. + * Given `<widget my-attr="hello {{name}}">` and widget definition + * of `scope: { localName:'@myAttr' }`, then widget scope property `localName` will reflect + * the interpolated value of `hello {{name}}`. As the `name` attribute changes so will the + * `localName` property on the widget scope. The `name` is read from the parent scope (not + * component scope). + * + * * `=` or `=attr` - set up bi-directional binding between a local scope property and the + * parent scope property of name defined via the value of the `attr` attribute. If no `attr` + * name is specified then the attribute name is assumed to be the same as the local name. + * Given `<widget my-attr="parentModel">` and widget definition of + * `scope: { localModel:'=myAttr' }`, then widget scope property `localModel` will reflect the + * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected + * in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent + * scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You + * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. + * + * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. + * If no `attr` name is specified then the attribute name is assumed to be the same as the + * local name. Given `<widget my-attr="count = count + value">` and widget definition of + * `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to + * a function wrapper for the `count = count + value` expression. Often it's desirable to + * pass data from the isolated scope via an expression and to the parent scope, this can be + * done by passing a map of local variable names and values into the expression wrapper fn. + * For example, if the expression is `increment(amount)` then we can specify the amount value + * by calling the `localFn` as `localFn({amount: 22})`. + * + * + * + * #### `controller` + * Controller constructor function. The controller is instantiated before the + * pre-linking phase and it is shared with other directives (see + * `require` attribute). This allows the directives to communicate with each other and augment + * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals: + * + * * `$scope` - Current scope associated with the element + * * `$element` - Current element + * * `$attrs` - Current attributes object for the element + * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope: + * `function(cloneLinkingFn)`. + * + * + * #### `require` + * Require another directive and inject its controller as the fourth argument to the linking function. The + * `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the + * injected argument will be an array in corresponding order. If no such directive can be + * found, or if the directive does not have a controller, then an error is raised. The name can be prefixed with: + * + * * (no prefix) - Locate the required controller on the current element. Throw an error if not found. + * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found. + * * `^` - Locate the required controller by searching the element's parents. Throw an error if not found. + * * `?^` - Attempt to locate the required controller by searching the element's parentsor pass `null` to the + * `link` fn if not found. + * + * + * #### `controllerAs` + * Controller alias at the directive scope. An alias for the controller so it + * can be referenced at the directive template. The directive needs to define a scope for this + * configuration to be used. Useful in the case when directive is used as component. + * + * + * #### `restrict` + * String of subset of `EACM` which restricts the directive to a specific directive + * declaration style. If omitted, the default (attributes only) is used. + * + * * `E` - Element name: `<my-directive></my-directive>` + * * `A` - Attribute (default): `<div my-directive="exp"></div>` + * * `C` - Class: `<div class="my-directive: exp;"></div>` + * * `M` - Comment: `<!-- directive: my-directive exp -->` + * + * + * #### `template` + * replace the current element with the contents of the HTML. The replacement process + * migrates all of the attributes / classes from the old element to the new one. See the + * {@link guide/directive#creating-custom-directives_creating-directives_template-expanding-directive + * Directives Guide} for an example. + * + * You can specify `template` as a string representing the template or as a function which takes + * two arguments `tElement` and `tAttrs` (described in the `compile` function api below) and + * returns a string value representing the template. + * + * + * #### `templateUrl` + * Same as `template` but the template is loaded from the specified URL. Because + * the template loading is asynchronous the compilation/linking is suspended until the template + * is loaded. + * + * You can specify `templateUrl` as a string representing the URL or as a function which takes two + * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns + * a string value representing the url. In either case, the template URL is passed through {@link + * api/ng.$sce#methods_getTrustedResourceUrl $sce.getTrustedResourceUrl}. + * + * + * #### `replace` + * specify where the template should be inserted. Defaults to `false`. + * + * * `true` - the template will replace the current element. + * * `false` - the template will replace the contents of the current element. + * + * + * #### `transclude` + * compile the content of the element and make it available to the directive. + * Typically used with {@link api/ng.directive:ngTransclude + * ngTransclude}. The advantage of transclusion is that the linking function receives a + * transclusion function which is pre-bound to the correct scope. In a typical setup the widget + * creates an `isolate` scope, but the transclusion is not a child, but a sibling of the `isolate` + * scope. This makes it possible for the widget to have private state, and the transclusion to + * be bound to the parent (pre-`isolate`) scope. + * + * * `true` - transclude the content of the directive. + * * `'element'` - transclude the whole element including any directives defined at lower priority. + * + * + * #### `compile` + * + * <pre> + * function compile(tElement, tAttrs, transclude) { ... } + * </pre> + * + * The compile function deals with transforming the template DOM. Since most directives do not do + * template transformation, it is not used often. Examples that require compile functions are + * directives that transform template DOM, such as {@link + * api/ng.directive:ngRepeat ngRepeat}, or load the contents + * asynchronously, such as {@link api/ngRoute.directive:ngView ngView}. The + * compile function takes the following arguments. + * + * * `tElement` - template element - The element where the directive has been declared. It is + * safe to do template transformation on the element and child elements only. + * + * * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared + * between all directive compile functions. + * + * * `transclude` - A transclude linking function: `function(scope, cloneLinkingFn)`. + * + * <div class="alert alert-warning"> + * **Note:** The template instance and the link instance may be different objects if the template has + * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that + * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration + * should be done in a linking function rather than in a compile function. + * </div> + * + * A compile function can have a return value which can be either a function or an object. + * + * * returning a (post-link) function - is equivalent to registering the linking function via the + * `link` property of the config object when the compile function is empty. + * + * * returning an object with function(s) registered via `pre` and `post` properties - allows you to + * control when a linking function should be called during the linking phase. See info about + * pre-linking and post-linking functions below. + * + * + * #### `link` + * This property is used only if the `compile` property is not defined. + * + * <pre> + * function link(scope, iElement, iAttrs, controller) { ... } + * </pre> + * + * The link function is responsible for registering DOM listeners as well as updating the DOM. It is + * executed after the template has been cloned. This is where most of the directive logic will be + * put. + * + * * `scope` - {@link api/ng.$rootScope.Scope Scope} - The scope to be used by the + * directive for registering {@link api/ng.$rootScope.Scope#methods_$watch watches}. + * + * * `iElement` - instance element - The element where the directive is to be used. It is safe to + * manipulate the children of the element only in `postLink` function since the children have + * already been linked. + * + * * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared + * between all directive linking functions. + * + * * `controller` - a controller instance - A controller instance if at least one directive on the + * element defines a controller. The controller is shared among all the directives, which allows + * the directives to use the controllers as a communication channel. + * + * + * + * #### Pre-linking function + * + * Executed before the child elements are linked. Not safe to do DOM transformation since the + * compiler linking function will fail to locate the correct elements for linking. + * + * #### Post-linking function + * + * Executed after the child elements are linked. It is safe to do DOM transformation in the post-linking function. + * + * <a name="Attributes"></a> + * ### Attributes + * + * The {@link api/ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the + * `link()` or `compile()` functions. It has a variety of uses. + * + * accessing *Normalized attribute names:* + * Directives like 'ngBind' can be expressed in many ways: 'ng:bind', `data-ng-bind`, or 'x-ng-bind'. + * the attributes object allows for normalized access to + * the attributes. + * + * * *Directive inter-communication:* All directives share the same instance of the attributes + * object which allows the directives to use the attributes object as inter directive + * communication. + * + * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object + * allowing other directives to read the interpolated value. + * + * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes + * that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also + * the only way to easily get the actual value because during the linking phase the interpolation + * hasn't been evaluated yet and so the value is at this time set to `undefined`. + * + * <pre> + * function linkingFn(scope, elm, attrs, ctrl) { + * // get the attribute value + * console.log(attrs.ngModel); + * + * // change the attribute + * attrs.$set('ngModel', 'new value'); + * + * // observe changes to interpolated attribute + * attrs.$observe('ngModel', function(value) { + * console.log('ngModel has changed value to ' + value); + * }); + * } + * </pre> + * + * Below is an example using `$compileProvider`. + * + * <div class="alert alert-warning"> + * **Note**: Typically directives are registered with `module.directive`. The example below is + * to illustrate how `$compile` works. + * </div> + * <doc:example module="compile"> <doc:source> <script> - // declare a new module, and inject the $compileProvider angular.module('compile', [], function($compileProvider) { // configure new 'compile' directive by passing a directive // factory function. The factory function injects the '$compile' @@ -4414,16 +5012,16 @@ * (a DOM element/tree) to a scope. Where: * * * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to. - * * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the `template` - * and call the `cloneAttachFn` function allowing the caller to attach the + * * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the + * `template` and call the `cloneAttachFn` function allowing the caller to attach the * cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is * called as: <br> `cloneAttachFn(clonedElement, scope)` where: * * * `clonedElement` - is a clone of the original `element` passed into the compiler. * * `scope` - is the current scope with which the linking function is working with. * - * Calling the linking function returns the element of the template. It is either the original element - * passed in, or the clone of the element if the `cloneAttachFn` is provided. + * Calling the linking function returns the element of the template. It is either the original + * element passed in, or the clone of the element if the `cloneAttachFn` is provided. * * After linking the view is not updated until after a call to $digest which typically is done by * Angular automatically. @@ -4574,10 +5172,10 @@ * * The sanitization is a security measure aimed at prevent XSS attacks via html links. * - * Any url about to be assigned to img[src] via data-binding is first normalized and turned into an - * absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist` regular - * expression. If a match is found, the original url is written into the dom. Otherwise, the - * absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. + * Any url about to be assigned to img[src] via data-binding is first normalized and turned into + * an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist` + * regular expression. If a match is found, the original url is written into the dom. Otherwise, + * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM. * * @param {RegExp=} regexp New regexp to whitelist urls with. * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for @@ -4632,8 +5230,8 @@ * @function * * @description - * Removes the CSS class value specified by the classVal parameter from the element. If animations - * are enabled then an animation will be triggered for the class removal. + * Removes the CSS class value specified by the classVal parameter from the element. If + * animations are enabled then an animation will be triggered for the class removal. * * @param {string} classVal The className value that will be removed from the element */ @@ -4733,7 +5331,7 @@ values.push(token); } return values; - }; + } }, @@ -4786,9 +5384,11 @@ //================================ - function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) { + function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, + previousCompileContext) { if (!($compileNodes instanceof jqLite)) { - // jquery always rewraps, whereas we need to preserve the original selector so that we can modify it. + // jquery always rewraps, whereas we need to preserve the original selector so that we can + // modify it. $compileNodes = jqLite($compileNodes); } // We can not compile top level text elements since text nodes can be merged and we will @@ -4798,7 +5398,9 @@ $compileNodes[index] = node = jqLite(node).wrap('<span></span>').parent()[0]; } }); - var compositeLinkFn = compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); + var compositeLinkFn = + compileNodes($compileNodes, transcludeFn, $compileNodes, + maxPriority, ignoreDirective, previousCompileContext); return function publicLinkFn(scope, cloneConnectFn){ assertArg(scope, 'scope'); // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart @@ -4839,13 +5441,14 @@ * @param {NodeList} nodeList an array of nodes or NodeList to compile * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the * scope argument is auto-generated to the new child of the transcluded parent scope. - * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then the - * rootElement must be set the jqLite collection of the compile root. This is + * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then + * the rootElement must be set the jqLite collection of the compile root. This is * needed so that the jqLite collection items can be replaced with widgets. * @param {number=} max directive priority * @returns {?function} A composite linking function of all of the matched directives or null. */ - function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective, previousCompileContext) { + function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective, + previousCompileContext) { var linkFns = [], nodeLinkFn, childLinkFn, directives, attrs, linkFnFound; @@ -4853,13 +5456,17 @@ attrs = new Attributes(); // we must always refer to nodeList[i] since the nodes can be replaced underneath us. - directives = collectDirectives(nodeList[i], [], attrs, i == 0 ? maxPriority : undefined, ignoreDirective); + directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined, + ignoreDirective); nodeLinkFn = (directives.length) - ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement, null, [], [], previousCompileContext) + ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement, + null, [], [], previousCompileContext) : null; - childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes || !nodeList[i].childNodes.length) + childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || + !nodeList[i].childNodes || + !nodeList[i].childNodes.length) ? null : compileNodes(nodeList[i].childNodes, nodeLinkFn ? nodeLinkFn.transclude : transcludeFn); @@ -4867,14 +5474,15 @@ linkFns.push(nodeLinkFn); linkFns.push(childLinkFn); linkFnFound = (linkFnFound || nodeLinkFn || childLinkFn); - previousCompileContext = null; //use the previous context only for the first element in the virtual group + //use the previous context only for the first element in the virtual group + previousCompileContext = null; } // return a linking function if we have found anything, null otherwise return linkFnFound ? compositeLinkFn : null; function compositeLinkFn(scope, nodeList, $rootElement, boundTranscludeFn) { - var nodeLinkFn, childLinkFn, node, childScope, childTranscludeFn, i, ii, n; + var nodeLinkFn, childLinkFn, node, $node, childScope, childTranscludeFn, i, ii, n; // copy nodeList so that linking doesn't break due to live list updates. var stableNodeList = []; @@ -4886,11 +5494,13 @@ node = stableNodeList[n]; nodeLinkFn = linkFns[i++]; childLinkFn = linkFns[i++]; + $node = jqLite(node); if (nodeLinkFn) { if (nodeLinkFn.scope) { - childScope = scope.$new(isObject(nodeLinkFn.scope)); - jqLite(node).data('$scope', childScope); + childScope = scope.$new(); + $node.data('$scope', childScope); + safeAddClass($node, 'ng-scope'); } else { childScope = scope; } @@ -4971,7 +5581,8 @@ attrs[nName] = true; // presence means true } addAttrInterpolateDirective(node, directives, value, nName); - addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, attrEndName); + addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, + attrEndName); } } @@ -5000,7 +5611,8 @@ } } } catch (e) { - // turns out that under some circumstances IE9 throws errors when one attempts to read comment's node value. + // turns out that under some circumstances IE9 throws errors when one attempts to read + // comment's node value. // Just ignore it and continue. (Can't seem to reproduce in test case.) } break; @@ -5011,7 +5623,8 @@ } /** - * Given a node with an directive-start it collects all of the siblings until it find directive-end. + * Given a node with an directive-start it collects all of the siblings until it finds + * directive-end. * @param node * @param attrStart * @param attrEnd @@ -5024,7 +5637,9 @@ var startNode = node; do { if (!node) { - throw $compileMinErr('uterdir', "Unterminated attribute, found '{0}' but no matching '{1}' found.", attrStart, attrEnd); + throw $compileMinErr('uterdir', + "Unterminated attribute, found '{0}' but no matching '{1}' found.", + attrStart, attrEnd); } if (node.nodeType == 1 /** Element **/) { if (node.hasAttribute(attrStart)) depth++; @@ -5052,7 +5667,7 @@ return function(scope, element, attrs, controllers) { element = groupScan(element[0], attrStart, attrEnd); return linkFn(scope, element, attrs, controllers); - } + }; } /** @@ -5065,32 +5680,36 @@ * @param {Node} compileNode The raw DOM node to apply the compile functions to * @param {Object} templateAttrs The shared attribute function * @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the - * scope argument is auto-generated to the new child of the transcluded parent scope. + * scope argument is auto-generated to the new + * child of the transcluded parent scope. * @param {JQLite} jqCollection If we are working on the root of the compile tree then this - * argument has the root jqLite array so that we can replace nodes on it. - * @param {Object=} originalReplaceDirective An optional directive that will be ignored when compiling - * the transclusion. + * argument has the root jqLite array so that we can replace nodes + * on it. + * @param {Object=} originalReplaceDirective An optional directive that will be ignored when + * compiling the transclusion. * @param {Array.<Function>} preLinkFns * @param {Array.<Function>} postLinkFns - * @param {Object} previousCompileContext Context used for previous compilation of the current node + * @param {Object} previousCompileContext Context used for previous compilation of the current + * node * @returns linkFn */ - function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection, - originalReplaceDirective, preLinkFns, postLinkFns, previousCompileContext) { + function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, + jqCollection, originalReplaceDirective, preLinkFns, postLinkFns, + previousCompileContext) { previousCompileContext = previousCompileContext || {}; var terminalPriority = -Number.MAX_VALUE, newScopeDirective, + controllerDirectives = previousCompileContext.controllerDirectives, newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective, templateDirective = previousCompileContext.templateDirective, + transcludeDirective = previousCompileContext.transcludeDirective, $compileNode = templateAttrs.$$element = jqLite(compileNode), directive, directiveName, $template, - transcludeDirective = previousCompileContext.transcludeDirective, replaceDirective = originalReplaceDirective, childTranscludeFn = transcludeFn, - controllerDirectives, linkFn, directiveValue; @@ -5102,7 +5721,7 @@ // collect multiblock sections if (attrStart) { - $compileNode = groupScan(compileNode, attrStart, attrEnd) + $compileNode = groupScan(compileNode, attrStart, attrEnd); } $template = undefined; @@ -5113,15 +5732,14 @@ if (directiveValue = directive.scope) { newScopeDirective = newScopeDirective || directive; - // skip the check for directives with async templates, we'll check the derived sync directive when - // the template arrives + // skip the check for directives with async templates, we'll check the derived sync + // directive when the template arrives if (!directive.templateUrl) { - assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive, $compileNode); + assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive, + $compileNode); if (isObject(directiveValue)) { - safeAddClass($compileNode, 'ng-isolate-scope'); newIsolateScopeDirective = directive; } - safeAddClass($compileNode, 'ng-scope'); } } @@ -5136,9 +5754,10 @@ } if (directiveValue = directive.transclude) { - // Special case ngRepeat so that we don't complain about duplicate transclusion, ngRepeat knows how to handle - // this on its own. - if (directiveName !== 'ngRepeat') { + // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion. + // This option should only be used by directives that know how to how to safely handle element transclusion, + // where the transcluded nodes are added or replaced after linking. + if (!directive.$$tlb) { assertNoDuplicate('transclusion', transcludeDirective, directive, $compileNode); transcludeDirective = directive; } @@ -5147,18 +5766,24 @@ terminalPriority = directive.priority; $template = groupScan(compileNode, attrStart, attrEnd); $compileNode = templateAttrs.$$element = - jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' ')); + jqLite(document.createComment(' ' + directiveName + ': ' + + templateAttrs[directiveName] + ' ')); compileNode = $compileNode[0]; replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode); childTranscludeFn = compile($template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, { - newIsolateScopeDirective: newIsolateScopeDirective, - transcludeDirective: transcludeDirective, - templateDirective: templateDirective + // Don't pass in: + // - controllerDirectives - otherwise we'll create duplicates controllers + // - newIsolateScopeDirective or templateDirective - combining templates with + // element transclusion doesn't make sense. + // + // We need only transcludeDirective so that we prevent putting transclusion + // on the same element more than once. + transcludeDirective: transcludeDirective }); } else { - $template = jqLite(JQLiteClone(compileNode)).contents(); + $template = jqLite(jqLiteClone(compileNode)).contents(); $compileNode.html(''); // clear contents childTranscludeFn = compile($template, transcludeFn); } @@ -5182,7 +5807,9 @@ compileNode = $template[0]; if ($template.length != 1 || compileNode.nodeType !== 1) { - throw $compileMinErr('tplrt', "Template for directive '{0}' must have exactly one root element. {1}", directiveName, ''); + throw $compileMinErr('tplrt', + "Template for directive '{0}' must have exactly one root element. {1}", + directiveName, ''); } replaceWith(jqCollection, $compileNode, compileNode); @@ -5191,16 +5818,16 @@ // combine directives from the original node and from the template: // - take the array of directives for this element - // - split it into two parts, those that were already applied and those that weren't - // - collect directives from the template, add them to the second group and sort them - // - append the second group with new directives to the first group - directives = directives.concat( - collectDirectives( - compileNode, - directives.splice(i + 1, directives.length - (i + 1)), - newTemplateAttrs - ) - ); + // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed) + // - collect directives from the template and sort them by priority + // - combine directives as: processed + template + unprocessed + var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs); + var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1)); + + if (newIsolateScopeDirective) { + markDirectivesAsIsolate(templateDirectives); + } + directives = directives.concat(templateDirectives).concat(unprocessedDirectives); mergeTemplateAttributes(templateAttrs, newTemplateAttrs); ii = directives.length; @@ -5219,9 +5846,10 @@ nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, { + controllerDirectives: controllerDirectives, newIsolateScopeDirective: newIsolateScopeDirective, - transcludeDirective: transcludeDirective, - templateDirective: templateDirective + templateDirective: templateDirective, + transcludeDirective: transcludeDirective }); ii = directives.length; } else if (directive.compile) { @@ -5244,7 +5872,7 @@ } - nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope; + nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true; nodeLinkFn.transclude = transcludeDirective && childTranscludeFn; // might be normal or delayed nodeLinkFn depending on if templateUrl is present @@ -5256,11 +5884,17 @@ if (pre) { if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd); pre.require = directive.require; + if (newIsolateScopeDirective === directive || directive.$$isolateScope) { + pre = cloneAndAnnotateFn(pre, {isolateScope: true}); + } preLinkFns.push(pre); } if (post) { if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd); post.require = directive.require; + if (newIsolateScopeDirective === directive || directive.$$isolateScope) { + post = cloneAndAnnotateFn(post, {isolateScope: true}); + } postLinkFns.push(post); } } @@ -5285,7 +5919,9 @@ } if (!value && !optional) { - throw $compileMinErr('ctreq', "Controller '{0}', required by directive '{1}', can't be found!", require, directiveName); + throw $compileMinErr('ctreq', + "Controller '{0}', required by directive '{1}', can't be found!", + require, directiveName); } return value; } else if (isArray(require)) { @@ -5299,7 +5935,7 @@ function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { - var attrs, $element, i, ii, linkFn, controller; + var attrs, $element, i, ii, linkFn, controller, isolateScope; if (compileNode === linkNode) { attrs = templateAttrs; @@ -5310,9 +5946,20 @@ if (newIsolateScopeDirective) { var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/; + var $linkNode = jqLite(linkNode); - var parentScope = scope.$parent || scope; + isolateScope = scope.$new(true); + if (templateDirective && (templateDirective === newIsolateScopeDirective.$$originalDirective)) { + $linkNode.data('$isolateScope', isolateScope) ; + } else { + $linkNode.data('$isolateScopeNoTemplate', isolateScope); + } + + + + safeAddClass($linkNode, 'ng-isolate-scope'); + forEach(newIsolateScopeDirective.scope, function(definition, scopeName) { var match = definition.match(LOCAL_REGEXP) || [], attrName = match[3] || scopeName, @@ -5321,64 +5968,64 @@ lastValue, parentGet, parentSet; - scope.$$isolateBindings[scopeName] = mode + attrName; + isolateScope.$$isolateBindings[scopeName] = mode + attrName; switch (mode) { - case '@': { + case '@': attrs.$observe(attrName, function(value) { - scope[scopeName] = value; + isolateScope[scopeName] = value; }); - attrs.$$observers[attrName].$$scope = parentScope; + attrs.$$observers[attrName].$$scope = scope; if( attrs[attrName] ) { - // If the attribute has been provided then we trigger an interpolation to ensure the value is there for use in the link fn - scope[scopeName] = $interpolate(attrs[attrName])(parentScope); + // If the attribute has been provided then we trigger an interpolation to ensure + // the value is there for use in the link fn + isolateScope[scopeName] = $interpolate(attrs[attrName])(scope); } break; - } - case '=': { + case '=': if (optional && !attrs[attrName]) { return; } parentGet = $parse(attrs[attrName]); parentSet = parentGet.assign || function() { // reset the change, or we will throw this exception on every $digest - lastValue = scope[scopeName] = parentGet(parentScope); - throw $compileMinErr('nonassign', "Expression '{0}' used with directive '{1}' is non-assignable!", + lastValue = isolateScope[scopeName] = parentGet(scope); + throw $compileMinErr('nonassign', + "Expression '{0}' used with directive '{1}' is non-assignable!", attrs[attrName], newIsolateScopeDirective.name); }; - lastValue = scope[scopeName] = parentGet(parentScope); - scope.$watch(function parentValueWatch() { - var parentValue = parentGet(parentScope); + lastValue = isolateScope[scopeName] = parentGet(scope); + isolateScope.$watch(function parentValueWatch() { + var parentValue = parentGet(scope); - if (parentValue !== scope[scopeName]) { + if (parentValue !== isolateScope[scopeName]) { // we are out of sync and need to copy if (parentValue !== lastValue) { // parent changed and it has precedence - lastValue = scope[scopeName] = parentValue; + lastValue = isolateScope[scopeName] = parentValue; } else { // if the parent can be assigned then do so - parentSet(parentScope, parentValue = lastValue = scope[scopeName]); + parentSet(scope, parentValue = lastValue = isolateScope[scopeName]); } } return parentValue; }); break; - } - case '&': { + case '&': parentGet = $parse(attrs[attrName]); - scope[scopeName] = function(locals) { - return parentGet(parentScope, locals); + isolateScope[scopeName] = function(locals) { + return parentGet(scope, locals); }; break; - } - default: { - throw $compileMinErr('iscp', "Invalid isolate scope definition for directive '{0}'. Definition: {... {1}: '{2}' ...}", + default: + throw $compileMinErr('iscp', + "Invalid isolate scope definition for directive '{0}'." + + " Definition: {... {1}: '{2}' ...}", newIsolateScopeDirective.name, scopeName, definition); - } } }); } @@ -5386,7 +6033,7 @@ if (controllerDirectives) { forEach(controllerDirectives, function(directive) { var locals = { - $scope: scope, + $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope, $element: $element, $attrs: attrs, $transclude: boundTranscludeFn @@ -5418,7 +6065,7 @@ for(i = 0, ii = preLinkFns.length; i < ii; i++) { try { linkFn = preLinkFns[i]; - linkFn(scope, $element, attrs, + linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, linkFn.require && getControllers(linkFn.require, $element)); } catch (e) { $exceptionHandler(e, startingTag($element)); @@ -5426,13 +6073,19 @@ } // RECURSION - childLinkFn && childLinkFn(scope, linkNode.childNodes, undefined, boundTranscludeFn); + // We only pass the isolate scope, if the isolate directive has a template, + // otherwise the child elements do not belong to the isolate directive. + var scopeToChild = scope; + if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) { + scopeToChild = isolateScope; + } + childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn); // POSTLINKING for(i = postLinkFns.length - 1; i >= 0; i--) { try { linkFn = postLinkFns[i]; - linkFn(scope, $element, attrs, + linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs, linkFn.require && getControllers(linkFn.require, $element)); } catch (e) { $exceptionHandler(e, startingTag($element)); @@ -5441,6 +6094,12 @@ } } + function markDirectivesAsIsolate(directives) { + // mark all directives as needing isolate scope. + for (var j = 0, jj = directives.length; j < jj; j++) { + directives[j] = inherit(directives[j], {$$isolateScope: true}); + } + } /** * looks up the directive and decorates it with exception handling and proper parameters. We @@ -5456,7 +6115,8 @@ * * `M`: comment * @returns true if directive was added. */ - function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName, endAttrName) { + function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName, + endAttrName) { if (name === ignoreDirective) return null; var match = null; if (hasDirectives.hasOwnProperty(name)) { @@ -5529,7 +6189,7 @@ origAsyncDirective = directives.shift(), // The fact that we have to copy and patch the directive seems wrong! derivedSyncDirective = extend({}, origAsyncDirective, { - templateUrl: null, transclude: null, replace: null + templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective }), templateUrl = (isFunction(origAsyncDirective.templateUrl)) ? origAsyncDirective.templateUrl($compileNode, tAttrs) @@ -5548,13 +6208,19 @@ compileNode = $template[0]; if ($template.length != 1 || compileNode.nodeType !== 1) { - throw $compileMinErr('tplrt', "Template for directive '{0}' must have exactly one root element. {1}", + throw $compileMinErr('tplrt', + "Template for directive '{0}' must have exactly one root element. {1}", origAsyncDirective.name, templateUrl); } tempTemplateAttrs = {$attr: {}}; replaceWith($rootElement, $compileNode, compileNode); - collectDirectives(compileNode, directives, tempTemplateAttrs); + var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs); + + if (isObject(origAsyncDirective.scope)) { + markDirectivesAsIsolate(templateDirectives); + } + directives = templateDirectives.concat(directives); mergeTemplateAttributes(tAttrs, tempTemplateAttrs); } else { compileNode = beforeTemplateCompileNode; @@ -5564,7 +6230,8 @@ directives.unshift(derivedSyncDirective); afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, - childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns, previousCompileContext); + childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns, + previousCompileContext); forEach($rootElement, function(node, i) { if (node == compileNode) { $rootElement[i] = $compileNode[0]; @@ -5582,11 +6249,12 @@ if (beforeTemplateLinkNode !== beforeTemplateCompileNode) { // it was cloned therefore we have to clone as well. - linkNode = JQLiteClone(compileNode); + linkNode = jqLiteClone(compileNode); replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode); } - afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller); + afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, + controller); } linkQueue = null; }). @@ -5663,37 +6331,43 @@ if (name === "multiple" && nodeName_(node) === "SELECT") { - throw $compileMinErr("selmulti", "Binding to the 'multiple' attribute is not supported. Element: {0}", + throw $compileMinErr("selmulti", + "Binding to the 'multiple' attribute is not supported. Element: {0}", startingTag(node)); } directives.push({ - priority: -100, - compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) { - var $$observers = (attr.$$observers || (attr.$$observers = {})); + priority: 100, + compile: function() { + return { + pre: function attrInterpolatePreLinkFn(scope, element, attr) { + var $$observers = (attr.$$observers || (attr.$$observers = {})); - if (EVENT_HANDLER_ATTR_REGEXP.test(name)) { - throw $compileMinErr('nodomevents', - "Interpolations for HTML DOM event attributes are disallowed. Please use the ng- " + - "versions (such as ng-click instead of onclick) instead."); - } + if (EVENT_HANDLER_ATTR_REGEXP.test(name)) { + throw $compileMinErr('nodomevents', + "Interpolations for HTML DOM event attributes are disallowed. Please use the " + + "ng- versions (such as ng-click instead of onclick) instead."); + } - // we need to interpolate again, in case the attribute value has been updated - // (e.g. by another directive's compile function) - interpolateFn = $interpolate(attr[name], true, getTrustedContext(node, name)); + // we need to interpolate again, in case the attribute value has been updated + // (e.g. by another directive's compile function) + interpolateFn = $interpolate(attr[name], true, getTrustedContext(node, name)); - // if attribute was updated so that there is no interpolation going on we don't want to - // register any observers - if (!interpolateFn) return; + // if attribute was updated so that there is no interpolation going on we don't want to + // register any observers + if (!interpolateFn) return; - // TODO(i): this should likely be attr.$set(name, iterpolateFn(scope) so that we reset the actual attr value - attr[name] = interpolateFn(scope); - ($$observers[name] || ($$observers[name] = [])).$$inter = true; - (attr.$$observers && attr.$$observers[name].$$scope || scope). - $watch(interpolateFn, function interpolateFnWatchAction(value) { - attr.$set(name, value); - }); - }) + // TODO(i): this should likely be attr.$set(name, iterpolateFn(scope) so that we reset the + // actual attr value + attr[name] = interpolateFn(scope); + ($$observers[name] || ($$observers[name] = [])).$$inter = true; + (attr.$$observers && attr.$$observers[name].$$scope || scope). + $watch(interpolateFn, function interpolateFnWatchAction(value) { + attr.$set(name, value); + }); + } + }; + } }); } @@ -5703,9 +6377,9 @@ * have no parents, provided that the containing jqLite collection is provided. * * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes - * in the root of the tree. - * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep the shell, - * but replace its DOM node reference. + * in the root of the tree. + * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep + * the shell, but replace its DOM node reference. * @param {Node} newNode The new DOM node. */ function replaceWith($rootElement, elementsToRemove, newNode) { @@ -5747,8 +6421,13 @@ } elementsToRemove[0] = newNode; - elementsToRemove.length = 1 + elementsToRemove.length = 1; } + + + function cloneAndAnnotateFn(fn, annotation) { + return extend(function() { return fn.apply(null, arguments); }, fn, annotation); + } }]; } @@ -5771,13 +6450,13 @@ /** * @ngdoc object * @name ng.$compile.directive.Attributes + * * @description + * A shared object between directive compile / linking functions which contains normalized DOM + * element attributes. The values reflect current binding state `{{ }}`. The normalization is + * needed since all of these are treated as equivalent in Angular: * - * A shared object between directive compile / linking functions which contains normalized DOM element - * attributes. The the values reflect current binding state `{{ }}`. The normalization is needed - * since all of these are treated as equivalent in Angular: - * - * <span ng:bind="a" ng-bind="a" data-ng-bind="a" x-ng-bind="a"> + * <span ng:bind="a" ng-bind="a" data-ng-bind="a" x-ng-bind="a"> */ /** @@ -5785,7 +6464,7 @@ * @name ng.$compile.directive.Attributes#$attr * @propertyOf ng.$compile.directive.Attributes * @returns {object} A map of DOM element attribute names to the normalized name. This is - * needed to do reverse lookup from normalized name back to actual name. + * needed to do reverse lookup from normalized name back to actual name. */ @@ -5834,7 +6513,7 @@ * controllers. * * This provider allows controller registration via the - * {@link ng.$controllerProvider#register register} method. + * {@link ng.$controllerProvider#methods_register register} method. */ function $ControllerProvider() { var controllers = {}, @@ -5853,7 +6532,7 @@ this.register = function(name, constructor) { assertNotHasOwnProperty(name, 'controller'); if (isObject(name)) { - extend(controllers, name) + extend(controllers, name); } else { controllers[name] = constructor; } @@ -5903,7 +6582,9 @@ if (identifier) { if (!(locals && typeof locals.$scope == 'object')) { - throw minErr('$controller')('noscp', "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", constructor || expression.name, identifier); + throw minErr('$controller')('noscp', + "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", + constructor || expression.name, identifier); } locals.$scope[identifier] = instance; @@ -6193,11 +6874,11 @@ * called for such responses. * * # Calling $http from outside AngularJS - * The `$http` service will not actually send the request until the next `$digest()` is executed. - * Normally this is not an issue, since almost all the time your call to `$http` will be from within - * a `$apply()` block. - * If you are calling `$http` from outside Angular, then you should wrap it in a call to `$apply` - * to cause a $digest to occur and also to handle errors in the block correctly. + * The `$http` service will not actually send the request until the next `$digest()` is + * executed. Normally this is not an issue, since almost all the time your call to `$http` will + * be from within a `$apply()` block. + * If you are calling `$http` from outside Angular, then you should wrap it in a call to + * `$apply` to cause a $digest to occur and also to handle errors in the block correctly. * * ``` * $scope.$apply(function() { @@ -6206,10 +6887,11 @@ * ``` * * # Writing Unit Tests that use $http - * When unit testing you are mostly responsible for scheduling the `$digest` cycle. If you do not - * trigger a `$digest` before calling `$httpBackend.flush()` then the request will not have been - * made and `$httpBackend.expect(...)` expectations will fail. The solution is to run the code - * that calls the `$http()` method inside a $apply block as explained in the previous section. + * When unit testing you are mostly responsible for scheduling the `$digest` cycle. If you do + * not trigger a `$digest` before calling `$httpBackend.flush()` then the request will not have + * been made and `$httpBackend.expect(...)` expectations will fail. The solution is to run the + * code that calls the `$http()` method inside a $apply block as explained in the previous + * section. * * ``` * $httpBackend.expectGET(...); @@ -6232,12 +6914,12 @@ * * Complete list of shortcut methods: * - * - {@link ng.$http#get $http.get} - * - {@link ng.$http#head $http.head} - * - {@link ng.$http#post $http.post} - * - {@link ng.$http#put $http.put} - * - {@link ng.$http#delete $http.delete} - * - {@link ng.$http#jsonp $http.jsonp} + * - {@link ng.$http#methods_get $http.get} + * - {@link ng.$http#methods_head $http.head} + * - {@link ng.$http#methods_post $http.post} + * - {@link ng.$http#methods_put $http.put} + * - {@link ng.$http#methods_delete $http.delete} + * - {@link ng.$http#methods_jsonp $http.jsonp} * * * # Setting HTTP Headers @@ -6258,8 +6940,9 @@ * with the lowercased HTTP method name as the key, e.g. * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }. * - * Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same - * fashion. + * The defaults can also be set at runtime via the `$http.defaults` object in the same + * fashion. In addition, you can supply a `headers` property in the config object passed when + * calling `$http(config)`, which overrides the defaults without changing them globally. * * * # Transforming Requests and Responses @@ -6269,22 +6952,24 @@ * * Request transformations: * - * - If the `data` property of the request configuration object contains an object, serialize it into - * JSON format. + * - If the `data` property of the request configuration object contains an object, serialize it + * into JSON format. * * Response transformations: * * - If XSRF prefix is detected, strip it (see Security Considerations section below). * - If JSON response is detected, deserialize it using a JSON parser. * - * To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and - * `$httpProvider.defaults.transformResponse` properties. These properties are by default an - * array of transform functions, which allows you to `push` or `unshift` a new transformation function into the - * transformation chain. You can also decide to completely override any default transformations by assigning your + * To globally augment or override the default transforms, modify the + * `$httpProvider.defaults.transformRequest` and `$httpProvider.defaults.transformResponse` + * properties. These properties are by default an array of transform functions, which allows you + * to `push` or `unshift` a new transformation function into the transformation chain. You can + * also decide to completely override any default transformations by assigning your * transformation functions to these properties directly without the array wrapper. * - * Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or - * `transformResponse` properties of the configuration object passed into `$http`. + * Similarly, to locally override the request/response transforms, augment the + * `transformRequest` and/or `transformResponse` properties of the configuration object passed + * into `$http`. * * * # Caching @@ -6322,16 +7007,16 @@ * * There are two kinds of interceptors (and two kinds of rejection interceptors): * - * * `request`: interceptors get called with http `config` object. The function is free to modify - * the `config` or create a new one. The function needs to return the `config` directly or as a - * promise. - * * `requestError`: interceptor gets called when a previous interceptor threw an error or resolved - * with a rejection. - * * `response`: interceptors get called with http `response` object. The function is free to modify - * the `response` or create a new one. The function needs to return the `response` directly or as a - * promise. - * * `responseError`: interceptor gets called when a previous interceptor threw an error or resolved - * with a rejection. + * * `request`: interceptors get called with http `config` object. The function is free to + * modify the `config` or create a new one. The function needs to return the `config` + * directly or as a promise. + * * `requestError`: interceptor gets called when a previous interceptor threw an error or + * resolved with a rejection. + * * `response`: interceptors get called with http `response` object. The function is free to + * modify the `response` or create a new one. The function needs to return the `response` + * directly or as a promise. + * * `responseError`: interceptor gets called when a previous interceptor threw an error or + * resolved with a rejection. * * * <pre> @@ -6384,6 +7069,7 @@ * 'response': function(response) { * // same as above * } + * }; * }); * </pre> * @@ -6480,9 +7166,10 @@ * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure * that only JavaScript running on your domain could have sent the request. The token must be - * unique for each user and must be verifiable by the server (to prevent the JavaScript from making - * up its own tokens). We recommend that the token is a digest of your site's authentication - * cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security. + * unique for each user and must be verifiable by the server (to prevent the JavaScript from + * making up its own tokens). We recommend that the token is a digest of your site's + * authentication cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} + * for added security. * * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName * properties of either $httpProvider.defaults, or the per-request config object. @@ -6493,18 +7180,21 @@ * * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc) * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested. - * - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned to - * `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified. + * - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned + * to `?key1=value1&key2=value2` after the url. If the value is not a string, it will be + * JSONified. * - **data** – `{string|Object}` – Data to be sent as the request message data. * - **headers** – `{Object}` – Map of strings or functions which return strings representing - * HTTP headers to send to the server. If the return value of a function is null, the header will - * not be sent. + * HTTP headers to send to the server. If the return value of a function is null, the + * header will not be sent. * - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token. * - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token. - * - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` – + * - **transformRequest** – + * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` – * transform function or an array of such functions. The transform function takes the http * request body and headers and returns its transformed (typically serialized) version. - * - **transformResponse** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` – + * - **transformResponse** – + * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` – * transform function or an array of such functions. The transform function takes the http * response body and headers and returns its transformed (typically deserialized) version. * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the @@ -6527,7 +7217,8 @@ * these functions are destructured representation of the response object passed into the * `then` method. The response object has these properties: * - * - **data** – `{string|Object}` – The response body transformed with the transform functions. + * - **data** – `{string|Object}` – The response body transformed with the transform + * functions. * - **status** – `{number}` – HTTP status code of the response. * - **headers** – `{function([headerName])}` – Header getter function. * - **config** – `{Object}` – The configuration object that was used to generate the request. @@ -6537,75 +7228,82 @@ * * * @example - <example> - <file name="index.html"> - <div ng-controller="FetchCtrl"> - <select ng-model="method"> - <option>GET</option> - <option>JSONP</option> - </select> - <input type="text" ng-model="url" size="80"/> - <button ng-click="fetch()">fetch</button><br> - <button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button> - <button ng-click="updateModel('JSONP', 'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">Sample JSONP</button> - <button ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">Invalid JSONP</button> - <pre>http status code: {{status}}</pre> - <pre>http response data: {{data}}</pre> - </div> - </file> - <file name="script.js"> - function FetchCtrl($scope, $http, $templateCache) { - $scope.method = 'GET'; - $scope.url = 'http-hello.html'; +<example> +<file name="index.html"> + <div ng-controller="FetchCtrl"> + <select ng-model="method"> + <option>GET</option> + <option>JSONP</option> + </select> + <input type="text" ng-model="url" size="80"/> + <button ng-click="fetch()">fetch</button><br> + <button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button> + <button + ng-click="updateModel('JSONP', + 'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')"> + Sample JSONP + </button> + <button + ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')"> + Invalid JSONP + </button> + <pre>http status code: {{status}}</pre> + <pre>http response data: {{data}}</pre> + </div> +</file> +<file name="script.js"> + function FetchCtrl($scope, $http, $templateCache) { + $scope.method = 'GET'; + $scope.url = 'http-hello.html'; - $scope.fetch = function() { - $scope.code = null; - $scope.response = null; + $scope.fetch = function() { + $scope.code = null; + $scope.response = null; - $http({method: $scope.method, url: $scope.url, cache: $templateCache}). - success(function(data, status) { - $scope.status = status; - $scope.data = data; - }). - error(function(data, status) { - $scope.data = data || "Request failed"; - $scope.status = status; - }); - }; + $http({method: $scope.method, url: $scope.url, cache: $templateCache}). + success(function(data, status) { + $scope.status = status; + $scope.data = data; + }). + error(function(data, status) { + $scope.data = data || "Request failed"; + $scope.status = status; + }); + }; - $scope.updateModel = function(method, url) { - $scope.method = method; - $scope.url = url; - }; - } - </file> - <file name="http-hello.html"> - Hello, $http! - </file> - <file name="scenario.js"> - it('should make an xhr GET request', function() { - element(':button:contains("Sample GET")').click(); - element(':button:contains("fetch")').click(); - expect(binding('status')).toBe('200'); - expect(binding('data')).toMatch(/Hello, \$http!/); - }); + $scope.updateModel = function(method, url) { + $scope.method = method; + $scope.url = url; + }; + } +</file> +<file name="http-hello.html"> + Hello, $http! +</file> +<file name="scenario.js"> + it('should make an xhr GET request', function() { + element(':button:contains("Sample GET")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('200'); + expect(binding('data')).toMatch(/Hello, \$http!/); + }); - it('should make a JSONP request to angularjs.org', function() { - element(':button:contains("Sample JSONP")').click(); - element(':button:contains("fetch")').click(); - expect(binding('status')).toBe('200'); - expect(binding('data')).toMatch(/Super Hero!/); - }); + it('should make a JSONP request to angularjs.org', function() { + element(':button:contains("Sample JSONP")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('200'); + expect(binding('data')).toMatch(/Super Hero!/); + }); - it('should make JSONP request to invalid URL and invoke the error handler', - function() { - element(':button:contains("Invalid JSONP")').click(); - element(':button:contains("fetch")').click(); - expect(binding('status')).toBe('0'); - expect(binding('data')).toBe('Request failed'); - }); - </file> - </example> + it('should make JSONP request to invalid URL and invoke the error handler', + function() { + element(':button:contains("Invalid JSONP")').click(); + element(':button:contains("fetch")').click(); + expect(binding('status')).toBe('0'); + expect(binding('data')).toBe('Request failed'); + }); +</file> +</example> */ function $http(requestConfig) { var config = { @@ -6965,7 +7663,7 @@ if (!params) return url; var parts = []; forEachSorted(params, function(value, key) { - if (value == null || value == undefined) return; + if (value === null || isUndefined(value)) return; if (!isArray(value)) value = [value]; forEach(value, function(v) { @@ -6984,6 +7682,7 @@ } var XHR = window.XMLHttpRequest || function() { + /* global ActiveXObject */ try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} @@ -7054,7 +7753,7 @@ var responseHeaders = xhr.getAllResponseHeaders(); // responseText is the old-school way of retrieving response (supported by IE8 & 9) - // response and responseType properties were introduced in XHR Level2 spec (supported by IE10) + // response/responseType properties were introduced in XHR Level2 spec (supported by IE10) completeRequest(callback, status || xhr.status, (xhr.responseType ? xhr.response : xhr.responseText), @@ -7142,31 +7841,31 @@ * Used for configuring the interpolation markup. Defaults to `{{` and `}}`. * * @example - <doc:example module="customInterpolationApp"> - <doc:source> - <script> - var customInterpolationApp = angular.module('customInterpolationApp', []); +<doc:example module="customInterpolationApp"> +<doc:source> +<script> + var customInterpolationApp = angular.module('customInterpolationApp', []); - customInterpolationApp.config(function($interpolateProvider) { - $interpolateProvider.startSymbol('//'); - $interpolateProvider.endSymbol('//'); - }); + customInterpolationApp.config(function($interpolateProvider) { + $interpolateProvider.startSymbol('//'); + $interpolateProvider.endSymbol('//'); + }); - customInterpolationApp.controller('DemoController', function DemoController() { - this.label = "This bindings is brought you you by // interpolation symbols."; - }); - </script> - <div ng-app="App" ng-controller="DemoController as demo"> - //demo.label// - </div> - </doc:source> - <doc:scenario> - it('should interpolate binding with custom symbols', function() { - expect(binding('demo.label')).toBe('This bindings is brought you you by // interpolation symbols.'); - }); - </doc:scenario> - </doc:example> + customInterpolationApp.controller('DemoController', function DemoController() { + this.label = "This binding is brought you by // interpolation symbols."; + }); +</script> +<div ng-app="App" ng-controller="DemoController as demo"> + //demo.label// +</div> +</doc:source> +<doc:scenario> + it('should interpolate binding with custom symbols', function() { + expect(binding('demo.label')).toBe('This binding is brought you by // interpolation symbols.'); + }); +</doc:scenario> +</doc:example> */ function $InterpolateProvider() { var startSymbol = '{{'; @@ -7243,11 +7942,11 @@ * embedded expression in order to return an interpolation function. Strings with no * embedded expression will return null for the interpolation function. * @param {string=} trustedContext when provided, the returned function passes the interpolated - * result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult, + * result through {@link ng.$sce#methods_getTrusted $sce.getTrusted(interpolatedResult, * trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that * provides Strict Contextual Escaping for details. - * @returns {function(context)} an interpolation function which is used to compute the interpolated - * string. The function has these parameters: + * @returns {function(context)} an interpolation function which is used to compute the + * interpolated string. The function has these parameters: * * * `context`: an object against which any expressions embedded in the strings are evaluated * against. @@ -7285,12 +7984,12 @@ length = 1; } - // Concatenating expressions makes it hard to reason about whether some combination of concatenated - // values are unsafe to use and could easily lead to XSS. By requiring that a single - // expression be used for iframe[src], object[src], etc., we ensure that the value that's used - // is assigned or constructed by some JS code somewhere that is more testable or make it - // obvious that you bound the value to some user controlled value. This helps reduce the load - // when auditing for XSS issues. + // Concatenating expressions makes it hard to reason about whether some combination of + // concatenated values are unsafe to use and could easily lead to XSS. By requiring that a + // single expression be used for iframe[src], object[src], etc., we ensure that the value + // that's used is assigned or constructed by some JS code somewhere that is more testable or + // make it obvious that you bound the value to some user controlled value. This helps reduce + // the load when auditing for XSS issues. if (trustedContext && parts.length > 1) { throw $interpolateMinErr('noconcat', "Error while interpolating: {0}\nStrict Contextual Escaping disallows " + @@ -7310,7 +8009,7 @@ } else { part = $sce.valueOf(part); } - if (part == null || part == undefined) { + if (part === null || isUndefined(part)) { part = ''; } else if (typeof part != 'string') { part = toJson(part); @@ -7321,7 +8020,8 @@ return concat.join(''); } catch(err) { - var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text, err.toString()); + var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text, + err.toString()); $exceptionHandler(newErr); } }; @@ -7346,7 +8046,7 @@ */ $interpolate.startSymbol = function() { return startSymbol; - } + }; /** @@ -7363,7 +8063,7 @@ */ $interpolate.endSymbol = function() { return endSymbol; - } + }; return $interpolate; }]; @@ -7389,7 +8089,7 @@ * number of iterations that have run. * To cancel an interval, call `$interval.cancel(promise)`. * - * In tests you can use {@link ngMock.$interval#flush `$interval.flush(millis)`} to + * In tests you can use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to * move forward by `millis` milliseconds and trigger any functions scheduled to run in that * time. * @@ -7398,18 +8098,18 @@ * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat * indefinitely. * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise - * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. + * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block. * @returns {promise} A promise which will be notified on each iteration. */ function interval(fn, delay, count, invokeApply) { var setInterval = $window.setInterval, - clearInterval = $window.clearInterval; - - var deferred = $q.defer(), + clearInterval = $window.clearInterval, + deferred = $q.defer(), promise = deferred.promise, - count = (isDefined(count)) ? count : 0, iteration = 0, skipApply = (isDefined(invokeApply) && !invokeApply); + + count = isDefined(count) ? count : 0, promise.then(null, null, fn); @@ -7502,8 +8202,9 @@ }, DATETIME_FORMATS: { - MONTH: 'January,February,March,April,May,June,July,August,September,October,November,December' - .split(','), + MONTH: + 'January,February,March,April,May,June,July,August,September,October,November,December' + .split(','), SHORTMONTH: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','), DAY: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','), SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','), @@ -7565,12 +8266,15 @@ relativeUrl = '/' + relativeUrl; } var match = urlResolve(relativeUrl); - locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ? match.pathname.substring(1) : match.pathname); + locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ? + match.pathname.substring(1) : match.pathname); locationObj.$$search = parseKeyValue(match.search); locationObj.$$hash = decodeURIComponent(match.hash); // make sure path starts with '/'; - if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') locationObj.$$path = '/' + locationObj.$$path; + if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') { + locationObj.$$path = '/' + locationObj.$$path; + } } @@ -7578,10 +8282,11 @@ * * @param {string} begin * @param {string} whole - * @returns {string} returns text from whole after begin or undefined if it does not begin with expected string. + * @returns {string} returns text from whole after begin or undefined if it does not begin with + * expected string. */ function beginsWith(begin, whole) { - if (whole.indexOf(begin) == 0) { + if (whole.indexOf(begin) === 0) { return whole.substr(begin.length); } } @@ -7626,7 +8331,8 @@ this.$$parse = function(url) { var pathUrl = beginsWith(appBaseNoFile, url); if (!isString(pathUrl)) { - throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url, appBaseNoFile); + throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url, + appBaseNoFile); } parseAppUrl(pathUrl, this); @@ -7665,7 +8371,7 @@ } else if (appBaseNoFile == url + '/') { return appBaseNoFile; } - } + }; } @@ -7698,7 +8404,8 @@ : ''; if (!isString(withoutHashUrl)) { - throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url, hashPrefix); + throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url, + hashPrefix); } parseAppUrl(withoutHashUrl, this); this.$$compose(); @@ -7720,7 +8427,7 @@ if(stripHash(appBase) == stripHash(url)) { return url; } - } + }; } @@ -7749,7 +8456,7 @@ } else if ( appBaseNoFile === url + '/') { return appBaseNoFile; } - } + }; } @@ -7888,11 +8595,14 @@ * * Change search part when called with parameter and return `$location`. * - * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or hash object. Hash object - * may contain an array of values, which will be decoded as duplicates in the url. - * @param {string=} paramValue If `search` is a string, then `paramValue` will override only a - * single search parameter. If the value is `null`, the parameter will be deleted. + * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or + * hash object. Hash object may contain an array of values, which will be decoded as duplicates in + * the url. * + * @param {(string|Array<string>)=} paramValue If `search` is a string, then `paramValue` will override only a + * single search parameter. If `paramValue` is an array, it will set the parameter as a + * comma-separated value. If `paramValue` is `null`, the parameter will be deleted. + * * @return {string} search */ search: function(search, paramValue) { @@ -7905,11 +8615,12 @@ } else if (isObject(search)) { this.$$search = search; } else { - throw $locationMinErr('isrcharg', 'The first argument of the `$location#search()` call must be a string or an object.'); + throw $locationMinErr('isrcharg', + 'The first argument of the `$location#search()` call must be a string or an object.'); } break; default: - if (paramValue == undefined || paramValue == null) { + if (isUndefined(paramValue) || paramValue === null) { delete this.$$search[search]; } else { this.$$search[search] = paramValue; @@ -8045,6 +8756,35 @@ } }; + /** + * @ngdoc event + * @name ng.$location#$locationChangeStart + * @eventOf ng.$location + * @eventType broadcast on root scope + * @description + * Broadcasted before a URL will change. This change can be prevented by calling + * `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on} for more + * details about event object. Upon successful change + * {@link ng.$location#$locationChangeSuccess $locationChangeSuccess} is fired. + * + * @param {Object} angularEvent Synthetic event object. + * @param {string} newUrl New URL + * @param {string=} oldUrl URL that was before it was changed. + */ + + /** + * @ngdoc event + * @name ng.$location#$locationChangeSuccess + * @eventOf ng.$location + * @eventType broadcast on root scope + * @description + * Broadcasted after a URL was changed. + * + * @param {Object} angularEvent Synthetic event object. + * @param {string} newUrl New URL + * @param {string=} oldUrl URL that was before it was changed. + */ + this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', function( $rootScope, $browser, $sniffer, $rootElement) { var $location, @@ -8101,7 +8841,8 @@ // update $location when $browser url changes $browser.onUrlChange(function(newUrl) { if ($location.absUrl() != newUrl) { - if ($rootScope.$broadcast('$locationChangeStart', newUrl, $location.absUrl()).defaultPrevented) { + if ($rootScope.$broadcast('$locationChangeStart', newUrl, + $location.absUrl()).defaultPrevented) { $browser.url($location.absUrl()); return; } @@ -8152,7 +8893,7 @@ * @requires $window * * @description - * Simple service for logging. Default implementation writes the message + * Simple service for logging. Default implementation safely writes the message * into the browser's console (if present). * * The main purpose of this service is to simplify debugging and troubleshooting. @@ -8201,12 +8942,12 @@ * @returns {*} current value if used as getter or itself (chaining) if used as setter */ this.debugEnabled = function(flag) { - if (isDefined(flag)) { - debug = flag; - return this; - } else { - return debug; - } + if (isDefined(flag)) { + debug = flag; + return this; + } else { + return debug; + } }; this.$get = ['$window', function($window){ @@ -8260,13 +9001,13 @@ * Write a debug message */ debug: (function () { - var fn = consoleLog('debug'); - - return function() { - if (debug) { - fn.apply(self, arguments); - } - } + var fn = consoleLog('debug'); + + return function() { + if (debug) { + fn.apply(self, arguments); + } + }; }()) }; @@ -8301,7 +9042,7 @@ // or we are IE where console.log doesn't have apply so we log at least first 2 args return function(arg1, arg2) { logFn(arg1, arg2 == null ? '' : arg2); - } + }; } }]; } @@ -8312,58 +9053,78 @@ // Sandboxing Angular Expressions // ------------------------------ -// Angular expressions are generally considered safe because these expressions only have direct access to $scope and -// locals. However, one can obtain the ability to execute arbitrary JS code by obtaining a reference to native JS -// functions such as the Function constructor. +// Angular expressions are generally considered safe because these expressions only have direct +// access to $scope and locals. However, one can obtain the ability to execute arbitrary JS code by +// obtaining a reference to native JS functions such as the Function constructor, the global Window +// or Document object. In addition, many powerful functions for use by JavaScript code are +// published on scope that shouldn't be available from within an Angular expression. // // As an example, consider the following Angular expression: // // {}.toString.constructor(alert("evil JS code")) // -// We want to prevent this type of access. For the sake of performance, during the lexing phase we disallow any "dotted" -// access to any member named "constructor". +// We want to prevent this type of access. For the sake of performance, during the lexing phase we +// disallow any "dotted" access to any member named "constructor" or to any member whose name begins +// or ends with an underscore. The latter allows one to exclude the private / JavaScript only API +// available on the scope and controllers from the context of an Angular expression. // -// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor while evaluating -// the expression, which is a stronger but more expensive test. Since reflective calls are expensive anyway, this is not -// such a big deal compared to static dereferencing. +// For reflective calls (a[b]), we check that the value of the lookup is not the Function +// constructor, Window or DOM node while evaluating the expression, which is a stronger but more +// expensive test. Since reflective calls are expensive anyway, this is not such a big deal compared +// to static dereferencing. // -// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits against the -// expression language, but not to prevent exploits that were enabled by exposing sensitive JavaScript or browser apis -// on Scope. Exposing such objects on a Scope is never a good practice and therefore we are not even trying to protect -// against interaction with an object explicitly exposed in this way. +// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits +// against the expression language, but not to prevent exploits that were enabled by exposing +// sensitive JavaScript or browser apis on Scope. Exposing such objects on a Scope is never a good +// practice and therefore we are not even trying to protect against interaction with an object +// explicitly exposed in this way. // -// A developer could foil the name check by aliasing the Function constructor under a different name on the scope. +// A developer could foil the name check by aliasing the Function constructor under a different +// name on the scope. // -// In general, it is not possible to access a Window object from an angular expression unless a window or some DOM -// object that has a reference to window is published onto a Scope. +// In general, it is not possible to access a Window object from an angular expression unless a +// window or some DOM object that has a reference to window is published onto a Scope. -function ensureSafeMemberName(name, fullExpression) { - if (name === "constructor") { +function ensureSafeMemberName(name, fullExpression, allowConstructor) { + if (typeof name !== 'string' && toString.apply(name) !== "[object String]") { + return name; + } + if (name === "constructor" && !allowConstructor) { throw $parseMinErr('isecfld', - 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', fullExpression); + 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', + fullExpression); } + if (name.charAt(0) === '_' || name.charAt(name.length-1) === '_') { + throw $parseMinErr('isecprv', + 'Referencing private fields in Angular expressions is disallowed! Expression: {0}', + fullExpression); + } return name; -}; +} function ensureSafeObject(obj, fullExpression) { // nifty check if obj is Function that is fast and works across iframes and other contexts if (obj && obj.constructor === obj) { throw $parseMinErr('isecfn', - 'Referencing Function in Angular expressions is disallowed! Expression: {0}', fullExpression); + 'Referencing Function in Angular expressions is disallowed! Expression: {0}', + fullExpression); } else if (// isWindow(obj) obj && obj.document && obj.location && obj.alert && obj.setInterval) { throw $parseMinErr('isecwindow', - 'Referencing the Window in Angular expressions is disallowed! Expression: {0}', fullExpression); + 'Referencing the Window in Angular expressions is disallowed! Expression: {0}', + fullExpression); } else if (// isElement(obj) obj && (obj.nodeName || (obj.on && obj.find))) { throw $parseMinErr('isecdom', - 'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}', fullExpression); + 'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}', + fullExpression); } else { return obj; } } var OPERATORS = { + /* jshint bitwise : false */ 'null':function(){return null;}, 'true':function(){return true;}, 'false':function(){return false;}, @@ -8377,7 +9138,10 @@ return a; } return isDefined(b)?b:undefined;}, - '-':function(self, locals, a,b){a=a(self, locals); b=b(self, locals); return (isDefined(a)?a:0)-(isDefined(b)?b:0);}, + '-':function(self, locals, a,b){ + a=a(self, locals); b=b(self, locals); + return (isDefined(a)?a:0)-(isDefined(b)?b:0); + }, '*':function(self, locals, a,b){return a(self, locals)*b(self, locals);}, '/':function(self, locals, a,b){return a(self, locals)/b(self, locals);}, '%':function(self, locals, a,b){return a(self, locals)%b(self, locals);}, @@ -8398,6 +9162,7 @@ '|':function(self, locals, a,b){return b(self, locals)(self, locals, a(self, locals));}, '!':function(self, locals, a){return !a(self, locals);} }; +/* jshint bitwise: true */ var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; @@ -8498,8 +9263,9 @@ }, isWhitespace: function(ch) { + // IE treats non-breaking space as \u00A0 return (ch === ' ' || ch === '\r' || ch === '\t' || - ch === '\n' || ch === '\v' || ch === '\u00A0'); // IE treats non-breaking space as \u00A0 + ch === '\n' || ch === '\v' || ch === '\u00A0'); }, isIdent: function(ch) { @@ -9016,7 +9782,10 @@ return extend(function(self, locals) { var o = obj(self, locals), - i = indexFn(self, locals), + // In the getter, we will not block looking up "constructor" by name in order to support user defined + // constructors. However, if value looked up is the Function constructor, we will still block it in the + // ensureSafeObject call right after we look up o[i] (a few lines below.) + i = ensureSafeMemberName(indexFn(self, locals), parser.text, true /* allowConstructor */), v, p; if (!o) return undefined; @@ -9032,7 +9801,7 @@ return v; }, { assign: function(self, value, locals) { - var key = indexFn(self, locals); + var key = ensureSafeMemberName(indexFn(self, locals), parser.text); // prevent overwriting of Function.constructor which would break ensureSafeObject check var safe = ensureSafeObject(obj(self, locals), parser.text); return safe[key] = value; @@ -9060,6 +9829,7 @@ } var fnPtr = fn(scope, locals, context) || noop; + ensureSafeObject(context, parser.text); ensureSafeObject(fnPtr, parser.text); // IE stupidity! (IE doesn't have apply for some native functions) @@ -9265,7 +10035,7 @@ pathVal = pathVal.$$v; } return pathVal; - } + }; } function getterFn(path, options, fullExp) { @@ -9281,20 +10051,22 @@ fn; if (options.csp) { - fn = (pathKeysLength < 6) - ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, options) - : function(scope, locals) { - var i = 0, val; - do { - val = cspSafeGetterFn( - pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], fullExp, options - )(scope, locals); + if (pathKeysLength < 6) { + fn = cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp, + options); + } else { + fn = function(scope, locals) { + var i = 0, val; + do { + val = cspSafeGetterFn(pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], + pathKeys[i++], fullExp, options)(scope, locals); - locals = undefined; // clear after first iteration - scope = val; - } while (i < pathKeysLength); - return val; - } + locals = undefined; // clear after first iteration + scope = val; + } while (i < pathKeysLength); + return val; + }; + } } else { var code = 'var l, fn, p;\n'; forEach(pathKeys, function(key, index) { @@ -9320,7 +10092,9 @@ }); code += 'return s;'; - var evaledFnGetter = Function('s', 'k', 'pw', code); // s=scope, k=locals, pw=promiseWarning + /* jshint -W054 */ + var evaledFnGetter = new Function('s', 'k', 'pw', code); // s=scope, k=locals, pw=promiseWarning + /* jshint +W054 */ evaledFnGetter.toString = function() { return code; }; fn = function(scope, locals) { return evaledFnGetter(scope, locals, promiseWarning); @@ -9384,7 +10158,8 @@ * @function * * @description - * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} service. + * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} + * service. */ function $ParseProvider() { var cache = {}; @@ -9406,35 +10181,40 @@ * * **This feature is deprecated, see deprecation notes below for more info** * - * If set to true (default is false), $parse will unwrap promises automatically when a promise is found at any part of - * the expression. In other words, if set to true, the expression will always result in a non-promise value. + * If set to true (default is false), $parse will unwrap promises automatically when a promise is + * found at any part of the expression. In other words, if set to true, the expression will always + * result in a non-promise value. * - * While the promise is unresolved, it's treated as undefined, but once resolved and fulfilled, the fulfillment value - * is used in place of the promise while evaluating the expression. + * While the promise is unresolved, it's treated as undefined, but once resolved and fulfilled, + * the fulfillment value is used in place of the promise while evaluating the expression. * * **Deprecation notice** * - * This is a feature that didn't prove to be wildly useful or popular, primarily because of the dichotomy between data - * access in templates (accessed as raw values) and controller code (accessed as promises). + * This is a feature that didn't prove to be wildly useful or popular, primarily because of the + * dichotomy between data access in templates (accessed as raw values) and controller code + * (accessed as promises). * - * In most code we ended up resolving promises manually in controllers anyway and thus unifying the model access there. + * In most code we ended up resolving promises manually in controllers anyway and thus unifying + * the model access there. * * Other downsides of automatic promise unwrapping: * * - when building components it's often desirable to receive the raw promises * - adds complexity and slows down expression evaluation - * - makes expression code pre-generation unattractive due to the amount of code that needs to be generated + * - makes expression code pre-generation unattractive due to the amount of code that needs to be + * generated * - makes IDE auto-completion and tool support hard * * **Warning Logs** * - * If the unwrapping is enabled, Angular will log a warning about each expression that unwraps a promise (to reduce - * the noise, each expression is logged only once). To disable this logging use + * If the unwrapping is enabled, Angular will log a warning about each expression that unwraps a + * promise (to reduce the noise, each expression is logged only once). To disable this logging use * `$parseProvider.logPromiseWarnings(false)` api. * * * @param {boolean=} value New value. - * @returns {boolean|self} Returns the current setting when used as getter and self if used as setter. + * @returns {boolean|self} Returns the current setting when used as getter and self if used as + * setter. */ this.unwrapPromises = function(value) { if (isDefined(value)) { @@ -9461,7 +10241,8 @@ * This setting applies only if `$parseProvider.unwrapPromises` setting is set to true as well. * * @param {boolean=} value New value. - * @returns {boolean|self} Returns the current setting when used as getter and self if used as setter. + * @returns {boolean|self} Returns the current setting when used as getter and self if used as + * setter. */ this.logPromiseWarnings = function(value) { if (isDefined(value)) { @@ -9565,8 +10346,8 @@ * </pre> * * At first it might not be obvious why this extra complexity is worth the trouble. The payoff - * comes in the way of - * [guarantees that promise and deferred APIs make](https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.m...). + * comes in the way of guarantees that promise and deferred APIs make, see + * https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.m.... * * Additionally the promise api allows for composition that is very hard to do with the * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach. @@ -9613,8 +10394,9 @@ * provide a progress indication, before the promise is resolved or rejected. * * This method *returns a new promise* which is resolved or rejected via the return value of the - * `successCallback`, `errorCallback`. It also notifies via the return value of the `notifyCallback` - * method. The promise can not be resolved or rejected from the notifyCallback method. + * `successCallback`, `errorCallback`. It also notifies via the return value of the + * `notifyCallback` method. The promise can not be resolved or rejected from the notifyCallback + * method. * * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)` * @@ -9630,8 +10412,8 @@ * * # Chaining promises * - * Because calling the `then` method of a promise returns a new derived promise, it is easily possible - * to create a chain of promises: + * Because calling the `then` method of a promise returns a new derived promise, it is easily + * possible to create a chain of promises: * * <pre> * promiseB = promiseA.then(function(result) { @@ -9655,8 +10437,6 @@ * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation * mechanism in angular, which means faster propagation of resolution or rejection into your * models and avoiding unnecessary browser repaints, which would result in flickering UI. - * - $q promises are recognized by the templating engine in angular, which means that in templates - * you can treat promises attached to a scope as if they were the resulting values. * - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains * all the important functionality needed for common async tasks. * @@ -9994,9 +10774,9 @@ * * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises. * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values, - * each value corresponding to the promise at the same index/key in the `promises` array/hash. If any of - * the promises is resolved with a rejection, this resulting promise will be rejected with the - * same rejection value. + * each value corresponding to the promise at the same index/key in the `promises` array/hash. + * If any of the promises is resolved with a rejection, this resulting promise will be rejected + * with the same rejection value. */ function all(promises) { var deferred = defer(), @@ -10070,11 +10850,19 @@ * @methodOf ng.$rootScopeProvider * @description * - * Sets the number of digest iterations the scope should attempt to execute before giving up and + * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and * assuming that the model is unstable. * * The current default is 10 iterations. * + * In complex applications it's possible that the dependencies between `$watch`s will result in + * several digest iterations. However if an application needs more than the default 10 digest + * iterations for its model to stabilize then you should investigate what is causing the model to + * continuously change during the digest. + * + * Increasing the TTL could have performance implications, so you should not change it without + * proper justification. + * * @param {number} limit The number of digest iterations. */ @@ -10111,7 +10899,7 @@ * @description * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the * {@link AUTO.$injector $injector}. Child scopes are created using the - * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when + * {@link ng.$rootScope.Scope#methods_$new $new()} method. (Most scopes are created automatically when * compiled HTML template is executed.) * * Here is a simple scope snippet to show how you can interact with the scope. @@ -10135,11 +10923,12 @@ * </pre> * * - * @param {Object.<string, function()>=} providers Map of service factory which need to be provided - * for the current scope. Defaults to {@link ng}. + * @param {Object.<string, function()>=} providers Map of service factory which need to be + * provided for the current scope. Defaults to {@link ng}. * @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should - * append/override services provided by `providers`. This is handy when unit-testing and having - * the need to override a default service. + * append/override services provided by `providers`. This is handy + * when unit-testing and having the need to override a default + * service. * @returns {Object} Newly created scope. * */ @@ -10177,12 +10966,12 @@ * Creates a new child {@link ng.$rootScope.Scope scope}. * * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} and - * {@link ng.$rootScope.Scope#$digest $digest()} events. The scope can be removed from the scope - * hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. + * {@link ng.$rootScope.Scope#$digest $digest()} events. The scope can be removed from the + * scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. * - * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is desired for - * the scope and its child scopes to be permanently detached from the parent and thus stop - * participating in model change detection and listener notification by invoking. + * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is + * desired for the scope and its child scopes to be permanently detached from the parent and + * thus stop participating in model change detection and listener notification by invoking. * * @param {boolean} isolate If true, then the scope does not prototypically inherit from the * parent scope. The scope is isolated, as it can not see parent scope properties. @@ -10233,25 +11022,26 @@ * @description * Registers a `listener` callback to be executed whenever the `watchExpression` changes. * - * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest $digest()} and - * should return the value that will be watched. (Since {@link ng.$rootScope.Scope#$digest $digest()} - * reruns when it detects changes the `watchExpression` can execute multiple times per + * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest + * $digest()} and should return the value that will be watched. (Since + * {@link ng.$rootScope.Scope#$digest $digest()} reruns when it detects changes the + * `watchExpression` can execute multiple times per * {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.) * - The `listener` is called only when the value from the current `watchExpression` and the * previous call to `watchExpression` are not equal (with the exception of the initial run, * see below). The inequality is determined according to - * {@link angular.equals} function. To save the value of the object for later comparison, the - * {@link angular.copy} function is used. It also means that watching complex options will - * have adverse memory and performance implications. - * - The watch `listener` may change the model, which may trigger other `listener`s to fire. This - * is achieved by rerunning the watchers until no changes are detected. The rerun iteration - * limit is 10 to prevent an infinite loop deadlock. + * {@link angular.equals} function. To save the value of the object for later comparison, + * the {@link angular.copy} function is used. It also means that watching complex options + * will have adverse memory and performance implications. + * - The watch `listener` may change the model, which may trigger other `listener`s to fire. + * This is achieved by rerunning the watchers until no changes are detected. The rerun + * iteration limit is 10 to prevent an infinite loop deadlock. * * * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called, * you can register a `watchExpression` function with no `listener`. (Since `watchExpression` - * can execute multiple times per {@link ng.$rootScope.Scope#$digest $digest} cycle when a change is - * detected, be prepared for multiple calls to your listener.) + * can execute multiple times per {@link ng.$rootScope.Scope#$digest $digest} cycle when a + * change is detected, be prepared for multiple calls to your listener.) * * After a watcher is registered with the scope, the `listener` fn is called asynchronously * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the @@ -10260,7 +11050,9 @@ * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the * listener was called due to initialization. * + * The example below contains an illustration of using a function as your $watch listener * + * * # Example * <pre> // let's assume that scope was dependency injected as the $rootScope @@ -10269,7 +11061,9 @@ scope.counter = 0; expect(scope.counter).toEqual(0); - scope.$watch('name', function(newValue, oldValue) { scope.counter = scope.counter + 1; }); + scope.$watch('name', function(newValue, oldValue) { + scope.counter = scope.counter + 1; + }); expect(scope.counter).toEqual(0); scope.$digest(); @@ -10279,13 +11073,43 @@ scope.name = 'adam'; scope.$digest(); expect(scope.counter).toEqual(1); + + + + // Using a listener function + var food; + scope.foodCounter = 0; + expect(scope.foodCounter).toEqual(0); + scope.$watch( + // This is the listener function + function() { return food; }, + // This is the change handler + function(newValue, oldValue) { + if ( newValue !== oldValue ) { + // Only increment the counter if the value changed + scope.foodCounter = scope.foodCounter + 1; + } + } + ); + // No digest has been run so the counter will be zero + expect(scope.foodCounter).toEqual(0); + + // Run the digest but since food has not changed cout will still be zero + scope.$digest(); + expect(scope.foodCounter).toEqual(0); + + // Update food and run digest. Now the counter will increment + food = 'cheeseburger'; + scope.$digest(); + expect(scope.foodCounter).toEqual(1); + * </pre> * * * * @param {(function()|string)} watchExpression Expression that is evaluated on each - * {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers a - * call to the `listener`. + * {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers + * a call to the `listener`. * * - `string`: Evaluated as {@link guide/expression expression} * - `function(scope)`: called with current `scope` as a parameter. @@ -10293,7 +11117,8 @@ * the `watchExpression` changes. * * - `string`: Evaluated as {@link guide/expression expression} - * - `function(newValue, oldValue, scope)`: called with current and previous values as parameters. + * - `function(newValue, oldValue, scope)`: called with current and previous values as + * parameters. * * @param {boolean=} objectEquality Compare object for equality rather than for reference. * @returns {function()} Returns a deregistration function for this listener. @@ -10345,13 +11170,13 @@ * * @description * Shallow watches the properties of an object and fires whenever any of the properties change - * (for arrays, this implies watching the array items; for object maps, this implies watching the properties). - * If a change is detected, the `listener` callback is fired. + * (for arrays, this implies watching the array items; for object maps, this implies watching + * the properties). If a change is detected, the `listener` callback is fired. * - * - The `obj` collection is observed via standard $watch operation and is examined on every call to $digest() to - * see if any items have been added, removed, or moved. - * - The `listener` is called whenever anything within the `obj` has changed. Examples include adding, removing, - * and moving items belonging to an object or array. + * - The `obj` collection is observed via standard $watch operation and is examined on every + * call to $digest() to see if any items have been added, removed, or moved. + * - The `listener` is called whenever anything within the `obj` has changed. Examples include + * adding, removing, and moving items belonging to an object or array. * * * # Example @@ -10377,19 +11202,19 @@ * </pre> * * - * @param {string|Function(scope)} obj Evaluated as {@link guide/expression expression}. The expression value - * should evaluate to an object or an array which is observed on each - * {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the collection will trigger - * a call to the `listener`. + * @param {string|Function(scope)} obj Evaluated as {@link guide/expression expression}. The + * expression value should evaluate to an object or an array which is observed on each + * {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the + * collection will trigger a call to the `listener`. * - * @param {function(newCollection, oldCollection, scope)} listener a callback function that is fired with both - * the `newCollection` and `oldCollection` as parameters. - * The `newCollection` object is the newly modified data obtained from the `obj` expression and the - * `oldCollection` object is a copy of the former collection data. + * @param {function(newCollection, oldCollection, scope)} listener a callback function that is + * fired with both the `newCollection` and `oldCollection` as parameters. + * The `newCollection` object is the newly modified data obtained from the `obj` expression + * and the `oldCollection` object is a copy of the former collection data. * The `scope` refers to the current scope. * - * @returns {function()} Returns a de-registration function for this listener. When the de-registration function - * is executed, the internal watch operation is terminated. + * @returns {function()} Returns a de-registration function for this listener. When the + * de-registration function is executed, the internal watch operation is terminated. */ $watchCollection: function(obj, listener) { var self = this; @@ -10484,21 +11309,22 @@ * @function * * @description - * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children. - * Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change the model, the - * `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} until no more listeners are - * firing. This means that it is possible to get into an infinite loop. This function will throw - * `'Maximum iteration limit exceeded.'` if the number of iterations exceeds 10. + * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and + * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change + * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} + * until no more listeners are firing. This means that it is possible to get into an infinite + * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of + * iterations exceeds 10. * * Usually, you don't call `$digest()` directly in * {@link ng.directive:ngController controllers} or in - * {@link ng.$compileProvider#directive directives}. - * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within a - * {@link ng.$compileProvider#directive directives}), which will force a `$digest()`. + * {@link ng.$compileProvider#methods_directive directives}. + * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within + * a {@link ng.$compileProvider#methods_directive directives}), which will force a `$digest()`. * * If you want to be notified whenever `$digest()` is called, - * you can register a `watchExpression` function with {@link ng.$rootScope.Scope#$watch $watch()} - * with no `listener`. + * you can register a `watchExpression` function with + * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`. * * In unit tests, you may need to call `$digest()` to simulate the scope life cycle. * @@ -10596,7 +11422,8 @@ if(dirty && !(ttl--)) { clearPhase(); throw $rootScopeMinErr('infdig', - '{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}', + '{0} $digest() iterations reached. Aborting!\n' + + 'Watchers fired in the last 5 iterations: {1}', TTL, toJson(watchLog)); } } while (dirty || asyncQueue.length); @@ -10675,8 +11502,9 @@ * @function * * @description - * Executes the `expression` on the current scope and returns the result. Any exceptions in the - * expression are propagated (uncaught). This is useful when evaluating Angular expressions. + * Executes the `expression` on the current scope and returns the result. Any exceptions in + * the expression are propagated (uncaught). This is useful when evaluating Angular + * expressions. * * # Example * <pre> @@ -10692,7 +11520,8 @@ * * - `string`: execute using the rules as defined in {@link guide/expression expression}. * - `function(scope)`: execute the function with the current `scope` parameter. - * + * + * @param {(object)=} locals Local variables object, useful for overriding values in scope. * @returns {*} The result of evaluating the expression. */ $eval: function(expr, locals) { @@ -10708,17 +11537,20 @@ * @description * Executes the expression on the current scope at a later point in time. * - * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only that: + * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only + * that: * - * - it will execute after the function that scheduled the evaluation (preferably before DOM rendering). - * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after `expression` execution. + * - it will execute after the function that scheduled the evaluation (preferably before DOM + * rendering). + * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after + * `expression` execution. * * Any exceptions from the execution of the expression are forwarded to the * {@link ng.$exceptionHandler $exceptionHandler} service. * - * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle will be scheduled. - * However, it is encouraged to always call code that changes the model from within an `$apply` call. - * That includes code evaluated via `$evalAsync`. + * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle + * will be scheduled. However, it is encouraged to always call code that changes the model + * from within an `$apply` call. That includes code evaluated via `$evalAsync`. * * @param {(string|function())=} expression An angular expression to be executed. * @@ -10727,8 +11559,8 @@ * */ $evalAsync: function(expr) { - // if we are outside of an $digest loop and this is the first time we are scheduling async task also schedule - // async auto-flush + // if we are outside of an $digest loop and this is the first time we are scheduling async + // task also schedule async auto-flush if (!$rootScope.$$phase && !$rootScope.$$asyncQueue.length) { $browser.defer(function() { if ($rootScope.$$asyncQueue.length) { @@ -10751,10 +11583,10 @@ * @function * * @description - * `$apply()` is used to execute an expression in angular from outside of the angular framework. - * (For example from browser DOM events, setTimeout, XHR or third party libraries). - * Because we are calling into the angular framework we need to perform proper scope life cycle - * of {@link ng.$exceptionHandler exception handling}, + * `$apply()` is used to execute an expression in angular from outside of the angular + * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). + * Because we are calling into the angular framework we need to perform proper scope life + * cycle of {@link ng.$exceptionHandler exception handling}, * {@link ng.$rootScope.Scope#$digest executing watches}. * * ## Life cycle @@ -10779,8 +11611,8 @@ * {@link ng.$rootScope.Scope#$eval $eval()} method. * 2. Any exceptions from the execution of the expression are forwarded to the * {@link ng.$exceptionHandler $exceptionHandler} service. - * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the expression - * was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method. + * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the + * expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method. * * * @param {(string|function())=} exp An angular expression to be executed. @@ -10814,18 +11646,20 @@ * @function * * @description - * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for discussion of - * event life cycle. + * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for + * discussion of event life cycle. * * The event listener function format is: `function(event, args...)`. The `event` object * passed into the listener has the following attributes: * - * - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or `$broadcast`-ed. + * - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or + * `$broadcast`-ed. * - `currentScope` - `{Scope}`: the current scope which is handling the event. * - `name` - `{string}`: name of the event. - * - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel further event - * propagation (available only for events that were `$emit`-ed). - * - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag to true. + * - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel + * further event propagation (available only for events that were `$emit`-ed). + * - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag + * to true. * - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called. * * @param {string} name Event name to listen on. @@ -10856,9 +11690,10 @@ * registered {@link ng.$rootScope.Scope#$on} listeners. * * The event life cycle starts at the scope on which `$emit` was called. All - * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get notified. - * Afterwards, the event traverses upwards toward the root scope and calls all registered - * listeners along the way. The event will stop propagating if one of the listeners cancels it. + * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get + * notified. Afterwards, the event traverses upwards toward the root scope and calls all + * registered listeners along the way. The event will stop propagating if one of the listeners + * cancels it. * * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed * onto the {@link ng.$exceptionHandler $exceptionHandler} service. @@ -10924,9 +11759,9 @@ * registered {@link ng.$rootScope.Scope#$on} listeners. * * The event life cycle starts at the scope on which `$broadcast` was called. All - * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get notified. - * Afterwards, the event propagates to all direct and indirect scopes of the current scope and - * calls all registered listeners along the way. The event cannot be canceled. + * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get + * notified. Afterwards, the event propagates to all direct and indirect scopes of the current + * scope and calls all registered listeners along the way. The event cannot be canceled. * * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed * onto the {@link ng.$exceptionHandler $exceptionHandler} service. @@ -11036,7 +11871,7 @@ function escapeForRegexp(s) { return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1'). replace(/\x08/g, '\\x08'); -}; +} function adjustMatcher(matcher) { @@ -11100,9 +11935,9 @@ * can override it completely to change the behavior of `$sce`, the common case would * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as - * templates. Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist + * templates. Refer {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist * $sceDelegateProvider.resourceUrlWhitelist} and {@link - * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} + * ng.$sceDelegateProvider#methods_resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} */ /** @@ -11113,8 +11948,8 @@ * The `$sceDelegateProvider` provider allows developers to configure the {@link ng.$sceDelegate * $sceDelegate} service. This allows one to get/set the whitelists and blacklists used to ensure * that the URLs used for sourcing Angular templates are safe. Refer {@link - * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and - * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} + * ng.$sceDelegateProvider#methods_resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and + * {@link ng.$sceDelegateProvider#methods_resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist} * * For the general details about this service in Angular, read the main page for {@link ng.$sce * Strict Contextual Escaping (SCE)}. @@ -11160,8 +11995,8 @@ * provided. This must be an array or null. A snapshot of this array is used so further * changes to the array are ignored. * - * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items allowed in - * this array. + * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items + * allowed in this array. * * Note: **an empty whitelist array will block all URLs**! * @@ -11190,19 +12025,19 @@ * provided. This must be an array or null. A snapshot of this array is used so further * changes to the array are ignored. * - * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items allowed in - * this array. + * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items + * allowed in this array. * - * The typical usage for the blacklist is to **block [open redirects](http://cwe.mitre.org/data/definitions/601.html)** - * served by your domain as these would otherwise be trusted but actually return content from the redirected - * domain. + * The typical usage for the blacklist is to **block + * [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as + * these would otherwise be trusted but actually return content from the redirected domain. * * Finally, **the blacklist overrides the whitelist** and has the final say. * * @return {Array} the currently set blacklist array. * - * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there is - * no blacklist.) + * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there + * is no blacklist.) * * @description * Sets/Gets the blacklist of trusted resource URLs. @@ -11258,21 +12093,21 @@ return allowed; } - function generateHolderType(base) { + function generateHolderType(Base) { var holderType = function TrustedValueHolderType(trustedValue) { this.$$unwrapTrustedValue = function() { return trustedValue; }; }; - if (base) { - holderType.prototype = new base(); + if (Base) { + holderType.prototype = new Base(); } holderType.prototype.valueOf = function sceValueOf() { return this.$$unwrapTrustedValue(); - } + }; holderType.prototype.toString = function sceToString() { return this.$$unwrapTrustedValue().toString(); - } + }; return holderType; } @@ -11304,9 +12139,10 @@ * where Angular expects a $sce.trustAs() return value. */ function trustAs(type, trustedValue) { - var constructor = (byType.hasOwnProperty(type) ? byType[type] : null); - if (!constructor) { - throw $sceMinErr('icontext', 'Attempted to trust a value in invalid context. Context: {0}; Value: {1}', + var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null); + if (!Constructor) { + throw $sceMinErr('icontext', + 'Attempted to trust a value in invalid context. Context: {0}; Value: {1}', type, trustedValue); } if (trustedValue === null || trustedValue === undefined || trustedValue === '') { @@ -11319,7 +12155,7 @@ 'Attempted to trust a non-string value in a content requiring a string: Context: {0}', type); } - return new constructor(trustedValue); + return new Constructor(trustedValue); } /** @@ -11328,18 +12164,18 @@ * @methodOf ng.$sceDelegate * * @description - * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs + * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#methods_trustAs * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link - * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. + * ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}. * * If the passed parameter is not a value that had been returned by {@link - * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is. + * ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}, returns it as-is. * - * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} + * @param {*} value The result of a prior {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`} * call or anything else. - * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs - * `$sceDelegate.trustAs`} if `value` is the result of such a call. Otherwise, returns `value` - * unchanged. + * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#methods_trustAs + * `$sceDelegate.trustAs`} if `value` is the result of such a call. Otherwise, returns + * `value` unchanged. */ function valueOf(maybeTrusted) { if (maybeTrusted instanceof trustedValueHolderBase) { @@ -11355,14 +12191,14 @@ * @methodOf ng.$sceDelegate * * @description - * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and returns the - * originally supplied value if the queried context type is a supertype of the created type. If - * this condition isn't satisfied, throws an exception. + * Takes the result of a {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`} call and + * returns the originally supplied value if the queried context type is a supertype of the + * created type. If this condition isn't satisfied, throws an exception. * * @param {string} type The kind of context in which this value is to be used. - * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs - * `$sceDelegate.trustAs`} call. - * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs + * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#methods_trustAs + * `$sceDelegate.trustAs`} call. + * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#methods_trustAs * `$sceDelegate.trustAs`} if valid in this context. Otherwise, throws an exception. */ function getTrusted(type, maybeTrusted) { @@ -11381,7 +12217,8 @@ return maybeTrusted; } else { throw $sceMinErr('insecurl', - 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}', maybeTrusted.toString()); + 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}', + maybeTrusted.toString()); } } else if (type === SCE_CONTEXTS.HTML) { return htmlSanitizer(maybeTrusted); @@ -11408,6 +12245,8 @@ * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}. */ +/* jshint maxlen: false*/ + /** * @ngdoc service * @name ng.$sce @@ -11464,20 +12303,20 @@ * allowing only the files in a specific directory to do this. Ensuring that the internal API * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task. * - * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs} (and shorthand - * methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to obtain values that will be - * accepted by SCE / privileged contexts. + * In the case of AngularJS' SCE service, one uses {@link ng.$sce#methods_trustAs $sce.trustAs} + * (and shorthand methods such as {@link ng.$sce#methods_trustAsHtml $sce.trustAsHtml}, etc.) to + * obtain values that will be accepted by SCE / privileged contexts. * * * ## How does it work? * - * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted + * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#methods_getTrusted * $sce.getTrusted(context, value)} rather than to the value directly. Directives use {@link - * ng.$sce#parse $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the - * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals. + * ng.$sce#methods_parse $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the + * {@link ng.$sce#methods_getTrusted $sce.getTrusted} behind the scenes on non-constant literals. * * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link - * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly + * ng.$sce#methods_parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly * simplified): * * <pre class="prettyprint"> @@ -11496,10 +12335,10 @@ * `templateUrl`'s specified by {@link guide/directive directives}. * * By default, Angular only loads templates from the same domain and protocol as the application - * document. This is done by calling {@link ng.$sce#getTrustedResourceUrl + * document. This is done by calling {@link ng.$sce#methods_getTrustedResourceUrl * $sce.getTrustedResourceUrl} on the template URL. To load templates from other domains and/or - * protocols, you may either either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist - * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value. + * protocols, you may either either {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelist + * them} or {@link ng.$sce#methods_trustAsResourceUrl wrap it} into a trusted value. * * *Please note*: * The browser's @@ -11519,20 +12358,21 @@ * `<div ng-html-bind-unsafe="'<b>implicitly trusted</b>'"></div>`) just works. * * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them - * through {@link ng.$sce#getTrusted $sce.getTrusted}. SCE doesn't play a role here. + * through {@link ng.$sce#methods_getTrusted $sce.getTrusted}. SCE doesn't play a role here. * * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load * templates in `ng-include` from your application's domain without having to even know about SCE. * It blocks loading templates from other domains or loading templates over http from an https * served document. You can change these by setting your own custom {@link - * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link - * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs. + * ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelists} and {@link + * ng.$sceDelegateProvider#methods_resourceUrlBlacklist blacklists} for matching such URLs. * * This significantly reduces the overhead. It is far easier to pay the small overhead and have an * application that's secure and can be audited to verify that with much more ease than bolting * security onto an application later. * - * ## What trusted context types are supported?<a name="contexts"></a> + * <a name="contexts"></a> + * ## What trusted context types are supported? * * | Context | Notes | * |---------------------|----------------| @@ -11542,7 +12382,7 @@ * | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contens are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. | * | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. | * - * ## Format of items in {@link ng.$sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a> + * ## Format of items in {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#methods_resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a> * * Each element in these arrays must be one of the following: * @@ -11587,65 +12427,68 @@ * Closure library's [goog.string.regExpEscape(s)]( * http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js...). * - * Refer {@link ng.$sceDelegateProvider#example $sceDelegateProvider} for an example. + * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example. * * ## Show me an example using SCE. * * @example - <example module="mySceApp"> - <file name="index.html"> - <div ng-controller="myAppController as myCtrl"> - <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br> - <b>User comments</b><br> - By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when $sanitize is available. If $sanitize isn't available, this results in an error instead of an exploit. - <div class="well"> - <div ng-repeat="userComment in myCtrl.userComments"> - <b>{{userComment.name}}</b>: - <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span> - <br> - </div> +<example module="mySceApp"> +<file name="index.html"> + <div ng-controller="myAppController as myCtrl"> + <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br> + <b>User comments</b><br> + By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when + $sanitize is available. If $sanitize isn't available, this results in an error instead of an + exploit. + <div class="well"> + <div ng-repeat="userComment in myCtrl.userComments"> + <b>{{userComment.name}}</b>: + <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span> + <br> </div> </div> - </file> + </div> +</file> - <file name="script.js"> - var mySceApp = angular.module('mySceApp', ['ngSanitize']); +<file name="script.js"> + var mySceApp = angular.module('mySceApp', ['ngSanitize']); - mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { - var self = this; - $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { - self.userComments = userComments; - }); - self.explicitlyTrustedHtml = $sce.trustAsHtml( - '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' + - 'sanitization."">Hover over this text.</span>'); + mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) { + var self = this; + $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { + self.userComments = userComments; }); - </file> + self.explicitlyTrustedHtml = $sce.trustAsHtml( + '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' + + 'sanitization."">Hover over this text.</span>'); + }); +</file> - <file name="test_data.json"> - [ - { "name": "Alice", - "htmlComment": "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>" - }, - { "name": "Bob", - "htmlComment": "<i>Yes!</i> Am I the only other one?" - } - ] - </file> +<file name="test_data.json"> +[ + { "name": "Alice", + "htmlComment": + "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>" + }, + { "name": "Bob", + "htmlComment": "<i>Yes!</i> Am I the only other one?" + } +] +</file> - <file name="scenario.js"> - describe('SCE doc demo', function() { - it('should sanitize untrusted values', function() { - expect(element('.htmlComment').html()).toBe('<span>Is <i>anyone</i> reading this?</span>'); - }); - it('should NOT sanitize explicitly trusted values', function() { - expect(element('#explicitlyTrustedHtml').html()).toBe( - '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' + - 'sanitization."">Hover over this text.</span>'); - }); +<file name="scenario.js"> + describe('SCE doc demo', function() { + it('should sanitize untrusted values', function() { + expect(element('.htmlComment').html()).toBe('<span>Is <i>anyone</i> reading this?</span>'); }); - </file> - </example> + it('should NOT sanitize explicitly trusted values', function() { + expect(element('#explicitlyTrustedHtml').html()).toBe( + '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' + + 'sanitization."">Hover over this text.</span>'); + }); + }); +</file> +</example> * * * @@ -11668,6 +12511,7 @@ * </pre> * */ +/* jshint maxlen: 100 */ function $SceProvider() { var enabled = true; @@ -11713,13 +12557,13 @@ * This function should return the a value that is safe to use in the context specified by * contextEnum or throw and exception otherwise. * - * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be opaque - * or wrapped in some holder object. That happens to be an implementation detail. For instance, - * an implementation could maintain a registry of all trusted objects by context. In such a case, - * trustAs() would return the same object that was passed in. getTrusted() would return the same - * object passed in if it was found in the registry under a compatible context or throw an - * exception otherwise. An implementation might only wrap values some of the time based on - * some criteria. getTrusted() might return a value and not throw an exception for special + * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be + * opaque or wrapped in some holder object. That happens to be an implementation detail. For + * instance, an implementation could maintain a registry of all trusted objects by context. In + * such a case, trustAs() would return the same object that was passed in. getTrusted() would + * return the same object passed in if it was found in the registry under a compatible context or + * throw an exception otherwise. An implementation might only wrap values some of the time based + * on some criteria. getTrusted() might return a value and not throw an exception for special * constants or objects even if not wrapped. All such implementations fulfill this contract. * * @@ -11774,8 +12618,8 @@ sce.valueOf = $sceDelegate.valueOf; if (!enabled) { - sce.trustAs = sce.getTrusted = function(type, value) { return value; }, - sce.valueOf = identity + sce.trustAs = sce.getTrusted = function(type, value) { return value; }; + sce.valueOf = identity; } /** @@ -11786,7 +12630,7 @@ * @description * Converts Angular {@link guide/expression expression} into a function. This is like {@link * ng.$parse $parse} and is identical when the expression is a literal constant. Otherwise, it - * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*, + * wraps the expression in a call to {@link ng.$sce#methods_getTrusted $sce.getTrusted(*type*, * *result*)} * * @param {string} type The kind of SCE context in which this result will be used. @@ -11805,7 +12649,7 @@ } else { return function sceParseAsTrusted(self, locals) { return sce.getTrusted(type, parsed(self, locals)); - } + }; } }; @@ -11815,11 +12659,12 @@ * @methodOf ng.$sce * * @description - * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. As such, returns an object - * that is trusted by angular for use in specified strict contextual escaping contexts (such as - * ng-html-bind-unsafe, ng-include, any src attribute interpolation, any dom event binding - * attribute interpolation such as for onclick, etc.) that uses the provided value. See * - * {@link ng.$sce $sce} for enabling strict contextual escaping. + * Delegates to {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs`}. As such, + * returns an objectthat is trusted by angular for use in specified strict contextual + * escaping contexts (such as ng-html-bind-unsafe, ng-include, any src attribute + * interpolation, any dom event binding attribute interpolation such as for onclick, etc.) + * that uses the provided value. See * {@link ng.$sce $sce} for enabling strict contextual + * escaping. * * @param {string} type The kind of context in which this value is safe for use. e.g. url, * resource_url, html, js and css. @@ -11834,13 +12679,14 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.trustAsHtml(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`} + * Shorthand method. `$sce.trustAsHtml(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.HTML, value)`} * * @param {*} value The value to trustAs. - * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedHtml * $sce.getTrustedHtml(value)} to obtain the original value. (privileged directives * only accept expressions that are either literal constants or are the - * return value of {@link ng.$sce#trustAs $sce.trustAs}.) + * return value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) */ /** @@ -11849,13 +12695,14 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.trustAsUrl(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`} + * Shorthand method. `$sce.trustAsUrl(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.URL, value)`} * * @param {*} value The value to trustAs. - * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedUrl * $sce.getTrustedUrl(value)} to obtain the original value. (privileged directives * only accept expressions that are either literal constants or are the - * return value of {@link ng.$sce#trustAs $sce.trustAs}.) + * return value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) */ /** @@ -11864,13 +12711,14 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.trustAsResourceUrl(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`} + * Shorthand method. `$sce.trustAsResourceUrl(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`} * * @param {*} value The value to trustAs. - * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedResourceUrl * $sce.getTrustedResourceUrl(value)} to obtain the original value. (privileged directives * only accept expressions that are either literal constants or are the return - * value of {@link ng.$sce#trustAs $sce.trustAs}.) + * value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) */ /** @@ -11879,13 +12727,14 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.trustAsJs(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`} + * Shorthand method. `$sce.trustAsJs(value)` → + * {@link ng.$sceDelegate#methods_trustAs `$sceDelegate.trustAs($sce.JS, value)`} * * @param {*} value The value to trustAs. - * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs + * @returns {*} An object that can be passed to {@link ng.$sce#methods_getTrustedJs * $sce.getTrustedJs(value)} to obtain the original value. (privileged directives * only accept expressions that are either literal constants or are the - * return value of {@link ng.$sce#trustAs $sce.trustAs}.) + * return value of {@link ng.$sce#methods_trustAs $sce.trustAs}.) */ /** @@ -11894,15 +12743,17 @@ * @methodOf ng.$sce * * @description - * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}. As such, takes - * the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the originally supplied - * value if the queried context type is a supertype of the created type. If this condition - * isn't satisfied, throws an exception. + * Delegates to {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted`}. As such, + * takes the result of a {@link ng.$sce#methods_trustAs `$sce.trustAs`}() call and returns the + * originally supplied value if the queried context type is a supertype of the created type. + * If this condition isn't satisfied, throws an exception. * * @param {string} type The kind of context in which this value is to be used. - * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`} call. - * @returns {*} The value the was originally provided to {@link ng.$sce#trustAs `$sce.trustAs`} if - * valid in this context. Otherwise, throws an exception. + * @param {*} maybeTrusted The result of a prior {@link ng.$sce#methods_trustAs `$sce.trustAs`} + * call. + * @returns {*} The value the was originally provided to + * {@link ng.$sce#methods_trustAs `$sce.trustAs`} if valid in this context. + * Otherwise, throws an exception. */ /** @@ -11911,7 +12762,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.getTrustedHtml(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`} + * Shorthand method. `$sce.getTrustedHtml(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`} * * @param {*} value The value to pass to `$sce.getTrusted`. * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)` @@ -11923,7 +12775,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.getTrustedCss(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`} + * Shorthand method. `$sce.getTrustedCss(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`} * * @param {*} value The value to pass to `$sce.getTrusted`. * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)` @@ -11935,7 +12788,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.getTrustedUrl(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`} + * Shorthand method. `$sce.getTrustedUrl(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.URL, value)`} * * @param {*} value The value to pass to `$sce.getTrusted`. * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)` @@ -11947,7 +12801,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.getTrustedResourceUrl(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`} + * Shorthand method. `$sce.getTrustedResourceUrl(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`} * * @param {*} value The value to pass to `$sceDelegate.getTrusted`. * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)` @@ -11959,7 +12814,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.getTrustedJs(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`} + * Shorthand method. `$sce.getTrustedJs(value)` → + * {@link ng.$sceDelegate#methods_getTrusted `$sceDelegate.getTrusted($sce.JS, value)`} * * @param {*} value The value to pass to `$sce.getTrusted`. * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)` @@ -11971,7 +12827,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.parseAsHtml(expression string)` → {@link ng.$sce#parse `$sce.parseAs($sce.HTML, value)`} + * Shorthand method. `$sce.parseAsHtml(expression string)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.HTML, value)`} * * @param {string} expression String expression to compile. * @returns {function(context, locals)} a function which represents the compiled expression: @@ -11988,7 +12845,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.parseAsCss(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.CSS, value)`} + * Shorthand method. `$sce.parseAsCss(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.CSS, value)`} * * @param {string} expression String expression to compile. * @returns {function(context, locals)} a function which represents the compiled expression: @@ -12005,7 +12863,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.parseAsUrl(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.URL, value)`} + * Shorthand method. `$sce.parseAsUrl(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.URL, value)`} * * @param {string} expression String expression to compile. * @returns {function(context, locals)} a function which represents the compiled expression: @@ -12022,7 +12881,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.parseAsResourceUrl(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.RESOURCE_URL, value)`} + * Shorthand method. `$sce.parseAsResourceUrl(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.RESOURCE_URL, value)`} * * @param {string} expression String expression to compile. * @returns {function(context, locals)} a function which represents the compiled expression: @@ -12039,7 +12899,8 @@ * @methodOf ng.$sce * * @description - * Shorthand method. `$sce.parseAsJs(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.JS, value)`} + * Shorthand method. `$sce.parseAsJs(value)` → + * {@link ng.$sce#methods_parse `$sce.parseAs($sce.JS, value)`} * * @param {string} expression String expression to compile. * @returns {function(context, locals)} a function which represents the compiled expression: @@ -12059,13 +12920,13 @@ var lName = lowercase(name); sce[camelCase("parse_as_" + lName)] = function (expr) { return parse(enumValue, expr); - } + }; sce[camelCase("get_trusted_" + lName)] = function (value) { return getTrusted(enumValue, value); - } + }; sce[camelCase("trust_as_" + lName)] = function (value) { return trustAs(enumValue, value); - } + }; }); return sce; @@ -12090,7 +12951,8 @@ function $SnifferProvider() { this.$get = ['$window', '$document', function($window, $document) { var eventSupport = {}, - android = int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), + android = + int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), boxee = /Boxee/i.test(($window.navigator || {}).userAgent), document = $document[0] || {}, vendorPrefix, @@ -12131,7 +12993,10 @@ // older webit browser (533.9) on Boxee box has exactly the same problem as Android has // so let's not use the history API also + // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined + // jshint -W018 history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee), + // jshint +W018 hashchange: 'onhashchange' in $window && // IE8 compatible mode lies (!document.documentMode || document.documentMode > 7), @@ -12148,10 +13013,11 @@ return eventSupport[event]; }, - csp: document.securityPolicy ? document.securityPolicy.isActive : false, + csp: csp(), vendorPrefix: vendorPrefix, transitions : transitions, - animations : animations + animations : animations, + msie : msie }; }]; } @@ -12183,7 +13049,7 @@ * @param {function()} fn A function, whose execution should be delayed. * @param {number=} [delay=0] Delay in milliseconds. * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise - * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. + * will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block. * @returns {Promise} Promise that will be resolved when the timeout is reached. The value this * promise will be resolved with is the return value of the `fn` function. * @@ -12410,7 +13276,8 @@ hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', hostname: urlParsingNode.hostname, port: urlParsingNode.port, - pathname: urlParsingNode.pathname && urlParsingNode.pathname.charAt(0) === '/' ? urlParsingNode.pathname : '/' + urlParsingNode.pathname + pathname: urlParsingNode.pathname && urlParsingNode.pathname.charAt(0) === '/' ? + urlParsingNode.pathname : '/' + urlParsingNode.pathname }; } @@ -12475,9 +13342,9 @@ * @name ng.$filterProvider * @description * - * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To - * achieve this a filter definition consists of a factory function which is annotated with dependencies and is - * responsible for creating a filter function. + * Filters are just functions which transform input to an output. However filters need to be + * Dependency Injected. To achieve this a filter definition consists of a factory function which is + * annotated with dependencies and is responsible for creating a filter function. * * <pre> * // Filter registration @@ -12500,7 +13367,9 @@ * } * </pre> * - * The filter function is registered with the `$injector` under the filter name suffix with `Filter`. + * The filter function is registered with the `$injector` under the filter name suffix with + * `Filter`. + * * <pre> * it('should be the same instance', inject( * function($filterProvider) { @@ -12515,8 +13384,7 @@ * * * For more information about how angular filters work, and how to create your own filters, see - * {@link guide/dev_guide.templates.filters Understanding Angular Filters} in the angular Developer - * Guide. + * {@link guide/filter Filters} in the Angular Developer Guide. */ /** * @ngdoc method @@ -12577,6 +13445,18 @@ }]; //////////////////////////////////////// + + /* global + currencyFilter: false, + dateFilter: false, + filterFilter: false, + jsonFilter: false, + limitToFilter: false, + lowercaseFilter: false, + numberFilter: false, + orderByFilter: false, + uppercaseFilter: false, + */ register('currency', currencyFilter); register('date', dateFilter); @@ -12597,9 +13477,6 @@ * @description * Selects a subset of items from `array` and returns it as a new array. * - * Note: This function is used to augment the `Array` type in Angular expressions. See - * {@link ng.$filter} for more information about Angular arrays. - * * @param {Array} array The source array. * @param {string|Object|function()} expression The predicate to be used for selecting items from * `array`. @@ -12694,9 +13571,12 @@ </doc:example> */ function filterFilter() { - return function(array, expression, comperator) { + return function(array, expression, comparator) { if (!isArray(array)) return array; - var predicates = []; + + var comparatorType = typeof(comparator), + predicates = []; + predicates.check = function(value) { for (var j = 0; j < predicates.length; j++) { if(!predicates[j](value)) { @@ -12705,22 +13585,20 @@ } return true; }; - switch(typeof comperator) { - case "function": - break; - case "boolean": - if(comperator == true) { - comperator = function(obj, text) { - return angular.equals(obj, text); - } - break; - } - default: - comperator = function(obj, text) { + + if (comparatorType !== 'function') { + if (comparatorType === 'boolean' && comparator) { + comparator = function(obj, text) { + return angular.equals(obj, text); + }; + } else { + comparator = function(obj, text) { text = (''+text).toLowerCase(); return (''+obj).toLowerCase().indexOf(text) > -1; }; + } } + var search = function(obj, text){ if (typeof text == 'string' && text.charAt(0) === '!') { return !search(obj, text.substr(1)); @@ -12729,12 +13607,11 @@ case "boolean": case "number": case "string": - return comperator(obj, text); + return comparator(obj, text); case "object": switch (typeof text) { case "object": - return comperator(obj, text); - break; + return comparator(obj, text); default: for ( var objKey in obj) { if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) { @@ -12759,13 +13636,16 @@ case "boolean": case "number": case "string": + // Set up expression object and fall through expression = {$:expression}; + // jshint -W086 case "object": + // jshint +W086 for (var key in expression) { if (key == '$') { (function() { if (!expression[key]) return; - var path = key + var path = key; predicates.push(function(value) { return search(value, expression[path]); }); @@ -12795,7 +13675,7 @@ } } return filtered; - } + }; } /** @@ -12942,13 +13822,13 @@ var whole = fraction[0]; fraction = fraction[1] || ''; - var pos = 0, + var i, pos = 0, lgroup = pattern.lgSize, group = pattern.gSize; if (whole.length >= (lgroup + group)) { pos = whole.length - lgroup; - for (var i = 0; i < pos; i++) { + for (i = 0; i < pos; i++) { if ((pos - i)%group === 0 && i !== 0) { formatedText += groupSep; } @@ -13162,7 +14042,7 @@ } dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3])); var h = int(match[4]||0) - tzHour; - var m = int(match[5]||0) - tzMin + var m = int(match[5]||0) - tzMin; var s = int(match[6]||0); var ms = Math.round(parseFloat('0.' + (match[7]||0)) * 1000); timeSetter.call(date, h, m, s, ms); @@ -13283,9 +14163,6 @@ * are taken from either the beginning or the end of the source array or string, as specified by * the value and sign (positive or negative) of `limit`. * - * Note: This function is used to augment the `Array` type in Angular expressions. See - * {@link ng.$filter} for more information about Angular arrays. - * * @param {Array|string} input Source array or string to be limited. * @param {string|number} limit The length of the returned array or string. If the `limit` number * is positive, `limit` number of items from the beginning of the source array/string are copied. @@ -13373,7 +14250,7 @@ } return out; - } + }; } /** @@ -13384,9 +14261,6 @@ * @description * Orders a specified `array` by the `expression` predicate. * - * Note: this function is used to augment the `Array` type in Angular expressions. See - * {@link ng.$filter} for more information about Angular arrays. - * * @param {Array} array The array to sort. * @param {function(*)|string|Array.<(function(*)|string)>} expression A predicate to be * used by the comparator to determine the order of elements. @@ -13511,14 +14385,14 @@ return t1 < t2 ? -1 : 1; } } - } + }; } function ngDirective(directive) { if (isFunction(directive)) { directive = { link: directive - } + }; } directive.restrict = directive.restrict || 'AC'; return valueFn(directive); @@ -13563,7 +14437,7 @@ event.preventDefault(); } }); - } + }; } }); @@ -13916,6 +14790,7 @@ }; }); +/* global -nullFormCtrl */ var nullFormCtrl = { $addControl: noop, $removeControl: noop, @@ -14121,7 +14996,7 @@ * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a * sub-group of controls needs to be determined. * - * @param {string=} name|ngForm Name of the form. If specified, the form controller will be published into + * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into * related scope, under this name. * */ @@ -14180,7 +15055,7 @@ * * - If a form has only one input field then hitting enter in this field triggers form submit * (`ngSubmit`) - * - if a form has has 2+ input fields and no buttons or input[type=submit] then hitting enter + * - if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter * doesn't trigger submit * - if a form has one or more input fields and one or more buttons or input[type=submit] then * hitting enter in any of the input fields will trigger the click handler on the *first* button or @@ -14281,6 +15156,14 @@ var formDirective = formDirectiveFactory(); var ngFormDirective = formDirectiveFactory(true); +/* global + + -VALID_CLASS, + -INVALID_CLASS, + -PRISTINE_CLASS, + -DIRTY_CLASS +*/ + var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/; var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; @@ -14309,8 +15192,7 @@ * patterns defined as scope expressions. * @param {string=} ngChange Angular expression to be executed when input changes due to user * interaction with the input element. - * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trimming the - * input. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. * * @example <doc:example> @@ -14817,8 +15699,8 @@ }); if (attr.min) { - var min = parseFloat(attr.min); var minValidator = function(value) { + var min = parseFloat(attr.min); if (!ctrl.$isEmpty(value) && value < min) { ctrl.$setValidity('min', false); return undefined; @@ -14833,8 +15715,8 @@ } if (attr.max) { - var max = parseFloat(attr.max); var maxValidator = function(value) { + var max = parseFloat(attr.max); if (!ctrl.$isEmpty(value) && value > max) { ctrl.$setValidity('max', false); return undefined; @@ -15099,7 +15981,7 @@ the control reads value from the DOM. Each function is called, in turn, passing the value through to the next. Used to sanitize / convert the value as well as validation. For validation, the parsers should update the validity state using - {@link ng.directive:ngModel.NgModelController#$setValidity $setValidity()}, + {@link ng.directive:ngModel.NgModelController#methods_$setValidity $setValidity()}, and return `undefined` for invalid values. * @@ -15212,30 +16094,31 @@ * Note that if you have a directive with an isolated scope, you cannot require `ngModel` * since the model value will be looked up on the isolated scope rather than the outer scope. * When the directive updates the model value, calling `ngModel.$setViewValue()` the property - * on the outer scope will not be updated. + * on the outer scope will not be updated. However you can get around this by using $parent. * - * Here is an example of this situation. You'll notice that even though both 'input' and 'div' - * seem to be attached to the same model, they are not kept in synch. + * Here is an example of this situation. You'll notice that the first div is not updating the input. + * However the second div can update the input properly. * * <example module="badIsolatedDirective"> <file name="script.js"> - angular.module('badIsolatedDirective', []).directive('bad', function() { - return { - require: 'ngModel', - scope: { }, - template: '<input ng-model="innerModel">', - link: function(scope, element, attrs, ngModel) { - scope.$watch('innerModel', function(value) { - console.log(value); - ngModel.$setViewValue(value); - }); - } - }; + angular.module('badIsolatedDirective', []).directive('isolate', function() { + return { + require: 'ngModel', + scope: { }, + template: '<input ng-model="innerModel">', + link: function(scope, element, attrs, ngModel) { + scope.$watch('innerModel', function(value) { + console.log(value); + ngModel.$setViewValue(value); + }); + } + }; }); </file> <file name="index.html"> - <input ng-model="someModel"> - <div bad ng-model="someModel"></div> + <input ng-model="someModel"/> + <div isolate ng-model="someModel"></div> + <div isolate ng-model="$parent.someModel"></div> </file> * </example> * @@ -15280,10 +16163,10 @@ * * @description * This is called when we need to determine if the value of the input is empty. - * + * * For instance, the required directive does this to work out if the input has data or not. * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`. - * + * * You can override this for input directives whose concept of being empty is different to the * default. The `checkboxInputType` directive does this because in its case a value of `false` * implies empty. @@ -15328,7 +16211,10 @@ * @param {boolean} isValid Whether the current state is valid (true) or invalid (false). */ this.$setValidity = function(validationErrorKey, isValid) { + // Purposeful use of ! here to cast isValid to boolean in case it is undefined + // jshint -W018 if ($error[validationErrorKey] === !isValid) return; + // jshint +W018 if (isValid) { if ($error[validationErrorKey]) invalidCount--; @@ -15408,7 +16294,7 @@ } catch(e) { $exceptionHandler(e); } - }) + }); } }; @@ -15491,7 +16377,7 @@ formCtrl.$addControl(modelCtrl); - element.on('$destroy', function() { + scope.$on('$destroy', function() { formCtrl.$removeControl(modelCtrl); }); } @@ -15757,8 +16643,8 @@ * Typically, you don't use `ngBind` directly, but instead you use the double curly markup like * `{{ expression }}` which is similar but less verbose. * - * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily - * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an + * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily + * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an * element attribute, it makes the bindings invisible to the user while the page is loading. * * An alternative solution to this problem would be using the @@ -15794,6 +16680,9 @@ var ngBindDirective = ngDirective(function(scope, element, attr) { element.addClass('ng-binding').data('$binding', attr.ngBind); scope.$watch(attr.ngBind, function ngBindWatchAction(value) { + // We are purposefully using == here rather than === because we want to + // catch when value is "null or undefined" + // jshint -W041 element.text(value == undefined ? '' : value); }); }); @@ -15855,7 +16744,7 @@ attr.$observe('ngBindTemplate', function(value) { element.text(value); }); - } + }; }]; @@ -15869,7 +16758,7 @@ * ngSanitize.$sanitize $sanitize} service. To utilize this functionality, ensure that `$sanitize` * is available, for example, by including {@link ngSanitize} in your module's dependencies (not in * core Angular.) You may also bypass sanitization for values you know are safe. To do so, bind to - * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}. See the example + * an explicitly trusted value via {@link ng.$sce#methods_trustAsHtml $sce.trustAsHtml}. See the example * under {@link ng.$sce#Example Strict Contextual Escaping (SCE)}. * * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you @@ -15877,6 +16766,29 @@ * * @element ANY * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate. + * + * @example + * Try it here: enter text in text box and watch the greeting change. + <doc:example module="ngBindHtmlExample" deps="angular-sanitize.js" > + <doc:source> + <script> + angular.module('ngBindHtmlExample', ['ngSanitize']) + + .controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) { + $scope.myHTML = 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'; + }]); + </script> + <div ng-controller="ngBindHtmlCtrl"> + <p ng-bind-html="myHTML"></p> + </div> + </doc:source> + <doc:scenario> + it('should check ng-bind-html', function() { + expect(using('.doc-example-live').binding('myHTML')). + toBe('I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'); + }); + </doc:scenario> + </doc:example> */ var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) { return function(scope, element, attr) { @@ -15897,7 +16809,7 @@ return { restrict: 'AC', link: function(scope, element, attr) { - var oldVal = undefined; + var oldVal; scope.$watch(attr[name], ngClassWatchAction, true); @@ -15908,6 +16820,7 @@ if (name !== 'ngClass') { scope.$watch('$index', function($index, old$index) { + // jshint bitwise: false var mod = $index & 1; if (mod !== old$index & 1) { if (mod === selector) { @@ -15954,7 +16867,7 @@ } return classVal; - }; + } } }; }; @@ -15985,7 +16898,7 @@ * names of the properties whose values are truthy will be added as css classes to the * element. * - * @example Example that demostrates basic bindings via ngClass directive. + * @example Example that demonstrates basic bindings via ngClass directive. <example> <file name="index.html"> <p ng-class="{strike: strike, bold: bold, red: red}">Map Syntax Example</p> @@ -16050,26 +16963,18 @@ <input type="button" value="set" ng-click="myVar='my-class'"> <input type="button" value="clear" ng-click="myVar=''"> <br> - <span ng-class="myVar">Sample Text</span> + <span class="base-class" ng-class="myVar">Sample Text</span> </file> <file name="style.css"> - .my-class-add, .my-class-remove { + .base-class { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; } - .my-class, - .my-class-add.my-class-add-active { + .base-class.my-class { color: red; font-size:3em; } - - .my-class-remove.my-class-remove-active { - font-size:1.0em; - color:black; - } </file> <file name="scenario.js"> it('should check ng-class', function() { @@ -16092,10 +16997,10 @@ ## ngClass and pre-existing CSS3 Transitions/Animations The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure. - Therefore, if any CSS3 Transition/Animation styles (outside of ngAnimate) are set on the element, then, if a ngClass animation - is triggered, the ngClass animation will be skipped so that ngAnimate can allow for the pre-existing transition or animation to - take over. This restriction allows for ngClass to still work with standard CSS3 Transitions/Animations that are defined - outside of ngAnimate. + Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder + any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure + to view the step by step details of {@link ngAnimate.$animate#methods_addclass $animate.addClass} and + {@link ngAnimate.$animate#methods_removeclass $animate.removeClass}. */ var ngClassDirective = classDirective('', true); @@ -16210,7 +17115,8 @@ * of the browser view. * * `ngCloak` works in cooperation with the following css rule embedded within `angular.js` and - * `angular.min.js`: + * `angular.min.js`. + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). * * <pre> * [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { @@ -16273,7 +17179,10 @@ * * Controller — The `ngController` directive specifies a Controller class; the class contains business * logic behind the application to decorate the scope with functions and values * - * Note that an alternative way to define controllers is via the {@link ngRoute.$route $route} service. + * Note that you can also attach controllers to the DOM by declaring it in a route definition + * via the {@link ngRoute.$route $route} service. A common mistake is to declare the controller + * again using `ng-controller` in the template itself. This will cause the controller to be attached + * and executed twice. * * @element ANY * @scope @@ -16428,25 +17337,30 @@ /** * @ngdoc directive * @name ng.directive:ngCsp - * @priority 1000 * * @element html * @description * Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support. - * + * * This is necessary when developing things like Google Chrome Extensions. - * + * * CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things). * For us to be compatible, we just need to implement the "getterFn" in $parse without violating * any of these restrictions. - * + * * AngularJS uses `Function(string)` generated functions as a speed optimization. Applying the `ngCsp` * directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will * evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will * be raised. - * + * + * CSP forbids JavaScript to inline stylesheet rules. In non CSP mode Angular automatically + * includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}). + * To make those directives work in CSP mode, include the `angular-csp.css` manually. + * * In order to use this feature put the `ngCsp` directive on the root element of the application. - * + * + * *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.* + * * @example * This example shows how to apply the `ngCsp` directive to the `html` tag. <pre> @@ -16458,14 +17372,9 @@ </pre> */ -var ngCspDirective = ['$sniffer', function($sniffer) { - return { - priority: 1000, - compile: function() { - $sniffer.csp = true; - } - }; -}]; +// ngCsp is not implemented as a proper directive any more, because we need it be processed while we bootstrap +// the system (before $parse is instantiated), for this reason we just have a csp() fn that looks for ng-csp attribute +// anywhere in the current doc /** * @ngdoc directive @@ -16508,13 +17417,17 @@ function(name) { var directiveName = directiveNormalize('ng-' + name); ngEventDirectives[directiveName] = ['$parse', function($parse) { - return function(scope, element, attr) { - var fn = $parse(attr[directiveName]); - element.on(lowercase(name), function(event) { - scope.$apply(function() { - fn(scope, {$event:event}); - }); - }); + return { + compile: function($element, attr) { + var fn = $parse(attr[directiveName]); + return function(scope, element, attr) { + element.on(lowercase(name), function(event) { + scope.$apply(function() { + fn(scope, {$event:event}); + }); + }); + }; + } }; }]; } @@ -16848,7 +17761,7 @@ * @priority 600 * @param {expression} ngIf If the {@link guide/expression expression} is falsy then * the element is removed from the DOM tree. If it is truthy a copy of the compiled - * eleent is added to the DOM tree. + * element is added to the DOM tree. * * @example <example animations="true"> @@ -16866,10 +17779,11 @@ padding:10px; } + /* + The transition styles can also be placed on the CSS base class above + */ .animate-if.ng-enter, .animate-if.ng-leave { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; } @@ -16878,8 +17792,8 @@ opacity:0; } - .animate-if.ng-enter.ng-enter-active, - .animate-if.ng-leave { + .animate-if.ng-leave, + .animate-if.ng-enter.ng-enter-active { opacity:1; } </file> @@ -16891,29 +17805,39 @@ priority: 600, terminal: true, restrict: 'A', + $$tlb: true, compile: function (element, attr, transclude) { return function ($scope, $element, $attr) { - var childElement, childScope; + var block, childScope; $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { - if (childElement) { - $animate.leave(childElement); - childElement = undefined; - } - if (childScope) { - childScope.$destroy(); - childScope = undefined; - } + if (toBoolean(value)) { + childScope = $scope.$new(); transclude(childScope, function (clone) { - childElement = clone; + block = { + startNode: clone[0], + endNode: clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ') + }; $animate.enter(clone, $element.parent(), $element); }); + + } else { + + if (childScope) { + childScope.$destroy(); + childScope = null; + } + + if (block) { + $animate.leave(getBlockElements(block)); + block = null; + } } }); - } + }; } - } + }; }]; /** @@ -16925,10 +17849,10 @@ * Fetches, compiles and includes an external HTML fragment. * * By default, the template URL is restricted to the same domain and protocol as the - * application document. This is done by calling {@link ng.$sce#getTrustedResourceUrl + * application document. This is done by calling {@link ng.$sce#methods_getTrustedResourceUrl * $sce.getTrustedResourceUrl} on it. To load templates from other domains or protocols - * you may either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or - * {@link ng.$sce#trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link + * you may either {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelist them} or + * {@link ng.$sce#methods_trustAsResourceUrl wrap them} as trusted values. Refer to Angular's {@link * ng.$sce Strict Contextual Escaping}. * * In addition, the browser's @@ -16967,8 +17891,8 @@ </select> url of the template: <tt>{{template.url}}</tt> <hr/> - <div class="example-animate-container"> - <div class="include-example" ng-include="template.url"></div> + <div class="slide-animate-container"> + <div class="slide-animate" ng-include="template.url"></div> </div> </div> </file> @@ -16987,7 +17911,7 @@ Content of template2.html </file> <file name="animations.css"> - .example-animate-container { + .slide-animate-container { position:relative; background:white; border:1px solid black; @@ -16995,14 +17919,12 @@ overflow:hidden; } - .example-animate-container > div { + .slide-animate { padding:10px; } - .include-example.ng-enter, .include-example.ng-leave { + .slide-animate.ng-enter, .slide-animate.ng-leave { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; position:absolute; @@ -17014,17 +17936,17 @@ padding:10px; } - .include-example.ng-enter { + .slide-animate.ng-enter { top:-50px; } - .include-example.ng-enter.ng-enter-active { + .slide-animate.ng-enter.ng-enter-active { top:0; } - .include-example.ng-leave { + .slide-animate.ng-leave { top:0; } - .include-example.ng-leave.ng-leave-active { + .slide-animate.ng-leave.ng-leave-active { top:50px; } </file> @@ -17094,6 +18016,11 @@ }; scope.$watch($sce.parseAsResourceUrl(srcExp), function ngIncludeWatchAction(src) { + var afterAnimation = function() { + if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }; var thisChangeId = ++changeCounter; if (src) { @@ -17108,13 +18035,8 @@ currentElement = clone; currentElement.html(response); - $animate.enter(currentElement, null, $element); + $animate.enter(currentElement, null, $element, afterAnimation); $compile(currentElement.contents())(currentScope); - - if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { - $anchorScroll(); - } - currentScope.$emit('$includeContentLoaded'); scope.$eval(onloadExp); }); @@ -17143,7 +18065,7 @@ * <div class="alert alert-error"> * The only appropriate use of `ngInit` for aliasing special properties of * {@link api/ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below. Besides this case, you - * should use {@link guide/dev_guide.mvc.understanding_controller controllers} rather than `ngInit` + * should use {@link guide/controller controllers} rather than `ngInit` * to initialize values on a scope. * </div> * @@ -17183,7 +18105,7 @@ pre: function(scope, element, attrs) { scope.$eval(attrs.ngInit); } - } + }; } }); @@ -17197,7 +18119,7 @@ * The `ngNonBindable` directive tells Angular not to compile or bind the contents of the current * DOM element. This is useful if the element contains what appears to be Angular directives and * bindings but which should be ignored by Angular. This could be the case if you have a site that - * displays snippets of code. for instance. + * displays snippets of code, for instance. * * @element ANY * @@ -17574,49 +18496,35 @@ border:1px solid black; list-style:none; margin:0; - padding:0; + padding:0 10px; } - .example-animate-container > li { - padding:10px; + .animate-repeat { + line-height:40px; list-style:none; + box-sizing:border-box; } + .animate-repeat.ng-move, .animate-repeat.ng-enter, - .animate-repeat.ng-leave, - .animate-repeat.ng-move { + .animate-repeat.ng-leave { -webkit-transition:all linear 0.5s; - -moz-transition:all linear 0.5s; - -o-transition:all linear 0.5s; transition:all linear 0.5s; } + .animate-repeat.ng-leave.ng-leave-active, + .animate-repeat.ng-move, .animate-repeat.ng-enter { - line-height:0; opacity:0; - padding-top:0; - padding-bottom:0; + max-height:0; } + + .animate-repeat.ng-leave, + .animate-repeat.ng-move.ng-move-active, .animate-repeat.ng-enter.ng-enter-active { - line-height:20px; opacity:1; - padding:10px; + max-height:40px; } - - .animate-repeat.ng-leave { - opacity:1; - line-height:20px; - padding:10px; - } - .animate-repeat.ng-leave.ng-leave-active { - opacity:0; - line-height:0; - padding-top:0; - padding-bottom:0; - } - - .animate-repeat.ng-move { } - .animate-repeat.ng-move.ng-move-active { } </file> <file name="scenario.js"> it('should render initial data set', function() { @@ -17648,6 +18556,7 @@ transclude: 'element', priority: 1000, terminal: true, + $$tlb: true, compile: function(element, attr, linker) { return function($scope, $element, $attr){ var expression = $attr.ngRepeat; @@ -17677,10 +18586,10 @@ } else { trackByIdArrayFn = function(key, value) { return hashKey(value); - } + }; trackByIdObjFn = function(key) { return key; - } + }; } match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/); @@ -17742,7 +18651,7 @@ trackById = trackByIdFn(key, value, index); assertNotHasOwnProperty(trackById, '`track by` id'); if(lastBlockMap.hasOwnProperty(trackById)) { - block = lastBlockMap[trackById] + block = lastBlockMap[trackById]; delete lastBlockMap[trackById]; nextBlockMap[trackById] = block; nextBlockOrder[index] = block; @@ -17790,9 +18699,7 @@ nextNode = nextNode.nextSibling; } while(nextNode && nextNode[NG_REMOVED]); - if (block.startNode == nextNode) { - // do nothing - } else { + if (block.startNode != nextNode) { // existing item which got moved $animate.move(getBlockElements(block), null, jqLite(previousNode)); } @@ -17808,7 +18715,9 @@ childScope.$first = (index === 0); childScope.$last = (index === (arrayLength - 1)); childScope.$middle = !(childScope.$first || childScope.$last); - childScope.$odd = !(childScope.$even = index%2==0); + // jshint bitwise: false + childScope.$odd = !(childScope.$even = (index&1) === 0); + // jshint bitwise: true if (!block.startNode) { linker(childScope, function(clone) { @@ -17827,23 +18736,6 @@ }; } }; - - function getBlockElements(block) { - if (block.startNode === block.endNode) { - return jqLite(block.startNode); - } - - var element = block.startNode; - var elements = [element]; - - do { - element = element.nextSibling; - if (!element) break; - elements.push(element); - } while (element !== block.endNode); - - return jqLite(elements); - } }]; /** @@ -17855,6 +18747,7 @@ * provided to the ngShow attribute. The element is shown or hidden by removing or adding * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined * in AngularJS and sets the display style to none (using an !important flag). + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). * * <pre> * <!-- when $scope.myValue is truthy (element is visible) --> @@ -17945,31 +18838,27 @@ </div> </file> <file name="animations.css"> - .animate-show.ng-hide-add, - .animate-show.ng-hide-remove { + .animate-show { -webkit-transition:all linear 0.5s; - -moz-transition:all linear 0.5s; - -o-transition:all linear 0.5s; transition:all linear 0.5s; + line-height:20px; + opacity:1; + padding:10px; + border:1px solid black; + background:white; + } + + .animate-show.ng-hide-add, + .animate-show.ng-hide-remove { display:block!important; } - .animate-show.ng-hide-add.ng-hide-add-active, - .animate-show.ng-hide-remove { + .animate-show.ng-hide { line-height:0; opacity:0; padding:0 10px; } - .animate-show.ng-hide-add, - .animate-show.ng-hide-remove.ng-hide-remove-active { - line-height:20px; - opacity:1; - padding:10px; - border:1px solid black; - background:white; - } - .check-element { padding:10px; border:1px solid black; @@ -18007,6 +18896,7 @@ * provided to the ngHide attribute. The element is shown or hidden by removing or adding * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is predefined * in AngularJS and sets the display style to none (using an !important flag). + * For CSP mode please add `angular-csp.css` to your html file (see {@link ng.directive:ngCsp ngCsp}). * * <pre> * <!-- when $scope.myValue is truthy (element is hidden) --> @@ -18097,31 +18987,27 @@ </div> </file> <file name="animations.css"> - .animate-hide.ng-hide-add, - .animate-hide.ng-hide-remove { + .animate-hide { -webkit-transition:all linear 0.5s; - -moz-transition:all linear 0.5s; - -o-transition:all linear 0.5s; transition:all linear 0.5s; + line-height:20px; + opacity:1; + padding:10px; + border:1px solid black; + background:white; + } + + .animate-hide.ng-hide-add, + .animate-hide.ng-hide-remove { display:block!important; } - .animate-hide.ng-hide-add.ng-hide-add-active, - .animate-hide.ng-hide-remove { + .animate-hide.ng-hide { line-height:0; opacity:0; padding:0 10px; } - .animate-hide.ng-hide-add, - .animate-hide.ng-hide-remove.ng-hide-remove-active { - line-height:20px; - opacity:1; - padding:10px; - border:1px solid black; - background:white; - } - .check-element { padding:10px; border:1px solid black; @@ -18250,9 +19136,9 @@ <hr/> <div class="animate-switch-container" ng-switch on="selection"> - <div ng-switch-when="settings">Settings Div</div> - <div ng-switch-when="home">Home Span</div> - <div ng-switch-default>default</div> + <div class="animate-switch" ng-switch-when="settings">Settings Div</div> + <div class="animate-switch" ng-switch-when="home">Home Span</div> + <div class="animate-switch" ng-switch-default>default</div> </div> </div> </file> @@ -18271,15 +19157,12 @@ overflow:hidden; } - .animate-switch-container > div { + .animate-switch { padding:10px; } - .animate-switch-container > .ng-enter, - .animate-switch-container > .ng-leave { + .animate-switch.ng-animate { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; - -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; position:absolute; @@ -18289,19 +19172,14 @@ bottom:0; } - .animate-switch-container > .ng-enter { + .animate-switch.ng-leave.ng-leave-active, + .animate-switch.ng-enter { top:-50px; } - .animate-switch-container > .ng-enter.ng-enter-active { + .animate-switch.ng-leave, + .animate-switch.ng-enter.ng-enter-active { top:0; } - - .animate-switch-container > .ng-leave { - top:0; - } - .animate-switch-container > .ng-leave.ng-leave-active { - top:50px; - } </file> <file name="scenario.js"> it('should start in settings', function() { @@ -18357,7 +19235,7 @@ } }); } - } + }; }]; var ngSwitchWhenDirective = ngDirective({ @@ -18600,7 +19478,7 @@ Color (null allowed): <span class="nullable"> <select ng-model="color" ng-options="c.name for c in colors"> - <option value="">-- chose color --</option> + <option value="">-- choose color --</option> </select> </span><br/> @@ -18630,10 +19508,12 @@ */ var ngOptionsDirective = valueFn({ terminal: true }); +// jshint maxlen: false var selectDirective = ['$compile', '$parse', function($compile, $parse) { //0000111110000000000022220000000000000000000000333300000000000000444444444444444000000000555555555555555000000066666666666666600000000000000007777000000000000000000088888 var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/, nullModelCtrl = {$setViewValue: noop}; +// jshint maxlen: 100 return { restrict: 'E', @@ -18714,7 +19594,7 @@ // find "null" option for(var i = 0, children = element.children(), ii = children.length; i < ii; i++) { - if (children[i].value == '') { + if (children[i].value === '') { emptyOption = nullOption = children.eq(i); break; } @@ -18737,16 +19617,16 @@ }); } - if (optionsExp) Options(scope, element, ngModelCtrl); - else if (multiple) Multiple(scope, element, ngModelCtrl); - else Single(scope, element, ngModelCtrl, selectCtrl); + if (optionsExp) setupAsOptions(scope, element, ngModelCtrl); + else if (multiple) setupAsMultiple(scope, element, ngModelCtrl); + else setupAsSingle(scope, element, ngModelCtrl, selectCtrl); //////////////////////////// - function Single(scope, selectElement, ngModelCtrl, selectCtrl) { + function setupAsSingle(scope, selectElement, ngModelCtrl, selectCtrl) { ngModelCtrl.$render = function() { var viewValue = ngModelCtrl.$viewValue; @@ -18771,7 +19651,7 @@ }); } - function Multiple(scope, selectElement, ctrl) { + function setupAsMultiple(scope, selectElement, ctrl) { var lastView; ctrl.$render = function() { var items = new HashMap(ctrl.$viewValue); @@ -18802,12 +19682,14 @@ }); } - function Options(scope, selectElement, ctrl) { + function setupAsOptions(scope, selectElement, ctrl) { var match; if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) { throw ngOptionsMinErr('iexp', - "Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}", + "Expected expression in form of " + + "'_select_ (as _label_)? for (_key_,)?_value_ in _collection_'" + + " but got '{0}'. Element: {1}", optionsExp, startingTag(selectElement)); } @@ -18819,9 +19701,10 @@ valuesFn = $parse(match[7]), track = match[8], trackFn = track ? $parse(match[8]) : null, - // This is an array of array of existing option groups in DOM. We try to reuse these if possible - // optionGroupsCache[0] is the options with no option group - // optionGroupsCache[?][0] is the parent: either the SELECT or OPTGROUP element + // This is an array of array of existing option groups in DOM. + // We try to reuse these if possible + // - optionGroupsCache[0] is the options with no option group + // - optionGroupsCache[?][0] is the parent: either the SELECT or OPTGROUP element optionGroupsCache = [[{element: selectElement, label:''}]]; if (nullOption) { @@ -18875,7 +19758,7 @@ key = selectElement.val(); if (key == '?') { value = undefined; - } else if (key == ''){ + } else if (key === ''){ value = null; } else { if (trackFn) { @@ -18903,7 +19786,8 @@ scope.$watch(render); function render() { - var optionGroups = {'':[]}, // Temporary location for the option groups before we render them + // Temporary location for the option groups before we render them + var optionGroups = {'':[]}, optionGroupNames = [''], optionGroupName, optionGroup, @@ -18952,7 +19836,9 @@ optionGroupNames.push(optionGroupName); } if (multiple) { - selected = selectedSet.remove(trackFn ? trackFn(scope, locals) : valueFn(scope, locals)) !== undefined; + selected = isDefined( + selectedSet.remove(trackFn ? trackFn(scope, locals) : valueFn(scope, locals)) + ); } else { if (trackFn) { var modelCast = {}; @@ -18964,9 +19850,12 @@ selectedSet = selectedSet || selected; // see if at least one item is selected } label = displayFn(scope, locals); // what will be seen by the user - label = label === undefined ? '' : label; // doing displayFn(scope, locals) || '' overwrites zero values + + // doing displayFn(scope, locals) || '' overwrites zero values + label = isDefined(label) ? label : ''; optionGroup.push({ - id: trackFn ? trackFn(scope, locals) : (keyName ? keys[index] : index), // either the index into array or key from object + // either the index into array or key from object + id: trackFn ? trackFn(scope, locals) : (keyName ? keys[index] : index), label: label, selected: selected // determine if we should be selected }); @@ -19138,4 +20027,5 @@ }); })(window, document); -angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}</style>'); \ No newline at end of file + +!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-start{clip:rect(0,auto,auto,0);-ms-zoom:1.0001;}.ng-animate-active{clip:rect(-1px,auto,auto,0);-ms-zoom:1;}</style>'); \ No newline at end of file Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", { Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js =================================================================== --- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js 2013-11-10 10:51:35 UTC (rev 224) +++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js 2013-11-10 11:10:19 UTC (rev 225) @@ -1,4 +1,5 @@ /* %%Ignore-License */ +'use strict'; angular.module("ngLocale", [], ["$provide", function($provide) { var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"}; $provide.value("$locale", {
participants (1)
-
echatellier@users.nuiton.org