1
0
mirror of https://github.com/2ec0b4/kaamelott-soundboard.git synced 2025-12-08 15:43:24 +00:00

126 Commits

Author SHA1 Message Date
Antoine
00a81e3ddf (master) Exclut le répertoire dist seulement à la racine 2023-10-30 08:29:43 +01:00
Antoine
b1bc28996b Met à jour static.yml 2023-10-30 08:25:56 +01:00
Antoine
f8457e4e98 Met en plce un workflow basique 2023-10-30 08:22:35 +01:00
Antoine
5db12358f4 Crée fichier .nojekyll 2023-10-30 08:18:19 +01:00
Antoine
b340ab9c14 Crée fichier .nojekyll 2023-10-30 08:17:02 +01:00
Antoine
8930cd2dc7 (master) Ajoute les dépendances manquantes 2023-10-30 08:06:39 +01:00
Antoine
dca241fc0b Create CNAME 2023-10-30 07:09:37 +01:00
Antoine
bb20540d68 Delete CNAME 2023-10-30 07:09:24 +01:00
Antoine
e9e11d6157 (master) Récupération d'un build pour GitHub Pages 2023-10-29 22:58:59 +01:00
Antoine
a744f48e50 Create CNAME 2023-10-29 22:50:13 +01:00
Antoine
f740ae2c63 (master) Merge branch 'scastrec-master'
* scastrec-master:
  Update README.md
  Update README.md
2022-01-22 18:03:14 +01:00
Antoine
cfe6151af7 (scastrec-master) Merge branch 'master' of https://github.com/scastrec/kaamelott-soundboard into scastrec-master
* 'master' of https://github.com/scastrec/kaamelott-soundboard:
  Update README.md
  Update README.md
2022-01-22 18:03:03 +01:00
Antoine
4c8357a606 (master) Merge branch 'stardeux-fixname'
* stardeux-fixname:
  Fix character name
2022-01-22 18:02:44 +01:00
Antoine
8b546c22f6 (stardeux-fixname) Merge branch 'fixname' of https://github.com/stardeux/kaamelott-soundboard into stardeux-fixname
* 'fixname' of https://github.com/stardeux/kaamelott-soundboard:
  Fix character name
2022-01-22 18:00:39 +01:00
Antoine
9866e39626 Merge branch 'dprslt-trois_jours_voyages_trois_jours_chez_vous'
# By Antoine (4) and others
* dprslt-trois_jours_voyages_trois_jours_chez_vous:
  (dprslt-trois_jours_voyages_trois_jours_chez_vous) Ajoute une majuscule et raccourcit le son
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) (an0rak-dev-son/peur_justifiee) Corrige une coquille
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) (Wobak-master) Corrige une coquille
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) ((no branch, rebasing Wobak-master)) Ça va j'picole pas souvent !
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout Yvain petits pets
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout mp3 petits pets
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ajout de 'peur justifiee' (leodagan)
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) (Wobak-master) Corrige une coquille
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ajout Yvain petits pets
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ajout mp3 petits pets
  ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ça va j'picole pas souvent !
  Ajout trois_jours_voyages_trois_jours_chez_vous

# Conflicts:
#	sounds/sounds.json
2022-01-22 17:41:40 +01:00
Antoine
4ca047df46 (dprslt-trois_jours_voyages_trois_jours_chez_vous) Ajoute une majuscule et raccourcit le son 2022-01-22 17:40:16 +01:00
Antoine
76d75492a3 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) (an0rak-dev-son/peur_justifiee) Corrige une coquille 2022-01-22 17:34:16 +01:00
Antoine
b31e08ddcf ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) (Wobak-master) Corrige une coquille 2022-01-22 17:33:44 +01:00
François Cléty
4206dd7ea7 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) ((no branch, rebasing Wobak-master)) Ça va j'picole pas souvent ! 2022-01-22 17:33:44 +01:00
Wobak
0f708a343c ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout Yvain petits pets 2022-01-22 17:33:42 +01:00
Wobak
7439566860 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout mp3 petits pets 2022-01-22 17:33:12 +01:00
Sylvain Nieuwlandt
0d28661ce2 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ajout de 'peur justifiee' (leodagan) 2022-01-22 17:31:42 +01:00
Antoine
525023bb95 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) (Wobak-master) Corrige une coquille 2022-01-22 17:30:54 +01:00
Wobak
5c1f5a8ff4 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ajout Yvain petits pets 2022-01-22 17:30:23 +01:00
Wobak
1aa1b0ed31 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ajout mp3 petits pets 2022-01-22 17:29:39 +01:00
François Cléty
1020bc8b67 ((no branch, rebasing dprslt-trois_jours_voyages_trois_jours_chez_vous)) Ça va j'picole pas souvent ! 2022-01-22 17:29:36 +01:00
Antoine
afef090577 Merge branch 'an0rak-dev-son/peur_justifiee'
# By Antoine (2) and others
* an0rak-dev-son/peur_justifiee:
  (an0rak-dev-son/peur_justifiee) Corrige une coquille
  ((no branch, rebasing an0rak-dev-son/peur_justifiee)) (Wobak-master) Corrige une coquille
  ((no branch, rebasing an0rak-dev-son/peur_justifiee)) ((no branch, rebasing Wobak-master)) Ça va j'picole pas souvent !
  ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout Yvain petits pets
  ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout mp3 petits pets
  ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ça va j'picole pas souvent !
  Ajout de 'peur justifiee' (leodagan)

# Conflicts:
#	sounds/sounds.json
2022-01-22 17:27:27 +01:00
Antoine
52ed833439 (an0rak-dev-son/peur_justifiee) Corrige une coquille 2022-01-22 17:26:44 +01:00
Antoine
a0a1900e41 ((no branch, rebasing an0rak-dev-son/peur_justifiee)) (Wobak-master) Corrige une coquille 2022-01-22 17:25:39 +01:00
François Cléty
ce6bc2a4a1 ((no branch, rebasing an0rak-dev-son/peur_justifiee)) ((no branch, rebasing Wobak-master)) Ça va j'picole pas souvent ! 2022-01-22 17:25:02 +01:00
Wobak
bd30895416 ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout Yvain petits pets 2022-01-22 17:24:59 +01:00
Wobak
75cd011406 ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ajout mp3 petits pets 2022-01-22 17:24:13 +01:00
François Cléty
8dad9c1282 ((no branch, rebasing an0rak-dev-son/peur_justifiee)) Ça va j'picole pas souvent ! 2022-01-22 17:24:11 +01:00
Antoine
a8048496a2 Merge branch 'Wobak-master'
# By Wobak (2) and others
* Wobak-master:
  (Wobak-master) Corrige une coquille
  ((no branch, rebasing Wobak-master)) Ça va j'picole pas souvent !
  Ajout Yvain petits pets
  Ajout mp3 petits pets

# Conflicts:
#	sounds/sounds.json
2022-01-22 17:20:37 +01:00
Antoine
877084c370 (Wobak-master) Corrige une coquille 2022-01-22 17:19:30 +01:00
François Cléty
669e6c310b ((no branch, rebasing Wobak-master)) Ça va j'picole pas souvent ! 2022-01-22 17:18:24 +01:00
Antoine
ea00e03f73 (master) Merge branch 'fclety-feat/ivresse'
* fclety-feat/ivresse:
  Ça va j'picole pas souvent !
2022-01-22 17:14:42 +01:00
dprslt
3fb102f35b Ajout trois_jours_voyages_trois_jours_chez_vous 2021-06-24 15:31:39 +02:00
Sylvain Nieuwlandt
a39b7eea6b Ajout de 'peur justifiee' (leodagan) 2021-06-03 13:52:55 +02:00
Wobak
a752b01310 Ajout Yvain petits pets 2021-01-03 19:49:48 +01:00
Wobak
b2c7cf7bbc Ajout mp3 petits pets 2021-01-03 19:47:29 +01:00
François Cléty
52f4c16ba7 Ça va j'picole pas souvent ! 2020-11-26 16:41:53 +01:00
Stephane
f5ca78ce54 Update README.md
UPdate github link
2020-11-05 10:49:58 +01:00
Stephane
70a6b8cf60 Update README.md
Add link to alexa bot
2020-11-04 17:24:28 +01:00
Jeremy Thil
c4d455f2ec Fix character name 2020-11-02 11:04:07 +01:00
Antoine
bce6888bda (master) Merge branch 'karinesabatier-seli-leodagan'
* karinesabatier-seli-leodagan:
  (karinesabatier-seli-leodagan) Apporte des modifications
  Un peu de Seli et de Léodagan
2020-10-29 22:13:00 +01:00
Antoine
f8d7d6acbf (karinesabatier-seli-leodagan) Apporte des modifications 2020-10-29 22:12:44 +01:00
Zenikarine
4525d59565 Un peu de Seli et de Léodagan 2020-10-26 23:15:27 +01:00
Antoine
e86e0b65df (master) Merge branch 'pabuisson-mavez-lair-en-forme-vous-ce-soir'
* pabuisson-mavez-lair-en-forme-vous-ce-soir:
  M'avez l'air en forme hein vous ce soir !
2020-10-19 22:57:54 +02:00
Antoine
881474da46 (pabuisson-mavez-lair-en-forme-vous-ce-soir) Merge branch 'mavez-lair-en-forme-vous-ce-soir' of https://github.com/pabuisson/kaamelott-soundboard into pabuisson-mavez-lair-en-forme-vous-ce-soir
* 'mavez-lair-en-forme-vous-ce-soir' of https://github.com/pabuisson/kaamelott-soundboard:
  M'avez l'air en forme hein vous ce soir !
2020-10-19 22:52:22 +02:00
Pierre-Adrien
b688b4f417 M'avez l'air en forme hein vous ce soir ! 2020-10-04 16:07:34 +02:00
Valentin Cocaud
93c2d34f7e Harmonisation des noms des personnages (#154) 2020-10-01 18:39:48 +02:00
Pierre-Adrien
46ce9c0935 Correction 2 autres épisodes livre V 2020-09-25 22:36:38 +02:00
Pierre-Adrien
3dff3772cf Correction numéro d'épisode + complété titre 2020-09-25 22:26:45 +02:00
Pierre-Adrien
82cc89ea09 Merge branch 'master' into attendus-aux-archives 2020-09-25 22:19:02 +02:00
Antoine
908e0af5bc (master) Merge branch 'pabuisson-ah-ah-ah-les-pegus'
* pabuisson-ah-ah-ah-les-pegus:
  sound file
  Ha ha ha, les pégus !
2020-09-21 22:17:13 +02:00
Pierre-Adrien
7a2e70e938 sound file 2020-09-12 19:14:58 +02:00
Pierre-Adrien
c1aa11208c Ha ha ha, les pégus ! 2020-09-12 19:14:11 +02:00
Pierre-Adrien
369d2d8eb9 Écoutez, déjà que ça me gonfle de porter des messages !!! 2020-09-12 17:28:19 +02:00
Pierre-Adrien
5e1066107a Correction du num d'épisode d'un autre son du livre V 2020-09-12 17:21:58 +02:00
Pierre-Adrien
bf573b514c Nouveau son: "Voilà... ZUT !"
C'est mortel.
2020-09-12 17:21:36 +02:00
Antoine
8c3269e13d (master) Supprime des silences en début de fichier 2020-07-22 14:24:08 +02:00
Antoine
e1c02e92e4 (master) Merge branch 'karinesabatier-burgonde-serie'
* karinesabatier-burgonde-serie:
  (karinesabatier-burgonde-serie) Normalise les sons
  Le Jeu de la Guerre
  IV-62, Le Jeu de la Guerre
2020-07-13 23:13:39 +02:00
Antoine
1d67a9edf7 (karinesabatier-burgonde-serie) Normalise les sons 2020-07-13 23:11:55 +02:00
Zenikarine
73005ac7c7 Le Jeu de la Guerre 2020-07-13 21:17:07 +02:00
Antoine
bfc6eabbcd (master) Merge branch 'thperret-sons-qui-envoient-du-pate'
* thperret-sons-qui-envoient-du-pate:
  (thperret-sons-qui-envoient-du-pate) Normalise les sons
  Kadoc Livre III 82
2020-07-12 22:21:08 +02:00
Antoine
d29d9d9e27 (thperret-sons-qui-envoient-du-pate) Normalise les sons 2020-07-12 22:20:49 +02:00
Antoine
5a6a308bc1 Merge branch 'sons-qui-envoient-du-pate' of https://github.com/thperret/kaamelott-soundboard into thperret-sons-qui-envoient-du-pate
# By Thomas Perret
# Via Thomas Perret
* 'sons-qui-envoient-du-pate' of https://github.com/thperret/kaamelott-soundboard:
  Kadoc Livre III 82

# Conflicts:
#	sounds/sounds.json
2020-07-12 22:20:15 +02:00
Antoine
d3f3d4fa91 (master) Merge branch 'MaxenceG2M-chef-de-guerre'
* MaxenceG2M-chef-de-guerre:
  (MaxenceG2M-chef-de-guerre) Normalise le son
  J'suis chef de guerre
2020-07-12 22:13:46 +02:00
Antoine
117aafcd77 (MaxenceG2M-chef-de-guerre) Normalise le son 2020-07-12 22:13:25 +02:00
Thomas Perret
c5ff1fd599 Kadoc Livre III 82 2020-07-09 20:12:07 +02:00
dfea143e0a J'suis chef de guerre 2020-07-04 22:41:36 +02:00
Zenikarine
441fec972b IV-62, Le Jeu de la Guerre 2020-07-01 22:55:04 +02:00
Antoine
8b1d7a038c (master) Modifie une dépendance Gulp 2020-06-19 13:49:55 +02:00
Antoine
84c07bdc66 (master) Dissocie une commande 2020-06-19 13:46:17 +02:00
Antoine
12e1b26fb2 (master) Harmonise le volume des fichiers sons 2020-06-17 17:00:01 +02:00
Antoine
e1d111efe8 (master) Merge branch 'kikko-rm-ajout-sons-divers'
* kikko-rm-ajout-sons-divers:
  (kikko-rm-ajout-sons-divers) Modifie des répliques et le nom d'un fichier
  ajout sons divers
2020-06-17 16:25:56 +02:00
Antoine
3a6abda3e7 (kikko-rm-ajout-sons-divers) Modifie des répliques et le nom d'un fichier 2020-06-17 16:25:19 +02:00
Antoine
3abf72a905 (kikko-rm-ajout-sons-divers) Merge branch 'ajout-sons-divers' of https://github.com/kikko-rm/kaamelott-soundboard into kikko-rm-ajout-sons-divers
* 'ajout-sons-divers' of https://github.com/kikko-rm/kaamelott-soundboard:
  ajout sons divers
2020-06-17 16:15:34 +02:00
Antoine
02ed48e584 (master) Crée une configuration Docker pour l'harmonisation du volume des fichiers sons 2020-06-17 16:14:51 +02:00
Antoine
97b7b2a0a7 (master) Modifie la configuration Docker 2020-06-17 15:40:27 +02:00
kikko-rm
e1b266b6cd ajout sons divers
Livre I, 6 - Le Garde du Corps - Allez-y mollo avec la joie
Livre I, 15 - Les Défis de Merlin - C'est pas pour rien qu'on m'appelle le fourbe
Livre I, 39 - Le Cas Yvain - Il parle pas, il bouge pas, il fait la gueule tout le temps! Dès qu'on lui fait une remarque, il lève les yeux au ciel! tiens, voilà!
Livre I, 39 - Le Cas Yvain - Première nouvelle! J'ai jamais entendu le son de sa voix! Hum... Si, là, voilà...
Livre I, 39 - Le Cas Yvain - Quand il a rien à dire, il dit rien. Il a pas été élevé chez les porcs, excusez-nous, hein!
Livre II 48 - La Vigilance d'Arthur - Ils commencent à doucement le faire chier ceux là aussi
Livre I 97 - Agnus Dei - Les gars me regardent avec des billes comme ça et puis ils décrochent hein... Ah rideau
Livre I 97 - Agnus Dei - Donc heu Amen, 'fin Deu gracia j'sais plus quoi... J'suis désolé, j'ai pas eu le temps de potasser les formules
2020-06-11 16:25:59 +02:00
Antoine
53cfccfe46 Merge branch 'klmp200-bot-telegram'
# By Bartuccio Antoine
# Via Antoine (1) and Bartuccio Antoine (1)
* klmp200-bot-telegram:
  Le lien d'un joli bot telegram qui utilise cet incroyable projet

# Conflicts:
#	README.md
2020-05-22 23:31:45 +02:00
Antoine
676ef979f4 (master) Merge branch 'master' of github.com:2ec0b4/kaamelott-soundboard
* 'master' of github.com:2ec0b4/kaamelott-soundboard:
  Lien vers une Application Android (#146)
2020-05-22 23:29:15 +02:00
Antoine
0e7e1fc3a2 (master) Fix 2020-05-22 23:28:57 +02:00
Antoine
2107f82c5d (klmp200-bot-telegram) Merge branch 'bot-telegram' of https://github.com/klmp200/kaamelott-soundboard into klmp200-bot-telegram
* 'bot-telegram' of https://github.com/klmp200/kaamelott-soundboard:
  Le lien d'un joli bot telegram qui utilise cet incroyable projet
2020-05-22 23:24:31 +02:00
Adel
dc356e1dd1 Lien vers une Application Android (#146) 2020-05-22 23:22:43 +02:00
Antoine
8d50ba255d (master) Merge branch 'bwjtkw-Ajout_perceval_des_glands_tous_les_jours'
* bwjtkw-Ajout_perceval_des_glands_tous_les_jours:
  (bwjtkw-Ajout_perceval_des_glands_tous_les_jours) Corrige une virgule manquante et précise la réplique
  Ajout c'est pas comme si on passait pour des glands tous les jours
2020-05-22 23:11:50 +02:00
Antoine
c8a706dc4b (bwjtkw-Ajout_perceval_des_glands_tous_les_jours) Corrige une virgule manquante et précise la réplique 2020-05-22 23:11:26 +02:00
Antoine
a6437498d5 (bwjtkw-Ajout_perceval_des_glands_tous_les_jours) Merge branch 'Ajout_perceval_des_glands_tous_les_jours' of https://github.com/bwjtkw/kaamelott-soundboard into bwjtkw-Ajout_perceval_des_glands_tous_les_jours
* 'Ajout_perceval_des_glands_tous_les_jours' of https://github.com/bwjtkw/kaamelott-soundboard:
  Ajout c'est pas comme si on passait pour des glands tous les jours
2020-05-22 23:07:06 +02:00
Hugo Gresse
dbb0787ac5 Normalize mp3 scripts (#143) 2020-05-22 23:04:54 +02:00
Bartuccio Antoine
1ad8f0d915 Le lien d'un joli bot telegram qui utilise cet incroyable projet 2020-05-06 12:05:33 +02:00
Baptiste Wojtkowski
3756b60b4c Ajout c'est pas comme si on passait pour des glands tous les jours 2020-04-29 22:16:06 +02:00
Antoine
f1ed8425ff (master) Merge branch 'qboileau-blaise-cest-de-la-merde'
* qboileau-blaise-cest-de-la-merde:
  Père Blaise : "C'est de la merde" La quinte juste
2020-04-27 23:01:59 +02:00
Antoine
20dc1e5328 Merge branch 'blaise-cest-de-la-merde' of https://github.com/qboileau/kaamelott-soundboard into qboileau-blaise-cest-de-la-merde
# By qboileau
# Via qboileau
* 'blaise-cest-de-la-merde' of https://github.com/qboileau/kaamelott-soundboard:
  Père Blaise : "C'est de la merde" La quinte juste

# Conflicts:
#	sounds/sounds.json
2020-04-27 23:01:37 +02:00
Antoine
07e0c0c622 (master) Merge branch 'Ant95-perceval-337'
* Ant95-perceval-337:
  Perceval - Livre 3 - Épisode 37 - J'en ai rien à foutre
2020-04-27 22:59:09 +02:00
qboileau
e576800f6e Père Blaise : "C'est de la merde" La quinte juste 2020-04-22 18:35:11 +02:00
Antoine MENOUX
ed60b8a8a3 Perceval - Livre 3 - Épisode 37 - J'en ai rien à foutre 2020-04-04 22:32:33 +02:00
Antoine
ab3ae55b40 (master) Merge branch 'adel-chebbine-new_sounds'
* adel-chebbine-new_sounds:
  new sounds
2020-03-31 12:00:19 +02:00
Adel CHEBBINE
beb098638e new sounds 2020-03-29 13:03:43 +02:00
Antoine
2f64fe295e (master) Merge branch 'sleduc-oh-mais-vous-etes-des-malades'
* sleduc-oh-mais-vous-etes-des-malades:
  Oh mais vous êtes des malades.
2020-03-10 22:06:11 +01:00
Antoine
4c352f4859 (sleduc-oh-mais-vous-etes-des-malades) Merge branch 'oh-mais-vous-etes-des-malades' of https://github.com/sleduc/kaamelott-soundboard into sleduc-oh-mais-vous-etes-des-malades
* 'oh-mais-vous-etes-des-malades' of https://github.com/sleduc/kaamelott-soundboard:
  Oh mais vous êtes des malades.
2020-03-10 22:04:59 +01:00
Antoine
d24157854a (master) Corrige les favicons 2020-03-10 22:03:28 +01:00
Antoine
51051704af (master) Supprime Likely 2020-03-10 21:44:12 +01:00
Sébastien Leduc
0f43c5789e Oh mais vous êtes des malades. 2020-02-28 11:17:56 +01:00
Antoine
59423c0d2d (master) Merge branch 'petosorus-random_button'
* petosorus-random_button:
  (petosorus-random_button) Corrige un "faux-vrai" de référence de fichier versionné par Gulp
  (petosorus-random_button) Améliore les espacements des boutons
  (petosorus-random_button) Réinitialise également le filtre
  (petosorus-random_button) Active / désactive le bouton
  Random button styling
  styling
  Filtrage lors de l'aléatoire
  Proto bouton aléatoire
2020-02-15 20:01:13 +01:00
Antoine
9eb2d9c021 (petosorus-random_button) Corrige un "faux-vrai" de référence de fichier versionné par Gulp 2020-02-15 20:00:49 +01:00
Antoine
a29a0bd092 (master) Merge branch 'sbrodin-ajout_sons'
* sbrodin-ajout_sons:
  Et oui mémé, t'es bien mouchée ! héhéhéhé
2020-02-11 21:46:40 +01:00
Antoine
e01f61c2d7 (sbrodin-ajout_sons) Merge branch 'ajout_sons' of https://github.com/sbrodin/kaamelott-soundboard into sbrodin-ajout_sons
* 'ajout_sons' of https://github.com/sbrodin/kaamelott-soundboard:
  Et oui mémé, t'es bien mouchée ! héhéhéhé
2020-02-11 21:46:25 +01:00
Antoine
8bfdfc5d68 (master) Merge branch 'corentinbettiol-patch-1'
* corentinbettiol-patch-1:
  Fix typo
2020-02-11 21:43:00 +01:00
Stanislas Brodin
4583106c97 Et oui mémé, t'es bien mouchée ! héhéhéhé 2020-02-10 16:24:12 +01:00
Corentin Bettiol
a44b2d34c4 Fix typo
"Eelance" -> "Relance"
2020-02-02 20:01:33 +01:00
Antoine
3b05583831 (master) Ajoute un fichier manifest.json et révise les favicons 2020-01-25 15:35:23 +01:00
Antoine
f204478c5c (master) Corrige une erreur 2020-01-25 14:16:04 +01:00
Antoine
603ba3e8c2 (master) Ajoute une réplique du teaser du film 🔥 2020-01-23 12:50:41 +01:00
Antoine
2413b608c0 (master) Ajoute un fichier CHANGELOG.md 2020-01-13 08:59:15 +01:00
Antoine
c8c5343265 (master) Modifie le protocole 2020-01-12 23:20:54 +01:00
Antoine
c01486701c (master) RIP Google Plus 2020-01-12 23:20:14 +01:00
Antoine
8df481de41 (master) Merge branch 'kevinlacire-master'
* kevinlacire-master:
  (kevinlacire-master) Apporte des corrections
  Livre II - Tome 1
2020-01-12 23:00:03 +01:00
Antoine
24f7fac07e (kevinlacire-master) Apporte des corrections 2020-01-12 22:59:33 +01:00
Antoine
bed1c666cf (kevinlacire-master) Merge branch 'master' of https://github.com/kevinlacire/kaamelott-soundboard into kevinlacire-master
* 'master' of https://github.com/kevinlacire/kaamelott-soundboard:
  Livre II - Tome 1
2020-01-10 16:56:07 +01:00
Antoine
6e84cfc33c (master) Merge branch 'sbrodin-ajout_sons'
* sbrodin-ajout_sons:
  Vous êtes un gros nul
  C'est l'anniversaire dans tous les recoins
2020-01-10 16:52:51 +01:00
Stanislas Brodin
9511455cf8 Vous êtes un gros nul 2020-01-10 11:27:56 +01:00
Kévin LACIRE
8e1ed1eacb Livre II - Tome 1 2019-12-29 18:21:17 +01:00
Stanislas Brodin
75571b550e C'est l'anniversaire dans tous les recoins 2019-12-13 10:45:08 +01:00
Djerfy
8fa005ee9b Run bower install on the docker build (#128) 2019-11-13 16:46:05 +01:00
1675 changed files with 101429 additions and 192 deletions

6
.docker/base/Dockerfile Normal file
View File

@@ -0,0 +1,6 @@
FROM alpine:3.10
WORKDIR /app
RUN set -xe && \
apk -U add bash git curl wget npm && \
npm install -g bower && \
npm install -g gulp

View File

@@ -0,0 +1,13 @@
FROM jrottenberg/ffmpeg:4.2-ubuntu
RUN apt-get -yqq update && \
apt-get install -yq --no-install-recommends python3-pip && \
apt-get autoremove -y && \
apt-get clean -y
RUN pip3 install ffmpeg-normalize
COPY normalize.sh /normalize.sh
RUN chmod +x /normalize.sh
ENTRYPOINT ["/normalize.sh"]

View File

@@ -0,0 +1,25 @@
# Noramlizing audio level
> Audio normalization is the application of a constant amount of gain to an audio recording to bring the amplitude to a target level (the norm). Because the same amount of gain is applied across the entire recording, the signal-to-noise ratio and relative dynamics are unchanged. Normalization is one of the functions commonly provided by a digital audio workstation. https://en.wikipedia.org/wiki/Audio_normalization
In other words, normalizing Kaamelott sounds allow each sound to have a ~same perceived audio loudness. So it reduce the volume of very loud sound and increase the volume of less audible ones.
## Prerequisite
- install `ffmpeg` using your preferred package managed (brew or apt-get for eg) or [this link](https://www.ffmpeg.org/download.html)
- install `ffmpeg-normalize` following [this](https://github.com/slhck/ffmpeg-normalize#installation)
With Docker:
```
docker build -t ks-normalize .docker/normalize/
```
## Usage
Normalize a given sound file
```
docker run --rm -v $(pwd):$(pwd) -w $(pwd) ks-normalize sounds/victoriae_mundis.mp3
```
It will copy replace the file with the new normalized sound to `victoriae_mundis.mp3`.

46
.docker/normalize/normalize.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
TEMP_FILE=temp.mp3
PADDED_FILE=paddedNormalized.temp.mp3
# Check than ffmpeg && ffmpeg-normalize is installed
if ! [ -x "$(command -v ffmpeg)" ]; then
echo 'Error: ffmpeg is not installed.' >&2
exit 1
fi
if ! [ -x "$(command -v ffmpeg-normalize)" ]; then
echo 'Error: ffmpeg-normalize is not installed.' >&2
exit 1
fi
# Check that input mp3 is present & exist
if [ -n "$1" ]
then
inputFile=$1
else
echo 'Error: missing input file' >&2
exit 1
fi
if [ ! -f ./$inputFile ]; then
echo "File not found!"
fi
cleanup () {
rm -f $TEMP_FILE
rm -f $PADDED_FILE
rm -f final.mp3
}
cleanup
# Normalize the file
# Due to an issue with ffmpeg-normalize, file shorter than 3s cannot be normalized
# The following use a solution from https://github.com/slhck/ffmpeg-normalize/issues/87#issuecomment-488944192
ffmpeg -i $inputFile -af "adelay=10000|10000" $TEMP_FILE
ffmpeg-normalize $TEMP_FILE -o $PADDED_FILE -c:a libmp3lame
ffmpeg -i $PADDED_FILE -ss 00:00:10.000 -acodec copy $inputFile -y
cleanup

41
.github/workflows/static.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
# Upload entire repository
path: './docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2

6
.gitignore vendored
View File

@@ -1,5 +1,9 @@
bower_components
dist
!docs/bower_components
/dist
node_modules
.gitconfig
*.swp
.DS_STORE
.idea/
package-lock.json

1
.nojekyll Normal file
View File

@@ -0,0 +1 @@

View File

@@ -8,28 +8,19 @@
<title>Kaamelott Soundboard</title>
<link rel="apple-touch-icon" sizes="57x57" href="/favicons/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/favicons/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/favicons/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/favicons/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/favicons/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon-180x180.png">
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicons/android-chrome-192x192.png" sizes="192x192">
<link rel="icon" type="image/png" href="/favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="/favicons/manifest.json">
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="/favicons/favicon.ico">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-TileImage" content="/favicons/mstile-144x144.png">
<meta name="msapplication-config" content="/favicons/browserconfig.xml">
<meta name="theme-color" content="#3f3552">
<link rel="manifest" href="manifest.json">
<link rel="apple-touch-icon" sizes="180x180" href="favicons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicons/favicon-16x16.png">
<link rel="mask-icon" href="favicons/safari-pinned-tab.svg" color="#18ae90">
<link rel="shortcut icon" href="favicons/favicon.ico">
<meta name="apple-mobile-web-app-title" content="Kaamelott Soundboard">
<meta name="application-name" content="Kaamelott Soundboard">
<meta name="msapplication-TileColor" content="#603cba">
<meta name="msapplication-config" content="favicons/browserconfig.xml">
<meta name="theme-color" content="#18ae90">
<link rel="stylesheet" href="/css/style.css" media="screen">
<link rel="stylesheet" href="css/style.css" media="screen">
</head>
<body>
<div id="wrapper">

View File

@@ -1,3 +0,0 @@
TrimSilence: threshold=-48.000000 min-start-silence=0.000000 min-end-silence=0.000000
Normalize: ApplyGain=yes RemoveDcOffset=yes Level=-1.000000 StereoIndependent=no
ExportMp3:

View File

@@ -1,8 +0,0 @@
# Utiliser Audacity pour uniformiser vos sons #
1. Installez [Audacity](https://sourceforge.net/projects/audacity/)
2. Installez l'encodeur [LAME MP3](http://manual.audacityteam.org/man/faq_installation_and_plug_ins.html#lame)
3. Installez l'extension [TrimSilence](http://wiki.audacityteam.org/wiki/Nyquist_Effect_Plug-ins#Trim_Silence)
4. Ajoutez le fichier [Chain](http://manual.audacityteam.org/man/edit_chains.html#Sharing_a_chain) suivant : `Audacity/Chains/NormalizeSounds.txt` dans le [répertoire de préférences de l'application](http://manual.audacityteam.org/man/preferences.html#stored)
5. Relancez l'application
6. Appliquez ce _Chain_ sur vos fichiers : _File > Apply Chain..._ puis sélectionnez _NormalizeSounds_ et enfin _Apply to files..._

182
CHANGELOG.md Normal file
View File

@@ -0,0 +1,182 @@
## 2020-01-12
### Arthur
* Livre II, 01 - Spangenhelm - [Il n'y a rien à prier on se souvient pas des mecs de toute façon](https://kaamelott-soundboard.2ec0b4.fr/#son/il-n-y-a-rien-a-prier)
* Livre II, 01 - Spangenhelm - [Bon de toute façon on vous demande de prier, vous priez, vous discutaillez pas des plombes du pourquoi du comment ! Commence à me gonfler léger ça aussi !](https://kaamelott-soundboard.2ec0b4.fr/#son/bon-de-toute-facon)
* Livre II, 01 - Spangenhelm - [Nan ça va pas être possible ça](https://kaamelott-soundboard.2ec0b4.fr/#son/nan-ca-va-pas-etre-possible-ca)
* Livre II, 02 - Les Alchimistes - [Allez quoi ! On a besoin d'une potion, on va pas la faire nous-même si ?](https://kaamelott-soundboard.2ec0b4.fr/#son/allez-quoi-on-a-besoin-dune-potion)
* Livre II, 03 - Le Dialogue de Paix - [Décarre tes troupes de chez moi ou je crame ton pays. C'est assez simple comme vocabulaire ça ?](https://kaamelott-soundboard.2ec0b4.fr/#son/decarre-tes-troupes-de-chez-moi-ou-je-crame-ton-pays)
* Livre II, 04 - Le Portrait - [Vous vous devriez arrêter de sourire parce que je vous promets ça devient vraiment malsain](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-vous-devriez-arreter-de-sourire)
* Livre II, 04 - Le Portrait - [Ah bah voilà, nan mais cherchez pas. Nan mais j'vous assure c'est hyper flippant](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-bah-voila-cherchez-pas-cest-hyper-flippant)
* Livre II, 04 - Le Portrait - [Oui peut-être oui oui...](https://kaamelott-soundboard.2ec0b4.fr/#son/oui-peut-etre-oui-oui)
* Livre II, 04 - Le Portrait - [Vous faites pas la gueule là ?](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-faites-pas-la-gueule-la)
* Livre II, 05 - Silbury Hill - [Mais c'est pas compliqué : quand vous voyez des gadins de 12 pieds de haut plantés en rond, figurez-vous qu'ils n'ont pas poussé dans la nuit](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-cest-pas-complique-quand-vous-voyez-des-gadins)
* Livre II, 06 - Le Reclassement - [Qu'est-ce que vous racontez ? C'est pas ça ! Simplement parce qu'on vous a vu de dos. Alors on s'est dit : \""qu'est-ce que c'est ? Tiens, on dirait un viking\""](https://kaamelott-soundboard.2ec0b4.fr/#son/quest-ce-que-vous-racontez-cest-pas-ca)
* Livre II, 06 - Le Reclassement - [Si on peut s'en farcir un ni vu ni connu, c'est toujours ça d'pris quoi... Oh pis on dira qu'c'est pas nous, allez !](https://kaamelott-soundboard.2ec0b4.fr/#son/si-on-peut-sen-farcir-un-cest-toujours-ca-de-pris-quoi)
* Livre II, 07 - Le Rassemblement du Corbeau - [Vous allez me promettre de pas y foutre les pieds !](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-allez-me-promettre-de-pas-y-foutre-les-pieds)
* Livre II, 07 - Le Rassemblement du Corbeau - [Sans déconner faut pas y aller demain](https://kaamelott-soundboard.2ec0b4.fr/#son/sans-deconner-faut-pas-y-aller-demain)
* Livre II, 07 - Le Rassemblement du Corbeau - [La blague est pas drôle !](https://kaamelott-soundboard.2ec0b4.fr/#son/la-blague-est-pas-drole)
* Livre II, 07 - Le Rassemblement du Corbeau - [Oh la vache, mais c'est nul !](https://kaamelott-soundboard.2ec0b4.fr/#son/oh-la-vache-mais-cest-nul)
* Livre II, 11 - Le Message Codé - [Il faut affranchir nos compagnons](https://kaamelott-soundboard.2ec0b4.fr/#son/il-faut-affranchir-nos-compagnons)
* Livre II, 12 - La Délégation Maure - [Euh... si il lâche une caisse ça l'fait ou pas ?](https://kaamelott-soundboard.2ec0b4.fr/#son/euh-si-il-lache-une-caisse-ca-le-fait-ou-pas)
* Livre II, 12 - La Délégation Maure - [C'est... personne, c'est... un connard. Asseyez-vous, je suis sûr qu'on va pouvoir trouver un accord](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-personne-un-connard)
* Livre II, 13 - L'Enlèvement de Guenièvre - [Qu'est-ce que vous voulez que ça me foute ?](https://kaamelott-soundboard.2ec0b4.fr/#son/quest-ce-que-vous-voulez-que-ca-me-foute)
* Livre II, 13 - L'Enlèvement de Guenièvre - [Ah putain ouais en fait vous m'avez fait lever pour rien](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-putain-ouais-en-fait-vous-mavez-fait-lever-pour-rien)
* Livre II, 15 - Le Monde d'Arthur - [Pfiou Pfiou Pfiou](https://kaamelott-soundboard.2ec0b4.fr/#son/pfiou-pfiou-pfiou)
* Livre II, 15 - Le Monde d'Arthur - [Boule de feu ! Boule de feu !](https://kaamelott-soundboard.2ec0b4.fr/#son/boule-de-feu-boule-de-feu)
* Livre II, 18 - Sept Cent Quarante-Quatre - [Nan c'est n'importe quoi](https://kaamelott-soundboard.2ec0b4.fr/#son/nan-cest-nimporte-quoi)
* Livre II, 18 - Sept Cent Quarante-Quatre - [C'est pour voir si vous avez un don ou si vous êtes définitivement un nullos](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-pour-voir-si-vous-avez-un-don)
* Livre II, 18 - Sept Cent Quarante-Quatre - [Qu'est-ce que je suis en train de faire avec mon doigt là ?](https://kaamelott-soundboard.2ec0b4.fr/#son/qu-est-ce-que-je-suis-en-train-de-faire-avec-mon-doigt)
* Livre II, 19 - L'absolution - [Attendez, que je me suis jamais quoi ? J'ai pas compris](https://kaamelott-soundboard.2ec0b4.fr/#son/attendez-que-je-me-suis-jamais-quoi)
* Livre II, 22 - Plus Près de Toi - [Merciiiii !](https://kaamelott-soundboard.2ec0b4.fr/#son/merciiiii)
* Livre II, 24 - Sous les Verrous - [Mais pas du tout !](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-pas-du-tout)
* Livre II, 24 - Sous les Verrous - [Mais je le sais bien que vous avez pas les clés ANDOUILLES ! Allez me chercher le geôlier](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-je-le-sais-bien-que-vous-avez-pas-les-cles-andouille)
* Livre II, 24 - Sous les Verrous - [Venez m'ouvrir !](https://kaamelott-soundboard.2ec0b4.fr/#son/venez-mouvriiir)
* Livre II, 24 - Sous les Verrous - [Allez bon Dieu mais magnez-vous ça pue là dedans !](https://kaamelott-soundboard.2ec0b4.fr/#son/allez-bon-dieu-mais-magnez-vous-ca-pue-la-dedans)
* Livre II, 24 - Sous les Verrous - [Parce que vous êtes en train de faire une connerie là quand même, moi je serais vous j'y penserais](https://kaamelott-soundboard.2ec0b4.fr/#son/parce-que-vous-etes-en-train-de-faire-une-connerie-la-quand-meme)
* Livre II, 27 - LAncien Temps - [Enfin, quand c'est demandé gentiment](https://kaamelott-soundboard.2ec0b4.fr/#son/enfin-quand-cest-demande-gentiment)
* Livre II, 27 - LAncien Temps - [Bon alors ? Combien il faut que je casque pour la fête aux pécores ?](https://kaamelott-soundboard.2ec0b4.fr/#son/bon-alors-combien-il-faut-que-casque-pour-la-fete-aux-pecores)
* Livre II, 27 - LAncien Temps - [Mais non, qu'est-ce que j'en ai à carrer](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-non-qu-est-ce-que-jen-ai-a-carrer)
* Livre II, 27 - LAncien Temps - [Ah ouais ! Vous m'adressez carrément plus la parole en fait ?](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-ouais-vous-madressez-carrement-plus-la-parole-en-fait)
* Livre II, 27 - LAncien Temps - [Elle me fixe aves ses yeux de serpent là](https://kaamelott-soundboard.2ec0b4.fr/#son/elle-me-fixe-avec-ses-yeux-de-serpent)
* Livre II, 28 - Le Passage Secret - [Non, on a fait 3 bornes. S'il vous plait, venez pas me parler de bout du monde](https://kaamelott-soundboard.2ec0b4.fr/#son/non-on-a-fait-3-bornes-sil-vous-plait)
* Livre II, 31 - LIvresse - [Et ça c'est du nougat !?](https://kaamelott-soundboard.2ec0b4.fr/#son/et-ca-cest-du-nougat)
* Livre II, 31 - LIvresse - [Les chevaliers de mes deux !](https://kaamelott-soundboard.2ec0b4.fr/#son/les-chevaliers-de-mes-deux)
* Livre II, 33 - Spiritueux - [Eh ben ? Eh ben voilà ! Cest bien pour la peine de rester huit jours. Cest alors donc : y en a pas un pour racheter lautre, cest dla merde, merci messieurs.](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-de-la-merde-merci-messieurs)
* Livre II, 33 - Spiritueux - [Non, il est dégueulasse celui là](https://kaamelott-soundboard.2ec0b4.fr/#son/non-il-est-degueulasse-celui-la)
* Livre II, 34 - La Ronde - [Est-ce que vous allez finir par fermer vos gueules ?](https://kaamelott-soundboard.2ec0b4.fr/#son/est-ce-que-vous-allez-finir-par-fermer-vos-gueules)
* Livre II, 34 - La Ronde - [Qu'est-ce que c'est qu'cette tisane ?](https://kaamelott-soundboard.2ec0b4.fr/#son/qu-est-ce-que-cest-cette-tisane)
* Livre II, 34 - La Ronde - [À la reine ? Pourquoi voulez-vous que je pense à la reine ? Je suis déjà à moitié crevé, j'ai assez de soucis comme ça](https://kaamelott-soundboard.2ec0b4.fr/#son/pourquoi-voulez-vous-que-je-pense-a-la-reine)
* Livre II, 35 - Merlin l'Archaïque - [Bah alors 884 charrettes de bouse](https://kaamelott-soundboard.2ec0b4.fr/#son/bah-alors-884-charrettes-de-bouses)
* Livre II, 35 - Merlin l'Archaïque - [Rien, ça fait rien, cassez-vous](https://kaamelott-soundboard.2ec0b4.fr/#son/rien-ca-fait-rien-cassez-vous)
* Livre II, 35 - Merlin l'Archaïque - [C'est pas du tout mon anniversaire](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-pas-du-tout-mon-anniversaire)
* Livre II, 38 - Le Larcin - [C'est plutôt du... c'est du... c'est, c'est de la daube quoi](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-de-la-daube)
* Livre II, 39 - La Rencontre - [Là c'est sûr que vu les tronches que vous tirez ça file pas tellement envie de faire la fiesta](https://kaamelott-soundboard.2ec0b4.fr/#son/la-cest-sur-vu-les-tronche-que-vous-tirez)
* Livre II, 41 - O'Brother - [Quoi ? Bah mon cochon vous manquez pas de cran !](https://kaamelott-soundboard.2ec0b4.fr/#son/quoi-bah-mon-cochon-vous-manquez-pas-de-cran)
* Livre II, 42 - La Fête du Printemps - [Non mais cest incroyable. Jai limpression de bouffer de la terre avec de la bouse et du gravier, ça sent le poulailler, mais cest du céleri et des oignons, cest prodigieux.](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-cest-incroyable-jai-limpression-de-bouffer-de-la-terre)
* Livre II, 42 - La Fête du Printemps - [Le plus intéressant cest : comment est-ce que vous arrivez à faire un truc aussi immonde avec des ingrédients normaux ?](https://kaamelott-soundboard.2ec0b4.fr/#son/le-plus-interessant-cest-comment-vous-arrivez-a-faire-un-truc-aussi-immonde)
* Livre II, 43 - La Voix Céleste - [Et bah tu peux te la garder !](https://kaamelott-soundboard.2ec0b4.fr/#son/et-bah-tu-peux-te-la-garder)
* Livre II, 43 - La Voix Céleste - [Ah non vous allez pas bouder ?!](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-non-vous-allez-pas-bouder)
* Livre II, 43 - La Voix Céleste - [Merde, là ! Ça vous va ça ?](https://kaamelott-soundboard.2ec0b4.fr/#son/merde-la-ca-vous-va-ca)
* Livre II, 43 - La Voix Céleste - [Mais vous guidez que dalle alors, vous êtes encore plus paumée que moi, venez pas me la jouer !](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-vous-guidez-que-dalle)
* Livre II, 45 - Amen - [Tu ne tueras point, comment on fait nous derrière ? Non cest comme ça. Cest, voilà, cest un peu, tu ne tueras point, voilà. Bon allez on y va.](https://kaamelott-soundboard.2ec0b4.fr/#son/tu-ne-tuera-point)
* Livre II, 46 - Le Cadeau - [La chèvre elle a bêlé 5 minutes. Vous, vous râlez depuis 3h. Pensez-y](https://kaamelott-soundboard.2ec0b4.fr/#son/la-chevre-a-beler-5-min)
* Livre II, 50 - Always - [Mais vous êtes pas mort espèce de connard ?!](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-vous-etes-pas-mort-espece-de-connard)
* Livre II, 50 - Always - [Le seigneur Perceval ne se met jamais en situation dangeureuse. Pour ça il fait preuve d'une intelligence redoutable](https://kaamelott-soundboard.2ec0b4.fr/#son/le-seigneur-perceval-ne-se-met-jamais-en-situation-dangeureuse)
* Livre II, 97 - La Conscience d'Arthur - [Vous êtes un gros nul, d'accord ? Un vrai gros naze](https://kaamelott-soundboard.2ec0b4.fr/#son/vous_etes_un_gros_nul)
### Belt le vigneron
* Livre II, 33 - Spiritueux - [Nous on foule le fruit avec nos propres pieds](https://kaamelott-soundboard.2ec0b4.fr/#son/nous-on-foule-le-fruit-avec-nos-propres-pieds)
* Livre II, 33 - Spiritueux - [Mais cest dl… dla merde ! Enfin euh… Sire, est-ce quon est obligés de perdre du temps avec tous les pignoufs dla région qui sprennent pour des exploitants ?](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-cest-de-la-merde)
* Livre II, 33 - Spiritueux - [Vous avez pas pris le temps de vous habituer au fruit](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-avez-pas-pris-le-temps-de-vous-habituer-au-fruit)
### Bohort
* Livre II, 14 - Les Classes de Bohort - [C'est un scandale !](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-un-scandale)
* Livre II, 38 - Le Larcin - [Quoi ?! Mais c'est un scandale !](https://kaamelott-soundboard.2ec0b4.fr/#son/quoi-mais-cest-un-scandale)
* Livre II, 44 - LInvincible - [Notre enchanteur m'informe que d'habitude il y arrive très bien mais que là, visiblement, ça marche pas !](https://kaamelott-soundboard.2ec0b4.fr/#son/notre-enchanteur-minforme-que-dhabitude-il-y-arrive-tres-bien)
### Dame Séli
* Livre II, 03 - Le Dialogue de Paix - [C'est pas du Burgonde ça](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-pas-du-burgonde-ca)
* Livre II, 20 - Les Misanthropes - [Il n'y a pas d'équivoque, vous êtes franchement un bourrin en toute circonstance](https://kaamelott-soundboard.2ec0b4.fr/#son/il-n-y-a-pas-dequivoque-vous-etes-franchement-un-bourrin)
* Livre II, 25 - Séli et les Rongeurs - [Et celle-là j'irai pas me coucher avant de l'avoir BOU-SI-LLÉE](https://kaamelott-soundboard.2ec0b4.fr/#son/et-celle-la-jirai-pas-me-coucher-avant-de-lavoir-bousillee)
* Livre II, 39 - La Rencontre - [Alors oisif, obèse, autant dire des gros cons](https://kaamelott-soundboard.2ec0b4.fr/#son/alors-oisif-obese-autant-dire-des-gros-cons)
* Livre II, 39 - La Rencontre - [Oh non mais il y a vraiment des jours où vous déconnez sec](https://kaamelott-soundboard.2ec0b4.fr/#son/oh-non-mais-il-y-a-des-jours-vous-deconnez-sec)
### Guenièvre
* Livre II, 35 - Merlin l'Archaïque - [Allez, je m'occupe de tout. Dites oui ! Dites oui ! Dites oui !](https://kaamelott-soundboard.2ec0b4.fr/#son/je-moccupe-de-tout-dite-oui)
* Livre II, 37 - LEscorte II - [Vous me prenez vraiment pour une conne](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-me-prenez-vraiment-pour-une-conne)
* Livre II, 37 - LEscorte II - [Qu'est ce que c'est ce nouveau genre seigneur Lancelot, vous oubliez peut-être que vous parlez à des GROSSES BOURGES !](https://kaamelott-soundboard.2ec0b4.fr/#son/quest-ce-que-cest-ce-nouveau-genre-seigneur-lancelot)
### Guethenoc
* Livre II, 33 - Spiritueux - [Nan mais quand même, non quand même, on vient pour essayer montrer quelque chose de sérieux, vous arrivez avec du jus de pieds, faut pas exagérer non plus](https://kaamelott-soundboard.2ec0b4.fr/#son/nan-mais-quand-meme)
### Kadoc
* Livre II, 41 - O'Brother - [Comme la mare aux canards ?](https://kaamelott-soundboard.2ec0b4.fr/#son/comme-la-mare-aux-canards)
* Livre II, 41 - O'Brother - [Jai le droit dêtre 4 jours pas chez moi... et après chez moi. Mais y a du voyage qui se prépare et euh, pour soigner les bêtes, y a pas que ma tante, y a moi aussi](https://kaamelott-soundboard.2ec0b4.fr/#son/jai-le-droit-detre-4-jours-pas-chez-moi)
### Karadoc
* Livre II, 02 - Les Alchimistes - [On est indestructible](https://kaamelott-soundboard.2ec0b4.fr/#son/on-est-indestructible)
* Livre II, 10 - La Chambre - [Mocheté en plus quand on voit le morceau qu'il se trimballe](https://kaamelott-soundboard.2ec0b4.fr/#son/mochete-en-plus-quand-on-voit-le-morceau-quil-se-trimballe)
* Livre II, 18 - Sept Cent Quarante-Quatre - [Ah une vache près hein, c'est pas une science exacte](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-une-vache-pres-cest-pas-une-science-exacte)
* Livre II, 18 - Sept Cent Quarante-Quatre - [Je vous ai toujours dit : ce que vous faites avec les chiffres, même moi j'arrive pas à l'faire](https://kaamelott-soundboard.2ec0b4.fr/#son/je-vous-ai-toujours-dit-ce-que-vous-faites-avec-les-chiffres)
* Livre II, 18 - Sept Cent Quarante-Quatre - [Il est fort le salaud](https://kaamelott-soundboard.2ec0b4.fr/#son/il-est-fort-le-salaud)
* Livre II, 33 - Spiritueux - [Le vôtre aussi c'est de la merde](https://kaamelott-soundboard.2ec0b4.fr/#son/le-votre-aussi-cest-de-la-merde)
* Livre II, 33 - Spiritueux - [C'est de la merde 2](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-de-la-merde)
### Lancelot
* Livre II, 30 - La Garde Royale - [Mais qu'est-ce que vous voulez qu'on en foute de vos peigne-culs ?](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-qu-est-ce-que-vous-voulez-quon-en-foute-de-vos-peigne-culs)
### Le Maître d'armes
* Livre II, 14 - Les Classes de Bohort - [Seigneur Bohort, je commence à en avoir plein le dos de votre comportement de péteux ! Vous allez me faire le plaisir de me faire une bonne insulte et de vous foutre en rogne une bonne fois pour toutes !](https://kaamelott-soundboard.2ec0b4.fr/#son/seigneur-bohort-je-commence-a-en-avoir-plein-le-dos)
* Livre II, 14 - Les Classes de Bohort - [Mais allez-y bon sang, magnez-vous le fion espèce de grosse dinde !](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-allez-y-magnez-vous-le-fion-espece-de-grosse-dinde)
* Livre II, 14 - Les Classes de Bohort - [Mais allez-y c'est pour vous stimuler, bon Dieu !](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-allez-y-cest-pour-vous-stimuler-bon-dieu)
* Livre II, 14 - Les Classes de Bohort - [Vous allez me montrer un peu ce que vous avez dans l'froc, ma mignonne !](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-allez-me-montrer-ce-que-vous-avez-un-peu-dans-le-froc)
* Livre II, 14 - Les Classes de Bohort - [Allez en garde espèce de petite couille molle !](https://kaamelott-soundboard.2ec0b4.fr/#son/allez-en-garde-espece-de-petite-couille-molle)
### Le tavernier
* Livre II, 11 - Le Message Codé - [Ça ça doit être du code parce que ça veut rien dire](https://kaamelott-soundboard.2ec0b4.fr/#son/ca-ca-doit-etre-du-code-parce-que-ca-veut-rien-dire)
* Livre II, 37 - LEscorte II - [Entre le roi Arthur qu'est pas capable de dénicher son Graal et la reine qu'est con comme une chaise !](https://kaamelott-soundboard.2ec0b4.fr/#son/entre-le-roi-arthur-quest-pas-capable-de-denicher-son-graal)
* Livre II, 37 - LEscorte II - [J'sais pas si c'est d'naissance ou quoi mais moi, la vue du bourgeois, ça m'fait d'l'aérophagie.](https://kaamelott-soundboard.2ec0b4.fr/#son/la-vue-du-bourgeois-ca-me-fait-de-laerophagie)
### Léodagan
Livre II, 04 - Le Portrait";"[Moi pour qu'on me reconnaisse faut juste 2-3 coups de pinceaux mais vous...](https://kaamelott-soundboard.2ec0b4.fr/#son/moi-pour-quon-me-reconnaisse-faut-juste-2-3-coups-de-pinceaux)"
* Livre II, 04 - Le Portrait - [C'est l'autre con là avec ses pinceaux](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-l-autre-con-avec-ses-pinceaux)
* Livre II, 04 - Le Portrait - [Mais qu'est-ce que vous venez me gonfler avec votre père Blaise !](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-qu-est-ce-que-vous-venez-me-gonfler-avec-votre-pere-blaise)
* Livre II, 05 - Silbury Hill - [Biensûr ! Ils ont qu'ça à foutre les paysans ! Bousiller les champs de blés pour dessiner des cercles !](https://kaamelott-soundboard.2ec0b4.fr/#son/biensur-ils-ont-que-ca-a-foutre-les-paysans)
* Livre II, 05 - Silbury Hill - [Oh bah oui vous en êtes une belle vous d'forme d'urticaire](https://kaamelott-soundboard.2ec0b4.fr/#son/oh-bah-oui-vous-en-etes-une-belle-forme-durticaire)
* Livre II, 06 - Le Reclassement - [Ah ça, quand on connait pas, il faut se méfier avec les champignons](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-ca-quand-on-connait-pas-il-faut-se-mefier-avec-les-champignons)
* Livre II, 09 - Le Terroriste - [Pas moyen de lui faire fermer sa gueule](https://kaamelott-soundboard.2ec0b4.fr/#son/pas-moyen-de-lui-faire-fermer-sa-gueule)
* Livre II, 10 - La Chambre - [Ah c'est réglé hein, je confirme ! En ce moment, il range ses slibards dans ma commode](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-cest-regle-hein-je-confirme)
* Livre II, 16 - Les Tuteurs - [Peut-être même qu'il faut que je mette une armure, ils sont capables de pas me reconnaître et d'essayer de me buter !](https://kaamelott-soundboard.2ec0b4.fr/#son/peut-etre-meme-que-je-mette-une-armure)
* Livre II, 16 - Les Tuteurs - [Des bêtes sauvages que je vais récupérer, des machines à tuer](https://kaamelott-soundboard.2ec0b4.fr/#son/des-betes-sauvages-que-je-vais-recuperer)
* Livre II, 21 - La Cassette - [Ah bah c'est sûr on se marre](https://kaamelott-soundboard.2ec0b4.fr/#son/ah-bah-cest-sur-on-se-marre)
* Livre II, 25 - Séli et les Rongeurs - [Non mais vous pouvez la distraire avec un numéro de jonglage vous la toucherez pas avec ça !](https://kaamelott-soundboard.2ec0b4.fr/#son/non-mais-vous-pouvez-la-distraire-avec-un-numero-de-jonglage)
* Livre II, 25 - Séli et les Rongeurs - [Non mais biensûr. Donc vous, vous dégommez les souris au maillet ?](https://kaamelott-soundboard.2ec0b4.fr/#son/non-mais-biensur-donc-vous-vous-degommez-les-souris-au-maillet)
* Livre II, 28 - Le Passage Secret - [Vous savez c'est pas parce qu'un vieux moisi vient vous baver dans les étagère que ça vaut forcément quelque chose !](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-savez-cest-pas-parce-quun-vieux-moisi)
* Livre II, 31 - LIvresse - [En fait, j'étais dans un pâturage, j'ai tué 76 chèvres](https://kaamelott-soundboard.2ec0b4.fr/#son/en-fait-jetais-dans-un-paturage)
* Livre II, 33 - Spiritueux - [C'est une blague ?](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-une-blague)
* Livre II, 40 - Les Pigeons - [Vous pouvez aller vous gratter. C'est signé... ah non mais c'est moi ça !](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-pouvez-aller-vous-gratter)
* Livre II, 41 - O'Brother - [Pas moyen de piger un broc de ce qu'il dit](https://kaamelott-soundboard.2ec0b4.fr/#son/pas-moyen-de-piger-un-broc-de-ce-quil-dit)
* Livre II, 42 - La Fête du Printemps - [Vous me dites il faut quelque chose de festif](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-me-dites-il-faut-quelque-chose-de-festif)
### Merlin
* Livre II, 07 - Le Rassemblement du Corbeau - [Mais évidemment c'est sans alcool !](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-evidemment-cest-sans-alcool)
* Livre II, 20 - Les Misanthropes - [Franchement, une potion pour faire pisser bleu ça pressait à la minute là ?](https://kaamelott-soundboard.2ec0b4.fr/#son/franchement-une-potion-pour-faire-pisser-bleu)
* Livre II, 44 - LInvincible - [Remarquez j'ai un pote poissonier qui sait boire du lait à la paille par les trous de nez](https://kaamelott-soundboard.2ec0b4.fr/#son/remarquez-jai-un-pote-poissonier)
### Perceval
* Livre II, 02 - Les Alchimistes - [Mais comparé à ce qu'on a trouvé, la potion de puissance ça vaut de la pisse](https://kaamelott-soundboard.2ec0b4.fr/#son/mais-compare-a-ce-quon-a-trouve)
* Livre II, 02 - Les Alchimistes - [Arrêtez, c'est pour déconner !](https://kaamelott-soundboard.2ec0b4.fr/#son/arretez-cest-pour-deconner)
* Livre II, 02 - Les Alchimistes - [Ouais, c'est grâce à notre arme secrète !](https://kaamelott-soundboard.2ec0b4.fr/#son/ouais-cest-grace-a-notre-arme-secrete)
* Livre II, 02 - Les Alchimistes - [Bah on a pas de technique mais c'est comme tout, faut avoir du... voyez](https://kaamelott-soundboard.2ec0b4.fr/#son/bah-on-a-pas-de-technique-mais-cest-comme-tout)
* Livre II, 02 - Les Alchimistes - [Allez-y vous sentez là, il faut oser se lancer sinon vous progresserez jamais](https://kaamelott-soundboard.2ec0b4.fr/#son/allez-y-vous)
* Livre II, 02 - Les Alchimistes - [Vous en mettez pas trop](https://kaamelott-soundboard.2ec0b4.fr/#son/vous-en-mettez-pas-trop)
* Livre II, 02 - Les Alchimistes - [Donc cette fiole, selon comme elle pue, on dit qu'elle est plutôt bonne et faut pas trop en mettre](https://kaamelott-soundboard.2ec0b4.fr/#son/donc-cette-fiole)
* Livre II, 02 - Les Alchimistes - [Qu'est-ce qu'il y a d'autre qui pue sinon ?](https://kaamelott-soundboard.2ec0b4.fr/#son/qu-est-ce-qui-a-dautre-qui-pue-sinon)
* Livre II, 08 - Les Volontaires II - [Par contre il est hyper con, j'sais pas pourquoi](https://kaamelott-soundboard.2ec0b4.fr/#son/par-contre-il-est-hyper-con-je-sais-pas-pourquoi)
* Livre II, 08 - Les Volontaires II - [Salut sire ! Je trouve qu'il fait beau mais encore frais, mais beau](https://kaamelott-soundboard.2ec0b4.fr/#son/salut-sire-je-trouve-quil-fait-beau-mais-encore-frais-mais-beau)
* Livre II, 18 - Sept Cent Quarante-Quatre - [De toutes façons les réunions de la table ronde, cest deux fois par mois ! Donc si le mec il dit : après-demain, à partir de dans deux jours, suivant sil le dit à la fin du mois ça reporte.](https://kaamelott-soundboard.2ec0b4.fr/#son/de-toute-facon-les-reunions-cest-2-fois-par-mois)
* Livre II, 18 - Sept Cent Quarante-Quatre - [Bah ça dépend à partir de quand. Après-demain à partir d'aujourd'hui ?](https://kaamelott-soundboard.2ec0b4.fr/#son/bah-ca-depend-a-partir-de-quand)
* Livre II, 18 - Sept Cent Quarante-Quatre - [Nan nan mais en vrai, pas sur la carte, je comprends rien aux cartes](https://kaamelott-soundboard.2ec0b4.fr/#son/nan-mais-en-vrai-pas-sur-la-carte)
* Livre II, 20 - Les Misanthropes - [Ah non, mais nous, on nest pas fixé ! On propose ça, cqui compte cest que ce soit un peu marrant, quoi ! Et pis pour vous, ça va vous faire rigoler un peu ! Cest pas bon drester enfermé dans votre cagibi à glander toute la journée](https://kaamelott-soundboard.2ec0b4.fr/#son/nan-nan-nous-on-est-pas-fixe)
* Livre II, 25 - Séli et les Rongeurs - [C'est marrant les petits bouts de fromage par terre, c'est ça que vous appelez une fondue ?](https://kaamelott-soundboard.2ec0b4.fr/#son/cest-marrant-les-petits-bouts-de-fromage-par-terre)
* Livre II, 29 - Les Mauvaises Graines - [Ils commencent par apprendre à lire, comme ils savent pas s'arrêter crac, ils apprennent à écrire, et voilà](https://kaamelott-soundboard.2ec0b4.fr/#son/ils-commencent-par-apprendre-a-lire)
* Livre II, 29 - Les Mauvaises Graines - [Insoupçonnable !](https://kaamelott-soundboard.2ec0b4.fr/#son/insoupconnable)
* Livre II, 30 - La Garde Royale - [Nan mais par contre, ils sont super cons !](https://kaamelott-soundboard.2ec0b4.fr/#son/nan-mais-par-contre-ils-sont-super-cons)
* Livre II, 36 - Les Exploités - [La tournure est plus graduelle](https://kaamelott-soundboard.2ec0b4.fr/#son/la-tournure-est-plus-graduelle)
* Livre II, 36 - Les Exploités - [Ah mais moi franchement, je serais nous. Non. Je serais vous, jvous écouterais.](https://kaamelott-soundboard.2ec0b4.fr/#son/non-mais-franchement-je-serais-nous-je-vous-ecouterais)
* Livre II, 36 - Les Exploités - [Maintenant il faut nous écouter ! Parce que là on en a gros](https://kaamelott-soundboard.2ec0b4.fr/#son/maintenant-il-faut-nous-ecouter-parce-que-la-on-en-a-gros)
* Livre II, 36 - Les Exploités - [Moi, j'serais vous, je vous écouterais](https://kaamelott-soundboard.2ec0b4.fr/#son/moi-je-serais-vous-je-vous-ecouterais)
* Livre II, 36 - Les Exploités - [Faites pas le con sire, ouvrez !](https://kaamelott-soundboard.2ec0b4.fr/#son/faites-pas-le-con-sire-ouvrez)
* Livre II, 41 - O'Brother - [Bah, Karadoc cest le gars brillant, quoi... le frère à côté cest sûr, euh... cest vraiment un gros con](https://kaamelott-soundboard.2ec0b4.fr/#son/karadoc-cest-le-gars-brillant)
* Livre II, 86 - Les Félicitations - [C'est l'anniversaire dans tous les recoins, c'est presque tous les ans qu'on a l'anniversaire, grâce à cet anni, c'est la joie, c'est pratique, c'est au moins un principe à retenir pour faire la frite, lalala, cette année c'est bien l'anniversaire tombe à pic !](https://kaamelott-soundboard.2ec0b4.fr/#son/cest_lanniversaire_dans_tous_les_recoins)
### Père Blaise
* Livre II, 30 - La Garde Royale - [Donc vous allez faire une troupe d'élite avec vos cousins débiles ?](https://kaamelott-soundboard.2ec0b4.fr/#son/donc-vous-allez-faire-une-troupe-delite-avec-vos-cousins-debiles)
* Livre II, 45 - Amen - [ON PISSE PAS CONTRE LES MURS DE LA CHAPELLE C'EST CLAIR !](https://kaamelott-soundboard.2ec0b4.fr/#son/on-pisse-pas-contre-les-murs-de-la-chapelle-cest-clair)
### Ygerne de Tintagel
* Livre II, 39 - La Rencontre - [Évitez de m'appeler maman !](https://kaamelott-soundboard.2ec0b4.fr/#son/evitez-de-mappeler-maman)
### Yvain
* Livre II, 16 - Les Tuteurs - [Et moi je me suis fait dérober de l'alimentation tout le long du voyage une véritable dérobade !](https://kaamelott-soundboard.2ec0b4.fr/#son/et-moi-je-me-suis-fait-derober-de-lalimentation-tout-le-long-du-voyage)

View File

@@ -1,2 +0,0 @@
FROM httpd:2.4
COPY . /usr/local/apache2/htdocs/

14
Makefile Executable file
View File

@@ -0,0 +1,14 @@
init:
docker build -t ks-base .docker/base
install:
docker-compose -f docker-compose.builder.yml run --rm install
start:
docker run -dit --rm --name ks-server -p 8000:80 -v `pwd`:/usr/local/apache2/htdocs/ httpd:2.4
stop:
docker stop ks-server
build:
docker-compose -f docker-compose.builder.yml run --rm build

View File

@@ -8,13 +8,13 @@ Alors, c'est classe ou c'est pas classe ? Ou c'est classe ?
## Lancer le projet ##
Pour faire fonctionner le projet sur votre machine, vous devrez tout d'abord, depuis la racine, exécuter la commande `bower install` puis accéder au fichier `index.html` via le serveur Web de votre choix (Apache pour moi, quand je ne suis pas sioux et que je ne m'y prends pas comme un commanche). Pour cela vous pouvez utiliser [Docker](https://www.docker.com/) avec les 2 commandes suivantes :
Pour faire fonctionner le projet sur votre machine, vous devrez tout d'abord, depuis la racine, exécuter la commande `bower install` puis accéder au fichier `index.html` via le serveur Web de votre choix (Apache pour moi, quand je ne suis pas sioux et que je ne m'y prends pas comme un commanche). Sinon vous pouvez aussi utiliser [Docker](https://www.docker.com/) avec les commandes suivantes :
```bash
docker build -t 2ec0b4/kaamelott-soundboard .
docker run -it --rm --name kaamelott-soundboard -p 80:80 -t 2ec0b4/kaamelott-soundboard
make init
make install
make start
```
+ Pour les utilisateurs Windows 10 : Rendez-vous sur la page [http://localhost]()
+ Pour les utilisateurs Windows 7 : Rendez-vous sur la page [http://192.168.99.100]()
(cf. le fichier `Makefile`)
Whoooohoooo woa c'est mortel !
@@ -23,15 +23,19 @@ Whoooohoooo woa c'est mortel !
1. Scissionnez (cf. [Fork](http://bitoduc.fr/#F)) ce dépôt
2. Créez une nouvelle branche (`git checkout -b sons-qui-envoient-du-pate`)
3. Ajoutez vos sons (format _mp3_) dans le répertoire `sounds/` et référencez-les dans le fichier `sounds/sounds.json`
4. Idéalement, vous pouvez [utiliser Audacity pour uniformiser vos sons](https://github.com/2ec0b4/kaamelott-soundboard/blob/master/Audacity/README.md)
5. Enregistrez les modifications (`git commit -am "Mes sons qui envoient du paté"`)
6. Poussez vos modifications (`git push origin head`)
7. Créez une [fusiodemande](https://github.com/2ec0b4/kaamelott-soundboard/pulls)
4. Indexez vos modifications (`git add -A`)
4. Enregistrez les modifications (`git commit -m "Mes sons qui envoient du paté"`)
5. Poussez vos modifications (`git push origin head`)
6. Créez une [fusiodemande](https://github.com/2ec0b4/kaamelott-soundboard/pulls)
7. Patientez 😇
## Liens ##
* [Reddit](https://www.reddit.com/r/france/comments/5orvyf/kaamelott_soundboard_3/)
* [Application iOS](https://github.com/tnducrocq/kaamelott-sound-board-ios)
* [Visualisation graphique des répliques du _soundboard_](https://github.com/aluriak/kaamelott-soundboard-viz)
* [Application Android](https://gitlab.com/astran/kaamelottsb) pas encore sur le store mais il y a un [lien pour l'apk de dev](https://gitlab.com/astran/kaamelottsb/-/jobs/artifacts/master/raw/app/build/outputs/apk/debug/app-debug.apk?job=assembleDebug)
* [Bot Telegram](https://github.com/klmp200/kaamelott-soundboard-telegram-bot)
* [VoiceBot](https://github.com/scastrec/kaamelottvoice) Pour l'instant, uniquement Alexa, mais déclinable rapidement en Google Assistant si demandes
Merci, de rien, au revoir m'sieur dame

View File

@@ -24,7 +24,6 @@
"backbone.radio": "^1.0.5",
"handlebars": "^4.0.5",
"jquery": "^2.2.4",
"ilyabirman-likely": "^2.1.0",
"require-css": "^0.1.8",
"require-handlebars-plugin": "^1.0.0",
"requirejs": "^2.2.0",

View File

@@ -0,0 +1,16 @@
version: '2'
services:
base:
image: ks-base
volumes:
- .:/app/
working_dir: /app/
install:
extends:
service: base
command: bash -c "npm install && bower install --allow-root"
build:
extends:
service: base
command: bash -c "gulp init && gulp build"

1
docs/.nojekyll Normal file
View File

@@ -0,0 +1 @@

45
docs/404.html Normal file
View File

@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="fr-fr">
<head>
<meta charset="utf-8">
<meta name="description" content="Quelques-unes des meilleures répliques sonores de Kaamelott. C'était ça ou chante Sloubi.">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<title>Kaamelott Soundboard</title>
<link rel="manifest" href="manifest.b5671402.json">
<link rel="apple-touch-icon" sizes="180x180" href="favicons/apple-touch-icon.d47a8919.png">
<link rel="icon" type="image/png" sizes="32x32" href="favicons/favicon-32x32.0489ef7a.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicons/favicon-16x16.5ed47bb5.png">
<link rel="mask-icon" href="favicons/safari-pinned-tab.165c1e3e.svg" color="#18ae90">
<link rel="shortcut icon" href="favicons/favicon.ico">
<meta name="apple-mobile-web-app-title" content="Kaamelott Soundboard">
<meta name="application-name" content="Kaamelott Soundboard">
<meta name="msapplication-TileColor" content="#603cba">
<meta name="msapplication-config" content="favicons/browserconfig.bbbd9568.xml">
<meta name="theme-color" content="#18ae90">
<link rel="stylesheet" href="css/style.9d756833.css" media="screen">
</head>
<body>
<div id="wrapper">
<header class="site-header" role="banner">
<h1>Kaamelott Soundboard</h1>
</header>
<main id="main" class="site-main" role="main">
<div id="error404">
<div class="video-wrapper">
<iframe width="420" height="315" src="https://www.youtube.com/embed/2eLNWtjxZK4?autoplay=1" frameborder="0" allowfullscreen></iframe>
</div>
<p>
La page est introuvable, on sonne la retraite. RETRAITE !!!<br/>
<a href="/">Retour à l'accueil</a>
</p>
</div>
</main>
</div>
</body>
</html>

1
docs/CNAME Normal file
View File

@@ -0,0 +1 @@
kaamelott-soundboard.2ec0b4.fr

View File

@@ -0,0 +1,48 @@
{
"name": "backbone.babysitter",
"version": "0.1.12",
"homepage": "https://github.com/marionettejs/backbone.babysitter",
"authors": [
"Derick Bailey <derickbailey@gmail.com>"
],
"description": "Manage child views in a Backbone.View",
"main": "lib/backbone.babysitter.js",
"keywords": [
"backbone",
"plugin",
"computed",
"field",
"model",
"client",
"browser"
],
"dependencies": {
"backbone": ">=0.9.9 <=1.3.x",
"underscore": ">=1.4.0 <=1.8.3"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"public",
"specs",
".gitignore",
".jshintrc",
".travis.yml",
"Gruntfile.js",
"component.json",
"package.json"
],
"_release": "0.1.12",
"_resolution": {
"type": "version",
"tag": "v0.1.12",
"commit": "e21524f2fd5164d2fb7a48c3c12d14c22175af4d"
},
"_source": "https://github.com/marionettejs/backbone.babysitter.git",
"_target": "^0.1.0",
"_originalSource": "backbone.babysitter"
}

View File

@@ -0,0 +1,83 @@
# Change log
### v0.1.12
* Bump version range of backbone support.
### v0.1.11
* Bump version range of backbone support.
### v0.1.10
* Bump version range of backbone support.
### v0.1.9
* Bump version range of backbone support.
### v0.1.8
* Bump version range of backbone and underscore support.
### v0.1.7
* Bump version range of backbone support.
### v0.1.6
* Expose `reduce` to babysitter collections. Thanks @romanbsd
### v0.1.5
* Minor updates to bower.json
### v0.1.4
* Update UMD Wrapper and build process
### v0.1.2
* Add .VERSION and n.oConflict
* General cleanups to tests and package.json
* Add travis build info
### v0.1.1
* Remove AMD builds and replace with a single UMD style wrapper.
### v0.1.0
* allow chaining of add and remove methods
* add component.json
#### General
* update grunt file
* readme fixed
* fix gruntfile url
### v0.0.6
* Removed `.findByCollection` method
* Added `.findByModelCid` method
### v0.0.5
* Updated build process to use GruntJS v0.4
### v0.0.4
* Added a fix for IE < 9, when applying a function to the views
* Added `.pluck` as a method, from Underscore.js
* Can specify an array of views to the container constructor
### v0.0.3
* Added iterators and other collection processing functions from Underscore.js
### v0.0.2
* Added `.length` attribute
* Added `.findByIndex` method
### v0.0.1
* Initial release

View File

@@ -0,0 +1,5 @@
# Backbone.BabySitter
Copyright (C)2013 Derick Bailey, Muted Solutions, LLC
Distributed Under [MIT License](http://mutedsolutions.mit-license.org/)

View File

@@ -0,0 +1,39 @@
{
"name": "backbone.babysitter",
"version": "0.1.11",
"homepage": "https://github.com/marionettejs/backbone.babysitter",
"authors": [
"Derick Bailey <derickbailey@gmail.com>"
],
"description": "Manage child views in a Backbone.View",
"main": "lib/backbone.babysitter.js",
"keywords": [
"backbone",
"plugin",
"computed",
"field",
"model",
"client",
"browser"
],
"dependencies": {
"backbone": ">=0.9.9 <=1.3.x",
"underscore": ">=1.4.0 <=1.8.3"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"public",
"specs",
".gitignore",
".jshintrc",
".travis.yml",
"Gruntfile.js",
"component.json",
"package.json"
]
}

View File

@@ -0,0 +1,190 @@
// Backbone.BabySitter
// -------------------
// v0.1.11
//
// Copyright (c)2016 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
//
// http://github.com/marionettejs/backbone.babysitter
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['backbone', 'underscore'], function(Backbone, _) {
return factory(Backbone, _);
});
} else if (typeof exports !== 'undefined') {
var Backbone = require('backbone');
var _ = require('underscore');
module.exports = factory(Backbone, _);
} else {
factory(root.Backbone, root._);
}
}(this, function(Backbone, _) {
'use strict';
var previousChildViewContainer = Backbone.ChildViewContainer;
// BabySitter.ChildViewContainer
// -----------------------------
//
// Provide a container to store, retrieve and
// shut down child views.
Backbone.ChildViewContainer = (function (Backbone, _) {
// Container Constructor
// ---------------------
var Container = function(views){
this._views = {};
this._indexByModel = {};
this._indexByCustom = {};
this._updateLength();
_.each(views, this.add, this);
};
// Container Methods
// -----------------
_.extend(Container.prototype, {
// Add a view to this container. Stores the view
// by `cid` and makes it searchable by the model
// cid (and model itself). Optionally specify
// a custom key to store an retrieve the view.
add: function(view, customIndex){
var viewCid = view.cid;
// store the view
this._views[viewCid] = view;
// index it by model
if (view.model){
this._indexByModel[view.model.cid] = viewCid;
}
// index by custom
if (customIndex){
this._indexByCustom[customIndex] = viewCid;
}
this._updateLength();
return this;
},
// Find a view by the model that was attached to
// it. Uses the model's `cid` to find it.
findByModel: function(model){
return this.findByModelCid(model.cid);
},
// Find a view by the `cid` of the model that was attached to
// it. Uses the model's `cid` to find the view `cid` and
// retrieve the view using it.
findByModelCid: function(modelCid){
var viewCid = this._indexByModel[modelCid];
return this.findByCid(viewCid);
},
// Find a view by a custom indexer.
findByCustom: function(index){
var viewCid = this._indexByCustom[index];
return this.findByCid(viewCid);
},
// Find by index. This is not guaranteed to be a
// stable index.
findByIndex: function(index){
return _.values(this._views)[index];
},
// retrieve a view by its `cid` directly
findByCid: function(cid){
return this._views[cid];
},
// Remove a view
remove: function(view){
var viewCid = view.cid;
// delete model index
if (view.model){
delete this._indexByModel[view.model.cid];
}
// delete custom index
_.any(this._indexByCustom, function(cid, key) {
if (cid === viewCid) {
delete this._indexByCustom[key];
return true;
}
}, this);
// remove the view from the container
delete this._views[viewCid];
// update the length
this._updateLength();
return this;
},
// Call a method on every view in the container,
// passing parameters to the call method one at a
// time, like `function.call`.
call: function(method){
this.apply(method, _.tail(arguments));
},
// Apply a method on every view in the container,
// passing parameters to the call method one at a
// time, like `function.apply`.
apply: function(method, args){
_.each(this._views, function(view){
if (_.isFunction(view[method])){
view[method].apply(view, args || []);
}
});
},
// Update the `.length` attribute on this container
_updateLength: function(){
this.length = _.size(this._views);
}
});
// Borrowing this code from Backbone.Collection:
// http://backbonejs.org/docs/backbone.html#section-106
//
// Mix in methods from Underscore, for iteration, and other
// collection related features.
var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
'select', 'reject', 'every', 'all', 'some', 'any', 'include',
'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
'last', 'without', 'isEmpty', 'pluck', 'reduce'];
_.each(methods, function(method) {
Container.prototype[method] = function() {
var views = _.values(this._views);
var args = [views].concat(_.toArray(arguments));
return _[method].apply(_, args);
};
});
// return the public API
return Container;
})(Backbone, _);
Backbone.ChildViewContainer.VERSION = '0.1.11';
Backbone.ChildViewContainer.noConflict = function () {
Backbone.ChildViewContainer = previousChildViewContainer;
return this;
};
return Backbone.ChildViewContainer;
}));

View File

@@ -0,0 +1 @@
{"version":3,"sources":["?"],"names":["root","factory","define","amd","Backbone","_","exports","require","module","this","previousChildViewContainer","ChildViewContainer","Container","views","_views","_indexByModel","_indexByCustom","_updateLength","each","add","extend","prototype","view","customIndex","viewCid","cid","model","findByModel","findByModelCid","modelCid","findByCid","findByCustom","index","findByIndex","values","remove","any","key","call","method","apply","tail","arguments","args","isFunction","length","size","methods","concat","toArray","VERSION","noConflict"],"mappings":"CASC,SAASA,EAAMC,GAEd,GAAsB,kBAAXC,SAAyBA,OAAOC,IACzCD,QAAQ,WAAY,cAAe,SAASE,EAAUC,GACpD,MAAOJ,GAAQG,EAAUC,SAEtB,IAAuB,mBAAZC,SAAyB,CACzC,GAAIF,GAAWG,QAAQ,YACnBF,EAAIE,QAAQ,aAChBC,QAAOF,QAAUL,EAAQG,EAAUC,OAEnCJ,GAAQD,EAAKI,SAAUJ,EAAKK,KAG9BI,KAAM,SAASL,EAAUC,GACzB,YAEA,IAAIK,GAA6BN,EAASO,kBAiK1C,OAzJAP,GAASO,mBAAqB,SAAWP,EAAUC,GAKjD,GAAIO,GAAY,SAASC,GACvBJ,KAAKK,UACLL,KAAKM,iBACLN,KAAKO,kBACLP,KAAKQ,gBAELZ,EAAEa,KAAKL,EAAOJ,KAAKU,IAAKV,MAM1BJ,GAAEe,OAAOR,EAAUS,WAMjBF,IAAK,SAASG,EAAMC,GAClB,GAAIC,GAAUF,EAAKG,GAgBnB,OAbAhB,MAAKK,OAAOU,GAAWF,EAGnBA,EAAKI,QACPjB,KAAKM,cAAcO,EAAKI,MAAMD,KAAOD,GAInCD,IACFd,KAAKO,eAAeO,GAAeC,GAGrCf,KAAKQ,gBACER,MAKTkB,YAAa,SAASD,GACpB,MAAOjB,MAAKmB,eAAeF,EAAMD,MAMnCG,eAAgB,SAASC,GACvB,GAAIL,GAAUf,KAAKM,cAAcc,EACjC,OAAOpB,MAAKqB,UAAUN,IAIxBO,aAAc,SAASC,GACrB,GAAIR,GAAUf,KAAKO,eAAegB,EAClC,OAAOvB,MAAKqB,UAAUN,IAKxBS,YAAa,SAASD,GACpB,MAAO3B,GAAE6B,OAAOzB,KAAKK,QAAQkB,IAI/BF,UAAW,SAASL,GAClB,MAAOhB,MAAKK,OAAOW,IAIrBU,OAAQ,SAASb,GACf,GAAIE,GAAUF,EAAKG,GAoBnB,OAjBIH,GAAKI,aACAjB,MAAKM,cAAcO,EAAKI,MAAMD,KAIvCpB,EAAE+B,IAAI3B,KAAKO,eAAgB,SAASS,EAAKY,GACvC,MAAIZ,KAAQD,SACHf,MAAKO,eAAeqB,IACpB,GAFT,QAIC5B,YAGIA,MAAKK,OAAOU,GAGnBf,KAAKQ,gBACER,MAMT6B,KAAM,SAASC,GACb9B,KAAK+B,MAAMD,EAAQlC,EAAEoC,KAAKC,aAM5BF,MAAO,SAASD,EAAQI,GACtBtC,EAAEa,KAAKT,KAAKK,OAAQ,SAASQ,GACvBjB,EAAEuC,WAAWtB,EAAKiB,KACpBjB,EAAKiB,GAAQC,MAAMlB,EAAMqB,UAM/B1B,cAAe,WACbR,KAAKoC,OAASxC,EAAEyC,KAAKrC,KAAKK,UAS9B,IAAIiC,IAAW,UAAW,OAAQ,MAAO,OAAQ,SAAU,SACzD,SAAU,SAAU,QAAS,MAAO,OAAQ,MAAO,UACnD,WAAY,SAAU,UAAW,QAAS,UAAW,OACrD,OAAQ,UAAW,UAAW,QAAS,SAWzC,OATA1C,GAAEa,KAAK6B,EAAS,SAASR,GACvB3B,EAAUS,UAAUkB,GAAU,WAC5B,GAAI1B,GAAQR,EAAE6B,OAAOzB,KAAKK,QACtB6B,GAAQ9B,GAAOmC,OAAO3C,EAAE4C,QAAQP,WACpC,OAAOrC,GAAEkC,GAAQC,MAAMnC,EAAGsC,MAKvB/B,GACNR,EAAUC,GAGbD,EAASO,mBAAmBuC,QAAU,SAEtC9C,EAASO,mBAAmBwC,WAAa,WAEvC,MADA/C,GAASO,mBAAqBD,EACvBD,MAGFL,EAASO","file":"lib/backbone.babysitter.min.js"}

View File

@@ -0,0 +1,12 @@
// Backbone.BabySitter
// -------------------
// v0.1.11
//
// Copyright (c)2016 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
//
// http://github.com/marionettejs/backbone.babysitter
!function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=a.ChildViewContainer;return a.ChildViewContainer=function(a,b){var c=function(a){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),b.each(a,this.add,this)};b.extend(c.prototype,{add:function(a,b){var c=a.cid;return this._views[c]=a,a.model&&(this._indexByModel[a.model.cid]=c),b&&(this._indexByCustom[b]=c),this._updateLength(),this},findByModel:function(a){return this.findByModelCid(a.cid)},findByModelCid:function(a){var b=this._indexByModel[a];return this.findByCid(b)},findByCustom:function(a){var b=this._indexByCustom[a];return this.findByCid(b)},findByIndex:function(a){return b.values(this._views)[a]},findByCid:function(a){return this._views[a]},remove:function(a){var c=a.cid;return a.model&&delete this._indexByModel[a.model.cid],b.any(this._indexByCustom,function(a,b){return a===c?(delete this._indexByCustom[b],!0):void 0},this),delete this._views[c],this._updateLength(),this},call:function(a){this.apply(a,b.tail(arguments))},apply:function(a,c){b.each(this._views,function(d){b.isFunction(d[a])&&d[a].apply(d,c||[])})},_updateLength:function(){this.length=b.size(this._views)}});var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck","reduce"];return b.each(d,function(a){c.prototype[a]=function(){var c=b.values(this._views),d=[c].concat(b.toArray(arguments));return b[a].apply(b,d)}}),c}(a,b),a.ChildViewContainer.VERSION="0.1.11",a.ChildViewContainer.noConflict=function(){return a.ChildViewContainer=c,this},a.ChildViewContainer});
//# sourceMappingURL=backbone.babysitter.min.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["backbone.babysitter.js"],"names":["root","factory","define","amd","Backbone","_","exports","require","module","this","previousChildViewContainer","ChildViewContainer","Container","views","_views","_indexByModel","_indexByCustom","_updateLength","each","add","extend","prototype","view","customIndex","viewCid","cid","model","findByModel","findByModelCid","modelCid","findByCid","findByCustom","index","findByIndex","values","remove","any","key","call","method","apply","tail","arguments","args","isFunction","length","size","methods","concat","toArray","VERSION","noConflict"],"mappings":";;;;;;;;;;CASC,SAASA,EAAMC,GAEd,GAAsB,kBAAXC,SAAyBA,OAAOC,IACzCD,QAAQ,WAAY,cAAe,SAASE,EAAUC,GACpD,MAAOJ,GAAQG,EAAUC,SAEtB,IAAuB,mBAAZC,SAAyB,CACzC,GAAIF,GAAWG,QAAQ,YACnBF,EAAIE,QAAQ,aAChBC,QAAOF,QAAUL,EAAQG,EAAUC,OAEnCJ,GAAQD,EAAKI,SAAUJ,EAAKK,IAG9BI,KAAM,SAASL,EAAUC,GACzB,YAEA,IAAIK,GAA6BN,EAASO,kBAiK1C,OAzJAP,GAASO,mBAAqB,SAAWP,EAAUC,GAKjD,GAAIO,GAAY,SAASC,GACvBJ,KAAKK,UACLL,KAAKM,iBACLN,KAAKO,kBACLP,KAAKQ,gBAELZ,EAAEa,KAAKL,EAAOJ,KAAKU,IAAKV,MAM1BJ,GAAEe,OAAOR,EAAUS,WAMjBF,IAAK,SAASG,EAAMC,GAClB,GAAIC,GAAUF,EAAKG,GAgBnB,OAbAhB,MAAKK,OAAOU,GAAWF,EAGnBA,EAAKI,QACPjB,KAAKM,cAAcO,EAAKI,MAAMD,KAAOD,GAInCD,IACFd,KAAKO,eAAeO,GAAeC,GAGrCf,KAAKQ,gBACER,MAKTkB,YAAa,SAASD,GACpB,MAAOjB,MAAKmB,eAAeF,EAAMD,MAMnCG,eAAgB,SAASC,GACvB,GAAIL,GAAUf,KAAKM,cAAcc,EACjC,OAAOpB,MAAKqB,UAAUN,IAIxBO,aAAc,SAASC,GACrB,GAAIR,GAAUf,KAAKO,eAAegB,EAClC,OAAOvB,MAAKqB,UAAUN,IAKxBS,YAAa,SAASD,GACpB,MAAO3B,GAAE6B,OAAOzB,KAAKK,QAAQkB,IAI/BF,UAAW,SAASL,GAClB,MAAOhB,MAAKK,OAAOW,IAIrBU,OAAQ,SAASb,GACf,GAAIE,GAAUF,EAAKG,GAoBnB,OAjBIH,GAAKI,aACAjB,MAAKM,cAAcO,EAAKI,MAAMD,KAIvCpB,EAAE+B,IAAI3B,KAAKO,eAAgB,SAASS,EAAKY,GACvC,MAAIZ,KAAQD,SACHf,MAAKO,eAAeqB,IACpB,GAFT,QAIC5B,YAGIA,MAAKK,OAAOU,GAGnBf,KAAKQ,gBACER,MAMT6B,KAAM,SAASC,GACb9B,KAAK+B,MAAMD,EAAQlC,EAAEoC,KAAKC,aAM5BF,MAAO,SAASD,EAAQI,GACtBtC,EAAEa,KAAKT,KAAKK,OAAQ,SAASQ,GACvBjB,EAAEuC,WAAWtB,EAAKiB,KACpBjB,EAAKiB,GAAQC,MAAMlB,EAAMqB,UAM/B1B,cAAe,WACbR,KAAKoC,OAASxC,EAAEyC,KAAKrC,KAAKK,UAS9B,IAAIiC,IAAW,UAAW,OAAQ,MAAO,OAAQ,SAAU,SACzD,SAAU,SAAU,QAAS,MAAO,OAAQ,MAAO,UACnD,WAAY,SAAU,UAAW,QAAS,UAAW,OACrD,OAAQ,UAAW,UAAW,QAAS,SAWzC,OATA1C,GAAEa,KAAK6B,EAAS,SAASR,GACvB3B,EAAUS,UAAUkB,GAAU,WAC5B,GAAI1B,GAAQR,EAAE6B,OAAOzB,KAAKK,QACtB6B,GAAQ9B,GAAOmC,OAAO3C,EAAE4C,QAAQP,WACpC,OAAOrC,GAAEkC,GAAQC,MAAMnC,EAAGsC,MAKvB/B,GACNR,EAAUC,GAGbD,EAASO,mBAAmBuC,QAAU,SAEtC9C,EAASO,mBAAmBwC,WAAa,WAEvC,MADA/C,GAASO,mBAAqBD,EACvBD,MAGFL,EAASO","file":"backbone.babysitter.min.js"}

View File

@@ -0,0 +1,236 @@
# Backbone.BabySitter
[![Build Status](https://travis-ci.org/marionettejs/backbone.babysitter.svg?branch=master)](https://travis-ci.org/marionettejs/backbone.babysitter)
Manage child views in a Backbone.View.
## About Backbone.BabySitter
Backbone provides a lot of functionality in its views, but does not directly
provide a way to manage child views or nested views. This is not terribly
difficult to do on your own, but it gets tedious to write the same code
over and over again.
Backbone.BabySitter provides a simple way to manage an unknown number of
child views within a Backbone.View, or other object that needs to track a
list of views.
## Downloads And Source
Grab the source from the `src` folder above. Grab the most recent builds
from the links below.
* Development: [backbone.babysitter.js](https://raw.github.com/marionettejs/backbone.babysitter/master/lib/backbone.babysitter.js)
* Production: [backbone.babysitter.min.js](https://raw.github.com/marionettejs/backbone.babysitter/master/lib/backbone.babysitter.min.js)
## Documentation
Backbone.BabySitter exposes one constructor function: `Backbone.ChildViewContainer`.
This constructor function contains all of the necessary code for managing a list of
views.
### Storing Views
Views can be added to a container by calling the `add` method:
```js
var container = new Backbone.ChildViewContainer();
container.add(someView);
container.add(anotherView);
```
Views will be stored once and indexed in several ways:
* by `view.cid`
* by `view.model.cid` if the view has a model
* by a custom index key
When adding a view, you can optionally specify a custom index key
by which you can later retrieve the view.
```js
container.add(aView, "an indexer");
```
Note that the custom indexer should be unique within the container. If you
add two different views with the same custom indexer, the last one in will
be the only one stored by that index key.
### Constructing With Views
An initial list of views can be added to the container through the
constructor function call. This list must be an array of view instances:
```js
var views = [someView, anotherView];
var container = new Backbone.ChildViewContainer(views);
```
### Retrieving Views
You can retrieve a view by any of the index:
```js
var container = new Backbone.ChildViewContainer();
container.add(someView);
container.add(anotherView);
container.add(collectionView);
container.add(aView, "an indexer");
// find by view cid
var s = container.findByCid(someView.cid);
// find by model
var av = container.findByModel(anotherView.model);
// find by model cid
var av2 = container.findByModelCid(anotherView.model.cid);
// find by custom key
var custv = container.findByCustom("an indexer");
// find by numeric index (unstable)
var custv = container.findByIndex(0);
```
If the `findBy*` method cannot find the view, it will return undefined.
### Removing A View
You can remove a view directly and it will be removed from all available
indexes.
```js
var container = new Backbone.ChildViewContainer();
container.add(view);
// some time later
container.remove(view);
```
To remove a view by an index, find it by that index and then remove
the resulting view.
### Executing Methods On All Views
You can execute any arbitrary method with any arbitrary parameters on all of
the views within the container. There are two ways to do this: `container.call`
and `container.apply`. These methods work similarly to `function.call` and
`function.apply` in how parameters are passed through. However, they do not
allow the context to be specified. The view on which a method is being called
will always be the context of the call.
```js
var View = Backbone.View.extend({
doStuff: function(a, b){
},
moreStuff: function(a, b){
}
});
var v1 = new View();
var v2 = new View();
var container = new Backbone.ChildViewContainer();
container.add(v1);
container.add(v2);
// call the doStuff function
container.call("doStuff", 1, 2);
// apply the doStuff function
container.apply("doStuff", [1, 2]);
```
If any given view within the container does not have the method specified, it
will not be called on that view. No errors will be thrown in this situation.
### Get The Number Of Stored Views
To get the number of stored views, call the `container.length`
attribute. This attribute is updated any time a view is added or
removed.
```js
var container = new Backbone.ChildViewContainer();
container.add(view);
container.add(v2);
container.add(v3);
console.log(container.length); //=> 3
container.remove(v2);
console.log(container.length); //=> 2
```
### Iterators And Collection Functions
The container object borrows several functions from Underscore.js, to
provide iterators and other collection functions, including:
* forEach
* each
* map
* reduce
* find
* detect
* filter
* select
* reject
* every
* all
* some
* any
* include
* contains
* invoke
* toArray
* first
* initial
* rest
* last
* without
* isEmpty
* pluck
These methods can be called directly on the container, to iterate and
process the views held by the container.
```js
var container = new Backbone.ChildViewContainer();
container.add(v1);
container.add(v2);
container.add(v3);
// iterate over all of the views
container.each(function(view){
// process each view individually, here
});
```
For more information about these methods, see the [Underscore.js documentation](http://underscorejs.org).
## ChangeLog
For a complete change log, see the [CHANGELOG.md](https://github.com/marionettejs/backbone.babysitter/blob/master/CHANGELOG.md)
file.
## License
MIT - see [LICENSE.md](https://github.com/marionettejs/backbone.babysitter/blob/master/LICENSE.md)
## Dev
* `npm install`
* `npm install -g grunt-cli`
* `grunt`

View File

@@ -0,0 +1,248 @@
describe("childview container", function(){
describe("when providing an array of views to the constructor", function(){
var container;
beforeEach(function(){
var views = [
new Backbone.View(),
new Backbone.View(),
new Backbone.View()
]
container = new Backbone.ChildViewContainer(views);
});
it("should add all of the views", function(){
expect(container.length).toBe(3);
});
});
describe("when adding a view that does not have a model to the container", function(){
var container, view, foundView, indexView;
beforeEach(function(){
view = new Backbone.View();
container = new Backbone.ChildViewContainer();
container.add(view);
foundView = container.findByCid(view.cid);
indexView = container.findByIndex(0);
});
it("should make the view retrievable by the view's cid", function(){
expect(foundView).toBe(view);
});
it("should make the view retrievable by numeric index", function(){
expect(indexView).toBe(view);
});
it("should update the size of the chidren", function(){
expect(container.length).toBe(1);
})
});
describe("when adding a view that has a model, to the container", function(){
var container, view, foundView, model;
beforeEach(function(){
model = new Backbone.Model();
view = new Backbone.View({
model: model
});
container = new Backbone.ChildViewContainer();
container.add(view);
foundView = container.findByModel(model);
});
it("should make the view retrievable by the model", function(){
expect(foundView).toBe(view);
});
});
describe("when adding a view with a custom index value", function(){
var container, view, foundView;
beforeEach(function(){
view = new Backbone.View();
container = new Backbone.ChildViewContainer();
container.add(view, "custom indexer");
foundView = container.findByCustom("custom indexer");
});
it("should make the view retrievable by the custom indexer", function(){
expect(foundView).toBe(view);
});
});
describe("when removing a view", function(){
var container, view, model, col, cust;
beforeEach(function(){
model = new Backbone.Model();
cust = "custome indexer";
view = new Backbone.View({
model: model
});
container = new Backbone.ChildViewContainer();
container.add(view, cust);
container.remove(view);
});
it("should update the size of the chidren", function(){
expect(container.length).toBe(0);
})
it("should remove the index by model", function(){
var v = container.findByModel(model);
expect(v).toBeUndefined();
});
it("should remove the index by custom", function(){
var v = container.findByCustom(cust);
expect(v).toBeUndefined();
});
it("should remove the view from the container", function(){
var v = container.findByCid(view.cid);
expect(v).toBeUndefined();
});
});
describe("adding or removing a view", function(){
var container, view, model;
beforeEach(function(){
model = new Backbone.Model();
view = new Backbone.View({
model: model
});
container = new Backbone.ChildViewContainer();
});
it("should return itself when adding, for chaining methods", function(){
expect(container.add(view)).toBe(container);
});
it("should return itself when removing, for chaining methods", function(){
expect(container.remove(view)).toBe(container);
});
});
describe("when a container has 2 views in it", function(){
describe("and applying a method with parameters", function(){
var container, v1, v2;
beforeEach(function(){
v1 = new Backbone.View();
v1.someFunc = jasmine.createSpy("some func");
v2 = new Backbone.View();
v2.someFunc = jasmine.createSpy("some func");
container = new Backbone.ChildViewContainer();
container.add(v1);
container.add(v2);
container.apply("someFunc", ["1", "2"]);
});
it("should call that method on the first view", function(){
expect(v1.someFunc).toHaveBeenCalledWith("1", "2");
});
it("should call that method on the second view", function(){
expect(v2.someFunc).toHaveBeenCalledWith("1", "2");
});
});
describe("and calling a method with parameters", function(){
var container, v1, v2;
beforeEach(function(){
v1 = new Backbone.View();
v1.someFunc = jasmine.createSpy("some func");
v2 = new Backbone.View();
v2.someFunc = jasmine.createSpy("some func");
container = new Backbone.ChildViewContainer();
container.add(v1);
container.add(v2);
container.call("someFunc", "1", "2");
});
it("should call that method on the first view", function(){
expect(v1.someFunc).toHaveBeenCalledWith("1", "2");
});
it("should call that method on the second view", function(){
expect(v2.someFunc).toHaveBeenCalledWith("1", "2");
});
});
describe("and calling a method that doesn't exist on one of the views", function(){
var container, v1, v2;
beforeEach(function(){
v1 = new Backbone.View();
v2 = new Backbone.View();
v2.someFunc = jasmine.createSpy("some func");
container = new Backbone.ChildViewContainer();
container.add(v1);
container.add(v2);
container.call("someFunc", "1", "2");
});
it("should call that method on the second view", function(){
expect(v2.someFunc).toHaveBeenCalledWith("1", "2");
});
});
});
describe("iterators and collection functions", function(){
var container, view, views;
beforeEach(function(){
views = [];
view = new Backbone.View();
container = new Backbone.ChildViewContainer();
container.add(view);
container.each(function(v, k){
views.push(v);
});
});
it("should provide a .each iterator", function(){
expect(_.isFunction(container.each)).toBe(true);
});
it("should iterate the views with the .each function", function(){
expect(views[0]).toBe(view);
});
});
});

View File

@@ -0,0 +1,8 @@
beforeEach(function() {
jasmine.addMatchers({
toHaveOwnProperty: function(expectedProperty) {
var obj = this.actual;
return obj.hasOwnProperty(expectedProperty);
}
});
});

View File

@@ -0,0 +1,31 @@
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['backbone', 'underscore'], function(Backbone, _) {
return factory(Backbone, _);
});
} else if (typeof exports !== 'undefined') {
var Backbone = require('backbone');
var _ = require('underscore');
module.exports = factory(Backbone, _);
} else {
factory(root.Backbone, root._);
}
}(this, function(Backbone, _) {
'use strict';
var previousChildViewContainer = Backbone.ChildViewContainer;
// @include ../childviewcontainer.js
Backbone.ChildViewContainer.VERSION = '<%= version %>';
Backbone.ChildViewContainer.noConflict = function () {
Backbone.ChildViewContainer = previousChildViewContainer;
return this;
};
return Backbone.ChildViewContainer;
}));

View File

@@ -0,0 +1,150 @@
// BabySitter.ChildViewContainer
// -----------------------------
//
// Provide a container to store, retrieve and
// shut down child views.
Backbone.ChildViewContainer = (function (Backbone, _) {
// Container Constructor
// ---------------------
var Container = function(views){
this._views = {};
this._indexByModel = {};
this._indexByCustom = {};
this._updateLength();
_.each(views, this.add, this);
};
// Container Methods
// -----------------
_.extend(Container.prototype, {
// Add a view to this container. Stores the view
// by `cid` and makes it searchable by the model
// cid (and model itself). Optionally specify
// a custom key to store an retrieve the view.
add: function(view, customIndex){
var viewCid = view.cid;
// store the view
this._views[viewCid] = view;
// index it by model
if (view.model){
this._indexByModel[view.model.cid] = viewCid;
}
// index by custom
if (customIndex){
this._indexByCustom[customIndex] = viewCid;
}
this._updateLength();
return this;
},
// Find a view by the model that was attached to
// it. Uses the model's `cid` to find it.
findByModel: function(model){
return this.findByModelCid(model.cid);
},
// Find a view by the `cid` of the model that was attached to
// it. Uses the model's `cid` to find the view `cid` and
// retrieve the view using it.
findByModelCid: function(modelCid){
var viewCid = this._indexByModel[modelCid];
return this.findByCid(viewCid);
},
// Find a view by a custom indexer.
findByCustom: function(index){
var viewCid = this._indexByCustom[index];
return this.findByCid(viewCid);
},
// Find by index. This is not guaranteed to be a
// stable index.
findByIndex: function(index){
return _.values(this._views)[index];
},
// retrieve a view by its `cid` directly
findByCid: function(cid){
return this._views[cid];
},
// Remove a view
remove: function(view){
var viewCid = view.cid;
// delete model index
if (view.model){
delete this._indexByModel[view.model.cid];
}
// delete custom index
_.any(this._indexByCustom, function(cid, key) {
if (cid === viewCid) {
delete this._indexByCustom[key];
return true;
}
}, this);
// remove the view from the container
delete this._views[viewCid];
// update the length
this._updateLength();
return this;
},
// Call a method on every view in the container,
// passing parameters to the call method one at a
// time, like `function.call`.
call: function(method){
this.apply(method, _.tail(arguments));
},
// Apply a method on every view in the container,
// passing parameters to the call method one at a
// time, like `function.apply`.
apply: function(method, args){
_.each(this._views, function(view){
if (_.isFunction(view[method])){
view[method].apply(view, args || []);
}
});
},
// Update the `.length` attribute on this container
_updateLength: function(){
this.length = _.size(this._views);
}
});
// Borrowing this code from Backbone.Collection:
// http://backbonejs.org/docs/backbone.html#section-106
//
// Mix in methods from Underscore, for iteration, and other
// collection related features.
var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
'select', 'reject', 'every', 'all', 'some', 'any', 'include',
'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
'last', 'without', 'isEmpty', 'pluck', 'reduce'];
_.each(methods, function(method) {
Container.prototype[method] = function() {
var views = _.values(this._views);
var args = [views].concat(_.toArray(arguments));
return _[method].apply(_, args);
};
});
// return the public API
return Container;
})(Backbone, _);

View File

@@ -0,0 +1,53 @@
{
"name": "backbone.marionette",
"description": "Make your Backbone.js apps dance with a composite application architecture!",
"homepage": "http://marionettejs.org",
"main": "./lib/core/backbone.marionette.js",
"version": "2.4.7",
"keywords": [
"backbone",
"framework",
"client",
"browser",
"composite"
],
"license": "MIT",
"author": {
"name": "Derick Bailey",
"email": "derickbailey@gmail.com"
},
"ignore": [
"api",
"docs",
"jsdoc",
"src",
"tasks",
"test",
".editorconfig",
".gitignore",
".jscsrc",
".jshintrc",
".npmignore",
".travis.yml",
"component.json",
"CONTRIBUTING.md",
"Gruntfile.js",
"SpecRunner.html",
"upgradeGuide.md"
],
"dependencies": {
"backbone": "1.0.0 - 1.3.x",
"underscore": "1.4.4 - 1.8.3",
"backbone.babysitter": "^0.1.0",
"backbone.wreqr": "^1.0.0"
},
"_release": "2.4.7",
"_resolution": {
"type": "version",
"tag": "v2.4.7",
"commit": "e1a512a2f44fadfebe5c01e8966bdbe4fa5f9e51"
},
"_source": "https://github.com/marionettejs/backbone.marionette.git",
"_target": "^2.4.6",
"_originalSource": "backbone.marionette"
}

View File

@@ -0,0 +1,21 @@
### Description
1. The problem you are facing (in as much detail as is necessary to describe the problem to someone who doesn't know anything about the system you're building)
2. A summary of the proposed solution
3. A description of how this solution solves the problem, in more detail than item #2
4. Any additional discussion on possible problems this might introduce, questions that you have related to the changes, etc.
### Expected behavior
Tell us what you think should happend.
### Actual behavior
If it is possible, please create a small demo that demonstrates the issue.
Please refrain from giving code examples in altJS languages like CoffeeScript, etc. Marionette is written in plain-old JavaScript and is generally easier for all members in the community to read.
### Environment
1. Marionette version:
2. Backbone version:
3. Additional build tools, etc:

View File

@@ -0,0 +1,6 @@
### Proposed changes
-
-
-
Link to the issue:

View File

@@ -0,0 +1,44 @@
{
"name": "backbone.marionette",
"description": "Make your Backbone.js apps dance with a composite application architecture!",
"homepage": "http://marionettejs.org",
"main": "./lib/core/backbone.marionette.js",
"version": "2.4.7",
"keywords": [
"backbone",
"framework",
"client",
"browser",
"composite"
],
"license": "MIT",
"author": {
"name": "Derick Bailey",
"email": "derickbailey@gmail.com"
},
"ignore": [
"api",
"docs",
"jsdoc",
"src",
"tasks",
"test",
".editorconfig",
".gitignore",
".jscsrc",
".jshintrc",
".npmignore",
".travis.yml",
"component.json",
"CONTRIBUTING.md",
"Gruntfile.js",
"SpecRunner.html",
"upgradeGuide.md"
],
"dependencies": {
"backbone": "1.0.0 - 1.3.x",
"underscore": "1.4.4 - 1.8.3",
"backbone.babysitter": "^0.1.0",
"backbone.wreqr": "^1.0.0"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
MarionetteJS is distributed under [MIT license](http://mutedsolutions.mit-license.org/).

Binary file not shown.

View File

@@ -0,0 +1,82 @@
{
"name": "backbone.marionette",
"description": "Make your Backbone.js apps dance!",
"version": "2.4.7",
"homepage": "https://github.com/marionettejs/backbone.marionette",
"main": "lib/core/backbone.marionette.js",
"keywords": [
"backbone",
"plugin",
"marionette",
"composite",
"architecture",
"single",
"page",
"app",
"client",
"browser"
],
"licenses": [
{
"type": "MIT",
"url": "https://github.com/marionettejs/backbone.marionette/blob/master/license.txt"
}
],
"scripts": {
"test": "grunt test --mocha-reporter=dot",
"coverage": "grunt coverage --mocha-reporter=dot"
},
"author": {
"name": "Derick Bailey",
"email": "derickbailey@gmail.com",
"url": "http://derickbailey.lostechies.com"
},
"bugs": {
"url": "https://github.com/marionettejs/backbone.marionette/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/marionettejs/backbone.marionette.git"
},
"github": "https://github.com/marionettejs/backbone.marionette",
"dependencies": {
"backbone.babysitter": "^0.1.0",
"backbone.wreqr": "^1.0.0",
"backbone": "1.0.0 - 1.3.x",
"underscore": "1.4.4 - 1.8.3"
},
"devDependencies": {
"chai": "3.4.1",
"chai-jq": "0.0.9",
"chai-jquery": "2.0.0",
"dox": "git://github.com/jasonLaster/dox.git#marked",
"grunt": "0.4.5",
"grunt-cli": "0.1.13",
"grunt-contrib-clean": "0.7.0",
"grunt-contrib-concat": "0.5.1",
"grunt-contrib-connect": "0.11.2",
"grunt-contrib-jshint": "0.11.3",
"grunt-contrib-uglify": "1.0.1",
"grunt-contrib-watch": "0.6.1",
"grunt-coveralls": "1.0.0",
"grunt-env": "0.4.4",
"grunt-istanbul": "0.6.1",
"grunt-jscs": "2.6.0",
"grunt-lintspaces": "0.7.1",
"grunt-mocha-test": "0.12.7",
"grunt-plato": "1.2.1",
"grunt-preprocess": "5.0.1",
"grunt-template": "0.2.3",
"highlight.js": "9.1.0",
"jquery": "2.2.0",
"js-yaml": "3.5.2",
"jsdom": "3.1.2",
"load-grunt-tasks": "3.4.0",
"marked": "0.3",
"mocha": "2.3.4",
"sinon": "1.10.3",
"sinon-chai": "2.8.0",
"unwrap": "0.1.0",
"grunt-yaml-validate": "~0.1.1"
}
}

View File

@@ -0,0 +1,144 @@
<h1 align="center">Marionette.js</h1>
<p align="center">
<img title="backbone marionette" src='marionette-logo.png' />
</p>
<p align="center">The Backbone framework</p>
<p align="center">
<a title='Build Status' href="https://travis-ci.org/marionettejs/backbone.marionette">
<img src='https://secure.travis-ci.org/marionettejs/backbone.marionette.svg?branch=master' />
</a>
<a href='https://coveralls.io/r/marionettejs/backbone.marionette'>
<img src='https://img.shields.io/coveralls/marionettejs/backbone.marionette.svg' alt='Coverage Status' />
</a>
<a href='https://gitter.im/marionettejs/backbone.marionette?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge'>
<img src='https://badges.gitter.im/Join%20Chat.svg' alt='Gitter Chat' />
</a>
</p>
## About Marionette
Marionette is a composite application library for Backbone.js that
aims to simplify the construction of large scale JavaScript applications.
It is a collection of common design and implementation patterns found in
applications.
## Documentation
All of the documentation for Marionette can be found at
##### [marionettejs.com/docs/current](http://marionettejs.com/docs/current)
### App Architecture On Backbone's Building Blocks
Backbone provides a great set of building blocks for our JavaScript
applications. It gives us the core constructs that are needed to build
small apps, organize jQuery DOM events, or create single page apps that
support mobile devices and large scale enterprise needs. But Backbone is
not a complete framework. It's a set of building blocks. It leaves
much of the application design, architecture and scalability to the
developer, including memory management, view management, and more.
Marionette brings an application architecture to Backbone, along with
built in view management and memory management. It's designed to be a
lightweight and flexible library of tools that sits on top of Backbone,
providing the framework for building a scalable application.
Like Backbone itself, you're not required to use all of Marionette just
because you want to use some of it. You can pick and choose which features
you want to use. This allows you to work with other Backbone
frameworks and plugins easily. It also means that you are not required
to engage in an all-or-nothing migration to begin using Marionette.
### Chat with us
Find us [on gitter](https://gitter.im/marionettejs/backbone.marionette) or on IRC in the FreeNode.net [#marionette channel](http://freenode.net).
We're happy to discuss design patterns and learn how you're using Marionette.
### Key Benefits
* Scalable: applications built in modules with event-driven architecture
* Sensible defaults: Underscore templates are used for view rendering
* Easily modifiable: works with the specific needs of your application
* Reduce boilerplate: for all views, including specialized types
* Create: application visuals at runtime with `Region` and `LayoutView` objects
* Nested: views and layouts within visual regions
* Built-in: memory management and zombie-killing for views, layoutViews and regions
* Event-driven architecture: utilizing the `Backbone.Wreqr.EventAggregator`
* Flexible: "as-needed" architecture allowing you to pick and choose what you need
* And much, much more
## Marionette Inspector
<a href="https://github.com/marionettejs/marionette.inspector"><img src="http://i.imgur.com/B1q9QXH.jpg" align="center" /></a>
+ **Visualize** the view hierarchy with the UI tree
+ **Visualize** application activity with a full history of actions
+ **Inspect** view ui, events, listeners, properties
+ **Inspect** model attributes, listeners, properties
+ **Explore** Radio channel events, requests, commands
+ **Explore** application with an inspector magnifying glass
+ **Jump** between the inspector elements and source panel with intelligent links
Download at [Chrome Web Store](https://chrome.google.com/webstore/detail/marionette-inspector/fbgfjlockdhidoaempmjcddibjklhpka)
Explore code at [Github](https://github.com/marionettejs/marionette.inspector)
## Source Code and Downloads
You can download the latest builds directly from the "lib" folder above.
For more information about the files in this folder, or to obtain an archive
containing all Marionette dependencies (including Underscore, Backbone, etc.),
please visit [the downloads section on the website](http://marionettejs.com#download).
#### [MarionetteJS.com](http://marionettejs.com#download)
### Available Packages
Marionette is available via bower, npm, and component.io. There are other channels that are maintained by the community.
## Release Notes And Upgrade Guide
**Changelog**: For change logs and release notes, see the
[changelog](changelog.md) file.
**Upgrade Guide**: Be sure to read [the upgrade guide](upgradeGuide.md)
for information on upgrading to the latest version of Marionette.
### Annotated Source Code
The source code for Marionette is heavily documented.
You can read the annotations for all the details of how Marionette works and advice on which methods to override.
##### [View the annotated source code](http://marionettejs.com/annotated-src/backbone.marionette)
## Compatibility and Requirements
MarionetteJS currently works with the following libraries:
* [jQuery](http://jquery.com) v1.8+
* [Underscore](http://underscorejs.org) v1.4.4 - 1.8.3
* [Backbone](http://backbonejs.org) v1.0.0 - 1.2.1 are preferred.
* [Backbone.Wreqr](https://github.com/marionettejs/backbone.wreqr) Comes automatically with the bundled build.
* [Backbone.BabySitter](https://github.com/marionettejs/backbone.babysitter) Comes automatically with the bundled build.
Marionette has not been tested against any other versions of these
libraries. You may or may not have success if you use a version other
than what is listed here.
## How to Contribute
If you would like to contribute to Marionette's source code, please read
the [guidelines for pull requests and contributions](CONTRIBUTING.md).
Following these guidelines will help make your contributions easier to
bring into the next release.
### [GitHub Issues](//github.com/marionettejs/backbone.marionette/issues)
Report issues with Marionette, submit pull requests to fix problems, or to
create summarized and documented feature requests (preferably with pull
requests that implement the feature).

View File

@@ -0,0 +1,42 @@
{
"name": "backbone.radio",
"version": "1.0.5",
"homepage": "https://github.com/marionettejs/backbone.radio",
"authors": [
"Jmeas <jellyes2@gmail.com>"
],
"description": "Messaging patterns for Backbone applications.",
"main": "build/backbone.radio.js",
"keywords": [
"backbone",
"marionette",
"decoupled",
"pubsub",
"publish",
"subscribe",
"messaging",
"architecture",
"spa"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"backbone": "1.0.0 - 1.3.x",
"underscore": "1.4.4 - 1.8.3"
},
"_release": "1.0.5",
"_resolution": {
"type": "version",
"tag": "v1.0.5",
"commit": "277936bb207583b64bdc3b71f039bf170ea0a393"
},
"_source": "https://github.com/marionettejs/backbone.radio.git",
"_target": "^1.0.5",
"_originalSource": "backbone.radio"
}

View File

@@ -0,0 +1,119 @@
### [1.0.5](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.5)
- Updated Backbone dep to allow v1.3.3
### [1.0.4](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.4)
- **Bug fix**: The UMD generated from rollup was setting `global` to `undefined`.
### [1.0.3](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.3)
- Updated Backbone dep to allow v1.3.2
### [1.0.2](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.2)
- Updated Backbone dep to allow v1.2.3
### [1.0.1](https://github.com/marionettejs/backbone.radio/releases/tag/1.0.1)
- Updated Backbone dep to allow v1.2.2
### [1.0.0](https://github.com/jmeas/backbone.radio/releases/tag/v1.0.0)
- **Breaking change**: Commands have been removed. ([see explanation](https://github.com/marionettejs/backbone.radio/pull/221#issuecomment-104782925))
### [0.9.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.9.1)
- **Refactor**: Structure and build using babel-boilerplate
- Update Underscore and Backbone dependencies to 1.8.3 and 1.2.1 respectively to match Marionette.
### [0.9.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.9.0)
- **Breaking change**: Space-separated requests no longer return an Array. Instead, an Object is returned.
```js
// old
myChannel.request('thingOne thingTwo');
// => [replyOne, replyTwo]
// new
myChannel.request('thingOne thingTwo');
// => { thingOne: replyOne, thingTwo: replyTwo }
```
- **New feature**: `Radio.reset()` is now a top-level API method that can be used to reset a channel, or all channels. Do note that channels continue to have their own `reset` method.
- **New feature**: `Radio.debugLog()` is now exposed...go forth and customize how Radio logs potential errors!
### [0.8.2](https://github.com/jmeas/backbone.radio/releases/tag/v0.8.2)
- **Refactor**: A small refactor to support Underscore 1.4.4 (the lowest version that Marionette supports)
### [0.8.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.8.1)
- **Bug fix**: Fixes bug where `stopComplying` and `stopReplying` would not remove the correct
callbacks in certain situations
### [0.8.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.8.0)
- **Feature**: DEBUG now warns when an already-registered Command or Request is overwritten
- **Feature**: `stopComplying` and `stopReplying` now accept the same arguments as `off`
### [0.7.2](https://github.com/jmeas/backbone.radio/releases/tag/v0.7.2)
- Corrects Underscore dependency in bower.json.
### [0.7.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.7.1)
- Corrects Underscore dependency.
### [0.7.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.7.0)
- **Feature**: All API methods of Commands ands Requests now support the space-separated syntax.
- **Enhancement**: Only Channels created through Radio's factory method will register themselves on the internal
store of Channels
- **Enhancement**: Callback execution has been optimized
### [0.6.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.6.0)
*This update is not backwards compatible.*
- **Feature:** `channelName` is now a public property on each Channel.
- **Feature:** Requests and Commands can now have `"default"` handlers which will be called when the specified event isn't registered.
- **API Change:** The convenience connectX methods have been removed. In their place, the object syntax can be used for registering
multiple events on channels. This makes the API of Radio more consistent with Backbone.Events. For instance,
```js
myChannel.reply({
oneRequest: myCallback,
anotherRequest: myCallback
}, myContext);
```
### [0.5.2](https://github.com/jmeas/backbone.radio/releases/tag/v0.5.2)
- Fixes a bug where the top-level API would not pass the correct arguments to the underlying methods.
### [0.5.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.5.1)
- Fixes Radio.VERSION in the built library
### [0.5.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.5.0)
- Commands.react has been renamed to Commands.comply
### [0.4.1](https://github.com/jmeas/backbone.radio/releases/tag/v0.4.1)
- The Channel convenience methods no longer bind the context, instead deferring that
responsibility to the wrapped methods themselves. This aids in stack traces and gives you
the ability to unregister the methods individually.
### [0.4.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.4.0)
- Debug mode now informs you when you attempt to unregister an event that was never registered. This is to help prevent memory leaks.
- `respond` has been renamed to `reply`
- More methods now return `this`, making the API more consistent internally, and with Backbone.Events
### [0.3.0](https://github.com/jmeas/backbone.radio/releases/tag/v0.3.0)
- More test coverage
- Tests completely rewritten
- Numerous bug fixes; more work on the library

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 James Smith
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,351 @@
# Backbone.Radio
[![Travis Build Status](http://img.shields.io/travis/marionettejs/backbone.radio.svg?style=flat)](https://travis-ci.org/marionettejs/backbone.radio)
[![Coverage](http://img.shields.io/codeclimate/coverage/github/marionettejs/backbone.radio.svg?style=flat)](https://codeclimate.com/github/marionettejs/backbone.radio)
[![Dependency Status](http://img.shields.io/david/marionettejs/backbone.radio.svg?style=flat)](https://david-dm.org/marionettejs/backbone.radio)
[![Gitter chat room](https://img.shields.io/badge/gitter-backbone.radio-brightgreen.svg?style=flat)](https://gitter.im/marionettejs/backbone.radio)
Backbone.Radio provides additional messaging patterns for Backbone applications.
Backbone includes an event system, Backbone.Events, which is an implementation of the publish-subscribe pattern. Pub-sub is by far the most
common event pattern in client-side applications, and for good reason: it is incredibly useful. It should also be familiar to web developers
in particular, because the DOM relies heavily on pub-sub. Consider, for instance, registering a handler on an element's `click` event. This isn't
so much different than listening to a Model's `change` event, as both of these situations are using pub-sub.
Backbone.Radio adds two additional messaging-related features. The first is Requests, an implementation of the request-reply pattern. Request-reply
should also be familiar to web developers, as it's the messaging pattern that backs HTTP communications. The other feature are Channels: explicit
namespaces to your communications.
## Installation
Clone this repository or install via [Bower](http://bower.io/) or [npm](https://www.npmjs.org/).
```
bower install backbone.radio
npm install backbone.radio
```
## Documentation
- [Getting Started](#getting-started)
- [Backbone.Events](#backboneevents)
- [Radio.Requests](#backboneradiorequests)
- [Channels](#channels)
- [Using With Marionette](#using-with-marionette)
- [API](#api)
- [Radio.Requests](#requests)
- [Channel](#channel)
- [Radio](#radio)
- [Top-level API](#top-level-api)
## Getting Started
### Backbone.Events
Anyone who has used Backbone should be quite familiar with Backbone.Events. Backbone.Events is what facilitates
communications between objects in your application. The quintessential example of this is listening in on a
Model's change event.
```js
// Listen in on a model's change events
this.listenTo(someModel, 'change', myCallback);
// Later on, the model triggers a change event when it has been changed
someModel.trigger('change');
```
Let's look at a diagram for Backbone.Events:
<p align='center'>
<img src='https://cloud.githubusercontent.com/assets/10248067/11762943/5a927e54-a0bd-11e5-8aa5-e0fafae0e559.png' alt='Backbone.Events diagram'>
</p>
It goes without saying that Backbone.Events is incredibly useful when you mix it into instances of Classes. But what
if you had a standalone Object with an instance of Backbone.Events on it? This gives you a powerful message bus to utilize.
```js
// Create a message bus
var myBus = _.extend({}, Backbone.Events);
// Listen in on the message bus
this.listenTo(myBus, 'some:event', myCallback);
// Trigger an event on the bus
myBus.trigger('some:event');
```
As long as there was an easy way to access this message bus throughout your entire application, then you would have a central
place to store a collection of events. This is the idea behind Channels. But before we go more into that, let's take a look at Requests.
### Backbone.Radio.Requests
Requests is similar to Events in that it's another event system. And it has a similar API, too. For this reason, you *could* mix
it into an object.
```js
_.extend(myView, Backbone.Radio.Requests);
```
Although this works, I wouldn't recommend it. Requests are most useful, I think, when they're used with a Channel.
Perhaps the biggest difference between Events and Requests is that Requests have *intention*. Unlike Events, which notify
nothing in particular about an occurrence, Requests are asking for a very specific thing to occur. As a consequence of this,
requests are 'one-to-one,' which means that you cannot have multiple 'listeners' to a single request.
Let's look at a basic example.
```js
// Set up an object to reply to a request. In this case, whether or not its visible.
myObject.reply('visible', this.isVisible);
// Get whether it's visible or not.
var isViewVisible = myObject.request('visible');
```
The handler in `reply` can either return a flat value, like `true` or `false`, or a function to be executed. Either way, the value is sent back to
the requester.
Here's a diagram of the Requests pattern:
<p align='center'>
<img src='https://cloud.githubusercontent.com/assets/10248067/11762945/5c302a36-a0bd-11e5-8e4e-0eee7cacbef1.png' alt='Backbone.Requests diagram'>
</p>
Although the name is 'Requests,' you can just as easily request information as you can request that an action be completed. Just like HTTP,
where you can both make GET requests for information, or DELETE requests to order than a resource be deleted, Requests can be used for a variety
of purposes.
One thing to note is that this pattern is **identical** to a simple method call. One can just as easily rewrite the above example as:
```js
// Set up a method...
myObject.isVisible = function() {
return this.viewIsVisible;
}
// Call that method
var isViewVisible = myObject.isVisible();
```
This is why mixing Requests into something like a View or Model does not make much sense. If you have access to the View or Model, then
you might as well just use methods.
### Channels
The real draw of Backbone.Radio are Channels. A Channel is simply an object that has Backbone.Events and Radio.Requests mixed into it:
it's a standalone message bus comprised of both systems.
Getting a handle of a Channel is easy.
```js
// Get a reference to the channel named 'user'
var userChannel = Backbone.Radio.channel('user');
```
Once you've got a channel, you can attach handlers to it.
```js
userChannel.on('some:event', function() {
console.log('An event has happened!');
});
userChannel.reply('some:request', 'food is good');
```
You can also use the 'trigger' methods on the Channel.
```js
userChannel.trigger('some:event');
userChannel.request('some:request');
```
You can have as many channels as you'd like
```js
// Maybe you have a channel for the profile section of your app
var profileChannel = Backbone.Radio.channel('profile');
// And another one for settings
var settingsChannel = Backbone.Radio.channel('settings');
```
The whole point of Channels is that they provide a way to explicitly namespace events in your application, and a means to easily access
any of those namespaces.
### Using With Marionette
[Marionette](https://github.com/marionettejs/backbone.marionette) does not use Radio by default, although it will in the next major release: v3. However, you can use Radio today by including a small shim after you load Marionette, but before you load your application's code. To get the shim, refer to [this Gist](https://gist.github.com/jmeas/7992474cdb1c5672d88b).
## API
Like Backbone.Events, **all** of the following methods support both the object-syntax and space-separated syntax. For the sake of brevity,
I only provide examples for these alternate syntaxes in the most common use cases.
### Requests
#### `request( requestName [, args...] )`
Make a request for `requestName`. Optionally pass arguments to send along to the callback. Returns the reply, if one
exists. If there is no reply registered then `undefined` will be returned.
You can make multiple requests at once by using the space-separated syntax.
```js
myChannel.request('requestOne requestTwo');
```
When using the space-separated syntax, the responses will be returned to you as an object, where
the keys are the name of the request, and the values are the replies.
#### `reply( requestName, callback [, context] )`
Register a handler for `requestName` on this object. `callback` will be executed whenever the request is made. Optionally
pass a `context` for the callback, defaulting to `this`.
To register a default handler for Requests use the `default` requestName. The unhandled `requestName` will be passed as the first argument.
```js
myChannel.reply('default', function(requestName) {
console.log('No reply exists for this request: ' + requestName);
});
// This will be handled by the default request
myChannel.request('someUnhandledRequest');
```
To register multiple requests at once you may also pass in a hash.
```js
// Connect all of the replies at once
myChannel.reply({
'some:request': myCallback,
'some:other:request': someOtherCallback
}, context);
```
Returns the instance of Requests.
#### `replyOnce( requestName, callback [, context] )`
Register a handler for `requestName` that will only be called a single time.
Like `reply`, you may also pass a hash of replies to register many at once. Refer to the `reply` documentation above
for an example.
Returns the instance of Requests.
#### `stopReplying( [requestName] [, callback] [, context] )`
If `context` is passed, then all replies with that context will be removed from the object. If `callback` is
passed then all requests with that callback will be removed. If `requestName` is passed then this method will
remove that reply. If no arguments are passed then all replies are removed from the object.
You may also pass a hash of replies or space-separated replies to remove many at once.
Returns the instance of Requests.
### Channel
#### `channelName`
The name of the channel.
#### `reset()`
Destroy all handlers from Backbone.Events and Radio.Requests from the channel. Returns the channel.
### Radio
#### `channel( channelName )`
Get a reference to a channel by name. If a name is not provided an Error will be thrown.
```js
var authChannel = Backbone.Radio.channel('auth');
```
#### `DEBUG`
This is a Boolean property. Setting it to `true` will cause console warnings to be issued
whenever you interact with a `request` that isn't registered. This is useful in development when you want to
ensure that you've got your event names in order.
```js
// Turn on debug mode
Backbone.Radio.DEBUG = true;
// This will log a warning to the console if it goes unhandled
myChannel.request('show:view');
// Likewise, this will too, helping to prevent memory leaks
myChannel.stopReplying('startTime');
```
#### `debugLog(warning, eventName, channelName)`
A function executed whenever an unregistered request is interacted with on a Channel. Only
called when `DEBUG` is set to `true`. By overriding this you could, for instance, make unhandled
events throw Errors.
The warning is a string describing the type of problem, such as:
> Attempted to remove the unregistered request
while the `eventName` and `channelName` are what you would expect.
#### `tuneIn( channelName )`
Tuning into a Channel is another useful tool for debugging. It passes all
triggers and requests made on the channel to
[`Radio.log`](https://github.com/jmeas/backbone.radio#log-channelname-eventname--args-).
Returns `Backbone.Radio`.
```js
Backbone.Radio.tuneIn('calendar');
```
#### `tuneOut( channelName )`
Once you're done tuning in you can call `tuneOut` to stop the logging. Returns `Backbone.Radio`.
```js
Backbone.Radio.tuneOut('calendar');
```
#### `log( channelName, eventName [, args...] )`
When tuned into a Channel, this method will be called for all activity on
a channel. The default implementation is to `console.log` the following message:
```js
'[channelName] "eventName" args1 arg2 arg3...'
```
where args are all of the arguments passed with the message. It is exposed so that you
may overwrite it with your own logging message if you wish.
### 'Top-level' API
If you'd like to execute a method on a channel, yet you don't need to keep a handle of the
channel around, you can do so with the proxy functions directly on the `Backbone.Radio` object.
```js
// Trigger 'some:event' on the settings channel
Backbone.Radio.trigger('settings', 'some:event');
```
All of the methods for both messaging systems are available from the top-level API.
#### `reset( [channelName] )`
You can also reset a single channel, or all Channels, from the `Radio` object directly. Pass a
`channelName` to reset just that specific channel, or call the method without any arguments
to reset every channel.
```js
// Reset all channels
Radio.reset();
```

View File

@@ -0,0 +1,33 @@
{
"name": "backbone.radio",
"version": "1.0.4",
"homepage": "https://github.com/marionettejs/backbone.radio",
"authors": [
"Jmeas <jellyes2@gmail.com>"
],
"description": "Messaging patterns for Backbone applications.",
"main": "build/backbone.radio.js",
"keywords": [
"backbone",
"marionette",
"decoupled",
"pubsub",
"publish",
"subscribe",
"messaging",
"architecture",
"spa"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"backbone": "1.0.0 - 1.3.x",
"underscore": "1.4.4 - 1.8.3"
}
}

View File

@@ -0,0 +1,352 @@
// Backbone.Radio v1.0.4
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('underscore'), require('backbone')) :
typeof define === 'function' && define.amd ? define(['underscore', 'backbone'], factory) :
(global.Backbone = global.Backbone || {}, global.Backbone.Radio = factory(global._,global.Backbone));
}(this, function (_,Backbone) { 'use strict';
_ = 'default' in _ ? _['default'] : _;
Backbone = 'default' in Backbone ? Backbone['default'] : Backbone;
var babelHelpers = {};
babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
babelHelpers;
var previousRadio = Backbone.Radio;
var Radio = Backbone.Radio = {};
Radio.VERSION = '1.0.4';
// This allows you to run multiple instances of Radio on the same
// webapp. After loading the new version, call `noConflict()` to
// get a reference to it. At the same time the old version will be
// returned to Backbone.Radio.
Radio.noConflict = function () {
Backbone.Radio = previousRadio;
return this;
};
// Whether or not we're in DEBUG mode or not. DEBUG mode helps you
// get around the issues of lack of warnings when events are mis-typed.
Radio.DEBUG = false;
// Format debug text.
Radio._debugText = function (warning, eventName, channelName) {
return warning + (channelName ? ' on the ' + channelName + ' channel' : '') + ': "' + eventName + '"';
};
// This is the method that's called when an unregistered event was called.
// By default, it logs warning to the console. By overriding this you could
// make it throw an Error, for instance. This would make firing a nonexistent event
// have the same consequence as firing a nonexistent method on an Object.
Radio.debugLog = function (warning, eventName, channelName) {
if (Radio.DEBUG && console && console.warn) {
console.warn(Radio._debugText(warning, eventName, channelName));
}
};
var eventSplitter = /\s+/;
// An internal method used to handle Radio's method overloading for Requests.
// It's borrowed from Backbone.Events. It differs from Backbone's overload
// API (which is used in Backbone.Events) in that it doesn't support space-separated
// event names.
Radio._eventsApi = function (obj, action, name, rest) {
if (!name) {
return false;
}
var results = {};
// Handle event maps.
if ((typeof name === 'undefined' ? 'undefined' : babelHelpers.typeof(name)) === 'object') {
for (var key in name) {
var result = obj[action].apply(obj, [key, name[key]].concat(rest));
eventSplitter.test(key) ? _.extend(results, result) : results[key] = result;
}
return results;
}
// Handle space separated event names.
if (eventSplitter.test(name)) {
var names = name.split(eventSplitter);
for (var i = 0, l = names.length; i < l; i++) {
results[names[i]] = obj[action].apply(obj, [names[i]].concat(rest));
}
return results;
}
return false;
};
// An optimized way to execute callbacks.
Radio._callHandler = function (callback, context, args) {
var a1 = args[0],
a2 = args[1],
a3 = args[2];
switch (args.length) {
case 0:
return callback.call(context);
case 1:
return callback.call(context, a1);
case 2:
return callback.call(context, a1, a2);
case 3:
return callback.call(context, a1, a2, a3);
default:
return callback.apply(context, args);
}
};
// A helper used by `off` methods to the handler from the store
function removeHandler(store, name, callback, context) {
var event = store[name];
if ((!callback || callback === event.callback || callback === event.callback._callback) && (!context || context === event.context)) {
delete store[name];
return true;
}
}
function removeHandlers(store, name, callback, context) {
store || (store = {});
var names = name ? [name] : _.keys(store);
var matched = false;
for (var i = 0, length = names.length; i < length; i++) {
name = names[i];
// If there's no event by this name, log it and continue
// with the loop
if (!store[name]) {
continue;
}
if (removeHandler(store, name, callback, context)) {
matched = true;
}
}
return matched;
}
/*
* tune-in
* -------
* Get console logs of a channel's activity
*
*/
var _logs = {};
// This is to produce an identical function in both tuneIn and tuneOut,
// so that Backbone.Events unregisters it.
function _partial(channelName) {
return _logs[channelName] || (_logs[channelName] = _.bind(Radio.log, Radio, channelName));
}
_.extend(Radio, {
// Log information about the channel and event
log: function log(channelName, eventName) {
if (typeof console === 'undefined') {
return;
}
var args = _.toArray(arguments).slice(2);
console.log('[' + channelName + '] "' + eventName + '"', args);
},
// Logs all events on this channel to the console. It sets an
// internal value on the channel telling it we're listening,
// then sets a listener on the Backbone.Events
tuneIn: function tuneIn(channelName) {
var channel = Radio.channel(channelName);
channel._tunedIn = true;
channel.on('all', _partial(channelName));
return this;
},
// Stop logging all of the activities on this channel to the console
tuneOut: function tuneOut(channelName) {
var channel = Radio.channel(channelName);
channel._tunedIn = false;
channel.off('all', _partial(channelName));
delete _logs[channelName];
return this;
}
});
/*
* Backbone.Radio.Requests
* -----------------------
* A messaging system for requesting data.
*
*/
function makeCallback(callback) {
return _.isFunction(callback) ? callback : function () {
return callback;
};
}
Radio.Requests = {
// Make a request
request: function request(name) {
var args = _.toArray(arguments).slice(1);
var results = Radio._eventsApi(this, 'request', name, args);
if (results) {
return results;
}
var channelName = this.channelName;
var requests = this._requests;
// Check if we should log the request, and if so, do it
if (channelName && this._tunedIn) {
Radio.log.apply(this, [channelName, name].concat(args));
}
// If the request isn't handled, log it in DEBUG mode and exit
if (requests && (requests[name] || requests['default'])) {
var handler = requests[name] || requests['default'];
args = requests[name] ? args : arguments;
return Radio._callHandler(handler.callback, handler.context, args);
} else {
Radio.debugLog('An unhandled request was fired', name, channelName);
}
},
// Set up a handler for a request
reply: function reply(name, callback, context) {
if (Radio._eventsApi(this, 'reply', name, [callback, context])) {
return this;
}
this._requests || (this._requests = {});
if (this._requests[name]) {
Radio.debugLog('A request was overwritten', name, this.channelName);
}
this._requests[name] = {
callback: makeCallback(callback),
context: context || this
};
return this;
},
// Set up a handler that can only be requested once
replyOnce: function replyOnce(name, callback, context) {
if (Radio._eventsApi(this, 'replyOnce', name, [callback, context])) {
return this;
}
var self = this;
var once = _.once(function () {
self.stopReplying(name);
return makeCallback(callback).apply(this, arguments);
});
return this.reply(name, once, context);
},
// Remove handler(s)
stopReplying: function stopReplying(name, callback, context) {
if (Radio._eventsApi(this, 'stopReplying', name)) {
return this;
}
// Remove everything if there are no arguments passed
if (!name && !callback && !context) {
delete this._requests;
} else if (!removeHandlers(this._requests, name, callback, context)) {
Radio.debugLog('Attempted to remove the unregistered request', name, this.channelName);
}
return this;
}
};
/*
* Backbone.Radio.channel
* ----------------------
* Get a reference to a channel by name.
*
*/
Radio._channels = {};
Radio.channel = function (channelName) {
if (!channelName) {
throw new Error('You must provide a name for the channel.');
}
if (Radio._channels[channelName]) {
return Radio._channels[channelName];
} else {
return Radio._channels[channelName] = new Radio.Channel(channelName);
}
};
/*
* Backbone.Radio.Channel
* ----------------------
* A Channel is an object that extends from Backbone.Events,
* and Radio.Requests.
*
*/
Radio.Channel = function (channelName) {
this.channelName = channelName;
};
_.extend(Radio.Channel.prototype, Backbone.Events, Radio.Requests, {
// Remove all handlers from the messaging systems of this channel
reset: function reset() {
this.off();
this.stopListening();
this.stopReplying();
return this;
}
});
/*
* Top-level API
* -------------
* Supplies the 'top-level API' for working with Channels directly
* from Backbone.Radio.
*
*/
var channel;
var args;
var systems = [Backbone.Events, Radio.Requests];
_.each(systems, function (system) {
_.each(system, function (method, methodName) {
Radio[methodName] = function (channelName) {
args = _.toArray(arguments).slice(1);
channel = this.channel(channelName);
return channel[methodName].apply(channel, args);
};
});
});
Radio.reset = function (channelName) {
var channels = !channelName ? this._channels : [this._channels[channelName]];
_.each(channels, function (channel) {
channel.reset();
});
};
return Radio;
}));
//# sourceMappingURL=./backbone.radio.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
// Backbone.Radio v1.0.4
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("underscore"),require("backbone")):"function"==typeof define&&define.amd?define(["underscore","backbone"],n):(e.Backbone=e.Backbone||{},e.Backbone.Radio=n(e._,e.Backbone))}(this,function(e,n){"use strict";function t(e,n,t,r){var o=e[n];return t&&t!==o.callback&&t!==o.callback._callback||r&&r!==o.context?void 0:(delete e[n],!0)}function r(n,r,o,i){n||(n={});for(var s=r?[r]:e.keys(n),u=!1,a=0,c=s.length;c>a;a++)r=s[a],n[r]&&t(n,r,o,i)&&(u=!0);return u}function o(n){return l[n]||(l[n]=e.bind(a.log,a,n))}function i(n){return e.isFunction(n)?n:function(){return n}}e="default"in e?e["default"]:e,n="default"in n?n["default"]:n;var s={};s["typeof"]="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};var u=n.Radio,a=n.Radio={};a.VERSION="1.0.4",a.noConflict=function(){return n.Radio=u,this},a.DEBUG=!1,a._debugText=function(e,n,t){return e+(t?" on the "+t+" channel":"")+': "'+n+'"'},a.debugLog=function(e,n,t){a.DEBUG&&console&&console.warn&&console.warn(a._debugText(e,n,t))};var c=/\s+/;a._eventsApi=function(n,t,r,o){if(!r)return!1;var i={};if("object"===("undefined"==typeof r?"undefined":s["typeof"](r))){for(var u in r){var a=n[t].apply(n,[u,r[u]].concat(o));c.test(u)?e.extend(i,a):i[u]=a}return i}if(c.test(r)){for(var l=r.split(c),f=0,h=l.length;h>f;f++)i[l[f]]=n[t].apply(n,[l[f]].concat(o));return i}return!1},a._callHandler=function(e,n,t){var r=t[0],o=t[1],i=t[2];switch(t.length){case 0:return e.call(n);case 1:return e.call(n,r);case 2:return e.call(n,r,o);case 3:return e.call(n,r,o,i);default:return e.apply(n,t)}};var l={};e.extend(a,{log:function(n,t){if("undefined"!=typeof console){var r=e.toArray(arguments).slice(2);console.log("["+n+'] "'+t+'"',r)}},tuneIn:function(e){var n=a.channel(e);return n._tunedIn=!0,n.on("all",o(e)),this},tuneOut:function(e){var n=a.channel(e);return n._tunedIn=!1,n.off("all",o(e)),delete l[e],this}}),a.Requests={request:function(n){var t=e.toArray(arguments).slice(1),r=a._eventsApi(this,"request",n,t);if(r)return r;var o=this.channelName,i=this._requests;if(o&&this._tunedIn&&a.log.apply(this,[o,n].concat(t)),i&&(i[n]||i["default"])){var s=i[n]||i["default"];return t=i[n]?t:arguments,a._callHandler(s.callback,s.context,t)}a.debugLog("An unhandled request was fired",n,o)},reply:function(e,n,t){return a._eventsApi(this,"reply",e,[n,t])?this:(this._requests||(this._requests={}),this._requests[e]&&a.debugLog("A request was overwritten",e,this.channelName),this._requests[e]={callback:i(n),context:t||this},this)},replyOnce:function(n,t,r){if(a._eventsApi(this,"replyOnce",n,[t,r]))return this;var o=this,s=e.once(function(){return o.stopReplying(n),i(t).apply(this,arguments)});return this.reply(n,s,r)},stopReplying:function(e,n,t){return a._eventsApi(this,"stopReplying",e)?this:(e||n||t?r(this._requests,e,n,t)||a.debugLog("Attempted to remove the unregistered request",e,this.channelName):delete this._requests,this)}},a._channels={},a.channel=function(e){if(!e)throw new Error("You must provide a name for the channel.");return a._channels[e]?a._channels[e]:a._channels[e]=new a.Channel(e)},a.Channel=function(e){this.channelName=e},e.extend(a.Channel.prototype,n.Events,a.Requests,{reset:function(){return this.off(),this.stopListening(),this.stopReplying(),this}});var f,h,d=[n.Events,a.Requests];return e.each(d,function(n){e.each(n,function(n,t){a[t]=function(n){return h=e.toArray(arguments).slice(1),f=this.channel(n),f[t].apply(f,h)}})}),a.reset=function(n){var t=n?[this._channels[n]]:this._channels;e.each(t,function(e){e.reset()})},a});
//# sourceMappingURL=backbone.radio.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,233 @@
import gulp from 'gulp';
import loadPlugins from 'gulp-load-plugins';
import del from 'del';
import glob from 'glob';
import path from 'path';
import {Instrumenter} from 'isparta';
import webpack from 'webpack';
import webpackStream from 'webpack-stream';
import _ from 'underscore';
import rollup from 'rollup';
import babel from 'rollup-plugin-babel';
import preset from 'babel-preset-es2015-rollup';
import fs from 'fs';
import mkdirp from 'mkdirp';
import mochaGlobals from './test/setup/.globals';
import manifest from './package.json';
// Load all of our Gulp plugins
const $ = loadPlugins();
// Gather the library data from `package.json`
const config = manifest.babelBoilerplateOptions;
const mainFile = manifest.main;
const destinationFolder = path.dirname(mainFile);
const exportFileName = path.basename(mainFile, path.extname(mainFile));
function cleanDist(done) {
del([destinationFolder]).then(() => done());
}
function cleanTmp(done) {
del(['tmp']).then(() => done());
}
function onError() {
$.util.beep();
}
// Lint a set of files
function lint(files) {
return gulp.src(files)
.pipe($.plumber())
.pipe($.eslint())
.pipe($.eslint.format())
.pipe($.eslint.failOnError())
.pipe($.jscs())
.pipe($.jscs.reporter())
.pipe($.jscs.reporter('fail'))
.on('error', onError);
}
function lintSrc() {
return lint('src/**/*.js');
}
function lintTest() {
return lint('test/**/*.js');
}
function lintGulpfile() {
return lint('gulpfile.babel.js');
}
function getBanner() {
var banner = '// Backbone.Radio v<%= version %>\n';
return _.template(banner)(manifest);
}
function build(done) {
rollup.rollup({
entry: path.join('src', config.entryFileName),
plugins: [
babel({
sourceMaps: true,
presets: [preset],
babelrc: false
})
]
}).then(function(bundle) {
var banner = getBanner();
var result = bundle.generate({
banner: banner,
format: 'umd',
sourceMap: 'inline',
sourceMapSource: config.entryFileName + '.js',
sourceMapFile: exportFileName + '.js',
moduleName: config.mainVarName
});
var code = _.template(result.code.toString())(manifest) +
`\n//# sourceMappingURL=./${exportFileName}.js.map`;
// Write the generated sourcemap
mkdirp.sync(destinationFolder);
fs.writeFileSync(path.join(destinationFolder, exportFileName + '.js'), code);
fs.writeFileSync(path.join(destinationFolder, `${exportFileName}.js.map`), result.map.toString());
$.file(exportFileName + '.js', code, { src: true })
.pipe($.plumber())
.pipe($.sourcemaps.init({ loadMaps: true }))
.pipe($.sourcemaps.write('./', {addComment: false}))
.pipe(gulp.dest(destinationFolder))
.pipe($.filter(['*', '!**/*.js.map']))
.pipe($.rename(exportFileName + '.min.js'))
.pipe($.sourcemaps.init({ loadMaps: true }))
.pipe($.uglify())
.pipe($.sourcemaps.write('./'))
.pipe($.header(banner))
.pipe(gulp.dest(destinationFolder))
.on('end', done);
}).catch(console.error);
}
function _mocha() {
return gulp.src(['test/setup/node.js', 'test/unit/**/*.js'], {read: false})
.pipe($.mocha({
reporter: 'dot',
globals: Object.keys(mochaGlobals.globals),
ignoreLeaks: false
}));
}
function _registerBabel() {
require('babel-register');
}
function test() {
_registerBabel();
return _mocha();
}
function coverage(done) {
_registerBabel();
gulp.src(['src/**/*.js'])
.pipe($.istanbul({ instrumenter: Instrumenter }))
.pipe($.istanbul.hookRequire())
.on('finish', () => {
return test()
.pipe($.istanbul.writeReports())
.on('end', done);
});
}
const watchFiles = ['src/**/*', 'test/**/*', 'package.json', '**/.eslintrc', '.jscsrc'];
// Run the headless unit tests as you make changes.
function watch() {
gulp.watch(watchFiles, ['test']);
}
function testBrowser() {
// Our testing bundle is made up of our unit tests, which
// should individually load up pieces of our application.
// We also include the browser setup file.
const testFiles = glob.sync('./test/unit/**/*.js');
const allFiles = ['./test/setup/browser.js'].concat(testFiles);
// Lets us differentiate between the first build and subsequent builds
var firstBuild = true;
// This empty stream might seem like a hack, but we need to specify all of our files through
// the `entry` option of webpack. Otherwise, it ignores whatever file(s) are placed in here.
return gulp.src('')
.pipe($.plumber())
.pipe(webpackStream({
watch: true,
entry: allFiles,
output: {
filename: '__spec-build.js'
},
module: {
loaders: [
// This is what allows us to author in future JavaScript
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },
// This allows the test setup scripts to load `package.json`
{ test: /\.json$/, exclude: /node_modules/, loader: 'json-loader' }
]
},
plugins: [
// By default, webpack does `n=>n` compilation with entry files. This concatenates
// them into a single chunk.
new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })
],
devtool: 'inline-source-map'
}, null, function() {
if (firstBuild) {
$.livereload.listen({port: 35729, host: 'localhost', start: true});
var watcher = gulp.watch(watchFiles, ['lint']);
} else {
$.livereload.reload('./tmp/__spec-build.js');
}
firstBuild = false;
}))
.pipe(gulp.dest('./tmp'));
}
// Remove the built files
gulp.task('clean', cleanDist);
// Remove our temporary files
gulp.task('clean-tmp', cleanTmp);
// Lint our source code
gulp.task('lint-src', lintSrc);
// Lint our test code
gulp.task('lint-test', lintTest);
// Lint this file
gulp.task('lint-gulpfile', lintGulpfile);
// Lint everything
gulp.task('lint', ['lint-src', 'lint-test', 'lint-gulpfile']);
// Build two versions of the library
gulp.task('build', ['lint', 'clean'], build);
// Lint and run our tests
gulp.task('test', ['lint'], test);
// Set up coverage and run tests
gulp.task('coverage', ['lint'], coverage);
// Set up a livereload environment for our spec runner `test/runner.html`
gulp.task('test-browser', ['lint', 'clean-tmp'], testBrowser);
// Run the headless unit tests as you make changes.
gulp.task('watch', watch);
// An alias of test
gulp.task('default', ['test']);

View File

@@ -0,0 +1,88 @@
{
"name": "backbone.radio",
"description": "Messaging patterns for Backbone applications.",
"homepage": "https://github.com/marionettejs/backbone.radio",
"version": "1.0.4",
"main": "build/backbone.radio.js",
"keywords": [
"backbone",
"marionette",
"decoupled",
"pubsub",
"publish",
"subscribe",
"messaging",
"architecture",
"spa"
],
"licenses": [
{
"type": "MIT",
"url": "https://github.com/marionettejs/backbone.radio/blob/master/LICENSE"
}
],
"scripts": {
"test": "gulp",
"test-browser": "gulp test-browser",
"build": "gulp build",
"coverage": "gulp coverage"
},
"author": {
"name": "Jmeas",
"email": "jellyes2@gmail.com",
"web": "http://jmeas.com"
},
"bugs": {
"url": "https://github.com/marionettejs/backbone.radio/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/marionettejs/backbone.radio.git"
},
"github": "https://github.com/marionettejs/backbone.radio",
"dependencies": {
"backbone": "1.0.0 - 1.3.x",
"underscore": "1.4.4 - 1.8.3"
},
"devDependencies": {
"babel-core": "^6.3.26",
"babel-eslint": "^4.1.6",
"babel-loader": "^6.2.0",
"babel-polyfill": "^6.3.14",
"babel-preset-es2015": "^6.3.13",
"babel-preset-es2015-rollup": "^1.1.1",
"babel-register": "^6.3.13",
"chai": "^3.4.1",
"del": "^2.2.0",
"glob": "^6.0.3",
"gulp": "^3.9.0",
"gulp-eslint": "^1.1.1",
"gulp-file": "^0.2.0",
"gulp-filter": "^3.0.0",
"gulp-header": "^1.7.1",
"gulp-istanbul": "^0.10.3",
"gulp-jscs": "^3.0.0",
"gulp-livereload": "^3.8.1",
"gulp-load-plugins": "^1.1.0",
"gulp-mocha": "^2.2.0",
"gulp-plumber": "^1.0.1",
"gulp-rename": "^1.2.2",
"gulp-sourcemaps": "^1.6.0",
"gulp-uglify": "^1.5.1",
"gulp-util": "^3.0.7",
"isparta": "^4.0.0",
"json-loader": "^0.5.3",
"mkdirp": "^0.5.1",
"mocha": "^2.3.4",
"rollup": "^0.25.4",
"rollup-plugin-babel": "^2.4.0",
"sinon": "^1.17.2",
"sinon-chai": "^2.8.0",
"webpack": "^1.12.9",
"webpack-stream": "^3.1.0"
},
"babelBoilerplateOptions": {
"entryFileName": "backbone.radio",
"mainVarName": "Backbone.Radio"
}
}

View File

@@ -0,0 +1,323 @@
import _ from 'underscore';
import Backbone from 'backbone';
var previousRadio = Backbone.Radio;
var Radio = Backbone.Radio = {};
Radio.VERSION = '<%= version %>';
// This allows you to run multiple instances of Radio on the same
// webapp. After loading the new version, call `noConflict()` to
// get a reference to it. At the same time the old version will be
// returned to Backbone.Radio.
Radio.noConflict = function() {
Backbone.Radio = previousRadio;
return this;
};
// Whether or not we're in DEBUG mode or not. DEBUG mode helps you
// get around the issues of lack of warnings when events are mis-typed.
Radio.DEBUG = false;
// Format debug text.
Radio._debugText = function(warning, eventName, channelName) {
return warning + (channelName ? ' on the ' + channelName + ' channel' : '') +
': "' + eventName + '"';
};
// This is the method that's called when an unregistered event was called.
// By default, it logs warning to the console. By overriding this you could
// make it throw an Error, for instance. This would make firing a nonexistent event
// have the same consequence as firing a nonexistent method on an Object.
Radio.debugLog = function(warning, eventName, channelName) {
if (Radio.DEBUG && console && console.warn) {
console.warn(Radio._debugText(warning, eventName, channelName));
}
};
var eventSplitter = /\s+/;
// An internal method used to handle Radio's method overloading for Requests.
// It's borrowed from Backbone.Events. It differs from Backbone's overload
// API (which is used in Backbone.Events) in that it doesn't support space-separated
// event names.
Radio._eventsApi = function(obj, action, name, rest) {
if (!name) {
return false;
}
var results = {};
// Handle event maps.
if (typeof name === 'object') {
for (var key in name) {
var result = obj[action].apply(obj, [key, name[key]].concat(rest));
eventSplitter.test(key) ? _.extend(results, result) : results[key] = result;
}
return results;
}
// Handle space separated event names.
if (eventSplitter.test(name)) {
var names = name.split(eventSplitter);
for (var i = 0, l = names.length; i < l; i++) {
results[names[i]] = obj[action].apply(obj, [names[i]].concat(rest));
}
return results;
}
return false;
};
// An optimized way to execute callbacks.
Radio._callHandler = function(callback, context, args) {
var a1 = args[0], a2 = args[1], a3 = args[2];
switch (args.length) {
case 0: return callback.call(context);
case 1: return callback.call(context, a1);
case 2: return callback.call(context, a1, a2);
case 3: return callback.call(context, a1, a2, a3);
default: return callback.apply(context, args);
}
};
// A helper used by `off` methods to the handler from the store
function removeHandler(store, name, callback, context) {
var event = store[name];
if (
(!callback || (callback === event.callback || callback === event.callback._callback)) &&
(!context || (context === event.context))
) {
delete store[name];
return true;
}
}
function removeHandlers(store, name, callback, context) {
store || (store = {});
var names = name ? [name] : _.keys(store);
var matched = false;
for (var i = 0, length = names.length; i < length; i++) {
name = names[i];
// If there's no event by this name, log it and continue
// with the loop
if (!store[name]) {
continue;
}
if (removeHandler(store, name, callback, context)) {
matched = true;
}
}
return matched;
}
/*
* tune-in
* -------
* Get console logs of a channel's activity
*
*/
var _logs = {};
// This is to produce an identical function in both tuneIn and tuneOut,
// so that Backbone.Events unregisters it.
function _partial(channelName) {
return _logs[channelName] || (_logs[channelName] = _.bind(Radio.log, Radio, channelName));
}
_.extend(Radio, {
// Log information about the channel and event
log: function(channelName, eventName) {
if (typeof console === 'undefined') { return; }
var args = _.toArray(arguments).slice(2);
console.log('[' + channelName + '] "' + eventName + '"', args);
},
// Logs all events on this channel to the console. It sets an
// internal value on the channel telling it we're listening,
// then sets a listener on the Backbone.Events
tuneIn: function(channelName) {
var channel = Radio.channel(channelName);
channel._tunedIn = true;
channel.on('all', _partial(channelName));
return this;
},
// Stop logging all of the activities on this channel to the console
tuneOut: function(channelName) {
var channel = Radio.channel(channelName);
channel._tunedIn = false;
channel.off('all', _partial(channelName));
delete _logs[channelName];
return this;
}
});
/*
* Backbone.Radio.Requests
* -----------------------
* A messaging system for requesting data.
*
*/
function makeCallback(callback) {
return _.isFunction(callback) ? callback : function() { return callback; };
}
Radio.Requests = {
// Make a request
request: function(name) {
var args = _.toArray(arguments).slice(1);
var results = Radio._eventsApi(this, 'request', name, args);
if (results) {
return results;
}
var channelName = this.channelName;
var requests = this._requests;
// Check if we should log the request, and if so, do it
if (channelName && this._tunedIn) {
Radio.log.apply(this, [channelName, name].concat(args));
}
// If the request isn't handled, log it in DEBUG mode and exit
if (requests && (requests[name] || requests['default'])) {
var handler = requests[name] || requests['default'];
args = requests[name] ? args : arguments;
return Radio._callHandler(handler.callback, handler.context, args);
} else {
Radio.debugLog('An unhandled request was fired', name, channelName);
}
},
// Set up a handler for a request
reply: function(name, callback, context) {
if (Radio._eventsApi(this, 'reply', name, [callback, context])) {
return this;
}
this._requests || (this._requests = {});
if (this._requests[name]) {
Radio.debugLog('A request was overwritten', name, this.channelName);
}
this._requests[name] = {
callback: makeCallback(callback),
context: context || this
};
return this;
},
// Set up a handler that can only be requested once
replyOnce: function(name, callback, context) {
if (Radio._eventsApi(this, 'replyOnce', name, [callback, context])) {
return this;
}
var self = this;
var once = _.once(function() {
self.stopReplying(name);
return makeCallback(callback).apply(this, arguments);
});
return this.reply(name, once, context);
},
// Remove handler(s)
stopReplying: function(name, callback, context) {
if (Radio._eventsApi(this, 'stopReplying', name)) {
return this;
}
// Remove everything if there are no arguments passed
if (!name && !callback && !context) {
delete this._requests;
} else if (!removeHandlers(this._requests, name, callback, context)) {
Radio.debugLog('Attempted to remove the unregistered request', name, this.channelName);
}
return this;
}
};
/*
* Backbone.Radio.channel
* ----------------------
* Get a reference to a channel by name.
*
*/
Radio._channels = {};
Radio.channel = function(channelName) {
if (!channelName) {
throw new Error('You must provide a name for the channel.');
}
if (Radio._channels[channelName]) {
return Radio._channels[channelName];
} else {
return (Radio._channels[channelName] = new Radio.Channel(channelName));
}
};
/*
* Backbone.Radio.Channel
* ----------------------
* A Channel is an object that extends from Backbone.Events,
* and Radio.Requests.
*
*/
Radio.Channel = function(channelName) {
this.channelName = channelName;
};
_.extend(Radio.Channel.prototype, Backbone.Events, Radio.Requests, {
// Remove all handlers from the messaging systems of this channel
reset: function() {
this.off();
this.stopListening();
this.stopReplying();
return this;
}
});
/*
* Top-level API
* -------------
* Supplies the 'top-level API' for working with Channels directly
* from Backbone.Radio.
*
*/
var channel, args, systems = [Backbone.Events, Radio.Requests];
_.each(systems, function(system) {
_.each(system, function(method, methodName) {
Radio[methodName] = function(channelName) {
args = _.toArray(arguments).slice(1);
channel = this.channel(channelName);
return channel[methodName].apply(channel, args);
};
});
});
Radio.reset = function(channelName) {
var channels = !channelName ? this._channels : [this._channels[channelName]];
_.each(channels, function(channel) { channel.reset();});
};
export default Radio;

View File

@@ -0,0 +1,58 @@
{
"name": "backbone.wreqr",
"version": "1.4.0",
"homepage": "https://github.com/marionettejs/backbone.wreqr",
"authors": [
"Derick Bailey"
],
"description": "A Simple Service Bus For Backbone and Backbone.Marionette",
"main": "lib/backbone.wreqr.js",
"keywords": [
"backbone",
"plugin",
"computed",
"field",
"model"
],
"dependencies": {
"backbone": ">=0.9.9 <=1.3.x",
"underscore": ">=1.3.3 <=1.8.3"
},
"devDependencies": {
"grunt": "0.4.0",
"grunt-contrib-jasmine": "0.4.1",
"grunt-contrib-uglify": "0.1.2",
"grunt-contrib-concat": "0.1.3",
"grunt-contrib-jshint": "0.2.0",
"grunt-contrib-watch": "0.3.1",
"grunt-contrib-connect": "0.2.0",
"grunt-template-jasmine-istanbul": "0.2.0",
"grunt-preprocess": "2.0.0",
"grunt-plato": "0.1.5"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"public",
"spec",
".gitignore",
".jshintrc",
".travis.yml",
"Gruntfile.js",
"component.json",
"package.json"
],
"_release": "1.4.0",
"_resolution": {
"type": "version",
"tag": "v1.4.0",
"commit": "ce4665f7e13ec46d66fe9215f5a91199e29dff51"
},
"_source": "https://github.com/marionettejs/backbone.wreqr.git",
"_target": "^1.0.0",
"_originalSource": "backbone.wreqr"
}

View File

@@ -0,0 +1,84 @@
# Change log
### v1.4.0
* Align code to be able to work with lodash 4.x in addition to underscore
### v1.3.7
* Bump version range of backbone.
### v1.3.6
* Bump version range of backbone.
### v1.3.5
* Bump version range of backbone.
### v1.3.4
* Bump version range of backbone.
### v1.3.3
* Bump version range of backbone and underscore support.
### v1.3.2
* Increase underscore range
* Minor underscore refactors
### v1.3.1
* Fix UMD setup and build process
### v1.3.0
* Add Wreqr.noConflict()
* Add Wreqr.VERSION
* Fixed a bug where reqres would not return a value using the 'top-level' Channel API.
### v1.2.1
* Remove AMD builds and add a single UMD style build.
### v1.2.0
* Adds Radio, allowing you to create explicit namespaces called Channels. A Channel is made up of
an instance of each of the three messaging systems.
### v1.1.0
* Removes the Error on unhandled commands/requests
### v1.0.1
* update dependencies
### v1.0.0
* major version release
* minor fixes
### v0.2.0
* Handlers (Commands/RequestResponse)
* **BREAKING:** renamed `addHandler` to `setHandler` to clarify the point of single handlers per named item
* Allow an `initialize` function when extending from the base type
* Added a `setHandlers` function that takes an object literal as the parameter, to configure multiple handlers in a single call
* Commands
* Introduced Wreqr.CommandStorage to store commands for later execution
* When a command has no handler, it will be stored for later execution
* When a handler for a stored command is added, the stored command will be
executed
* Updated build process to use Grunt v0.4
### v0.1.1
* Fixed "option strict" to be "use strict" ... #facepalm :P
* Added jam package config
### v0.1.0
* Fix calls to `.apply` to account for IE < 9 throwing an error when `arguments` is null or undefined
### v0.0.1
* Commands
* Can specify multiple arguments for `execute` method
* RequestResponse
* Can specify multiple arguments for `request` method
### v0.0.0
* Initial release

View File

@@ -0,0 +1,5 @@
# Backbone.Wreqr
Copyright (C)2012 Derick Bailey, Muted Solutions, LLC
Distributed Under MIT License

View File

@@ -0,0 +1,49 @@
{
"name": "backbone.wreqr",
"version": "1.4.0",
"homepage": "https://github.com/marionettejs/backbone.wreqr",
"authors": [
"Derick Bailey"
],
"description": "A Simple Service Bus For Backbone and Backbone.Marionette",
"main": "lib/backbone.wreqr.js",
"keywords": [
"backbone",
"plugin",
"computed",
"field",
"model"
],
"dependencies": {
"backbone": ">=0.9.9 <=1.3.x",
"underscore": ">=1.3.3 <=1.8.3"
},
"devDependencies": {
"grunt": "0.4.0",
"grunt-contrib-jasmine": "0.4.1",
"grunt-contrib-uglify": "0.1.2",
"grunt-contrib-concat": "0.1.3",
"grunt-contrib-jshint": "0.2.0",
"grunt-contrib-watch": "0.3.1",
"grunt-contrib-connect": "0.2.0",
"grunt-template-jasmine-istanbul": "0.2.0",
"grunt-preprocess": "2.0.0",
"grunt-plato": "0.1.5"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"public",
"spec",
".gitignore",
".jshintrc",
".travis.yml",
"Gruntfile.js",
"component.json",
"package.json"
]
}

View File

@@ -0,0 +1,435 @@
// Backbone.Wreqr (Backbone.Marionette)
// ----------------------------------
// v1.4.0
//
// Copyright (c)2016 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
//
// http://github.com/marionettejs/backbone.wreqr
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['backbone', 'underscore'], function(Backbone, _) {
return factory(Backbone, _);
});
} else if (typeof exports !== 'undefined') {
var Backbone = require('backbone');
var _ = require('underscore');
module.exports = factory(Backbone, _);
} else {
factory(root.Backbone, root._);
}
}(this, function(Backbone, _) {
"use strict";
var previousWreqr = Backbone.Wreqr;
var Wreqr = Backbone.Wreqr = {};
Backbone.Wreqr.VERSION = '1.4.0';
Backbone.Wreqr.noConflict = function () {
Backbone.Wreqr = previousWreqr;
return this;
};
// Handlers
// --------
// A registry of functions to call, given a name
Wreqr.Handlers = (function(Backbone, _){
"use strict";
// Constructor
// -----------
var Handlers = function(options){
this.options = options;
this._wreqrHandlers = {};
if (_.isFunction(this.initialize)){
this.initialize(options);
}
};
Handlers.extend = Backbone.Model.extend;
// Instance Members
// ----------------
_.extend(Handlers.prototype, Backbone.Events, {
// Add multiple handlers using an object literal configuration
setHandlers: function(handlers){
_.each(handlers, _.bind(function(handler, name){
var context = null;
if (_.isObject(handler) && !_.isFunction(handler)){
context = handler.context;
handler = handler.callback;
}
this.setHandler(name, handler, context);
}, this));
},
// Add a handler for the given name, with an
// optional context to run the handler within
setHandler: function(name, handler, context){
var config = {
callback: handler,
context: context
};
this._wreqrHandlers[name] = config;
this.trigger("handler:add", name, handler, context);
},
// Determine whether or not a handler is registered
hasHandler: function(name){
return !! this._wreqrHandlers[name];
},
// Get the currently registered handler for
// the specified name. Throws an exception if
// no handler is found.
getHandler: function(name){
var config = this._wreqrHandlers[name];
if (!config){
return;
}
return function(){
return config.callback.apply(config.context, arguments);
};
},
// Remove a handler for the specified name
removeHandler: function(name){
delete this._wreqrHandlers[name];
},
// Remove all handlers from this registry
removeAllHandlers: function(){
this._wreqrHandlers = {};
}
});
return Handlers;
})(Backbone, _);
// Wreqr.CommandStorage
// --------------------
//
// Store and retrieve commands for execution.
Wreqr.CommandStorage = (function(){
"use strict";
// Constructor function
var CommandStorage = function(options){
this.options = options;
this._commands = {};
if (_.isFunction(this.initialize)){
this.initialize(options);
}
};
// Instance methods
_.extend(CommandStorage.prototype, Backbone.Events, {
// Get an object literal by command name, that contains
// the `commandName` and the `instances` of all commands
// represented as an array of arguments to process
getCommands: function(commandName){
var commands = this._commands[commandName];
// we don't have it, so add it
if (!commands){
// build the configuration
commands = {
command: commandName,
instances: []
};
// store it
this._commands[commandName] = commands;
}
return commands;
},
// Add a command by name, to the storage and store the
// args for the command
addCommand: function(commandName, args){
var command = this.getCommands(commandName);
command.instances.push(args);
},
// Clear all commands for the given `commandName`
clearCommands: function(commandName){
var command = this.getCommands(commandName);
command.instances = [];
}
});
return CommandStorage;
})();
// Wreqr.Commands
// --------------
//
// A simple command pattern implementation. Register a command
// handler and execute it.
Wreqr.Commands = (function(Wreqr, _){
"use strict";
return Wreqr.Handlers.extend({
// default storage type
storageType: Wreqr.CommandStorage,
constructor: function(options){
this.options = options || {};
this._initializeStorage(this.options);
this.on("handler:add", this._executeCommands, this);
Wreqr.Handlers.prototype.constructor.apply(this, arguments);
},
// Execute a named command with the supplied args
execute: function(name){
name = arguments[0];
var args = _.rest(arguments);
if (this.hasHandler(name)){
this.getHandler(name).apply(this, args);
} else {
this.storage.addCommand(name, args);
}
},
// Internal method to handle bulk execution of stored commands
_executeCommands: function(name, handler, context){
var command = this.storage.getCommands(name);
// loop through and execute all the stored command instances
_.each(command.instances, function(args){
handler.apply(context, args);
});
this.storage.clearCommands(name);
},
// Internal method to initialize storage either from the type's
// `storageType` or the instance `options.storageType`.
_initializeStorage: function(options){
var storage;
var StorageType = options.storageType || this.storageType;
if (_.isFunction(StorageType)){
storage = new StorageType();
} else {
storage = StorageType;
}
this.storage = storage;
}
});
})(Wreqr, _);
// Wreqr.RequestResponse
// ---------------------
//
// A simple request/response implementation. Register a
// request handler, and return a response from it
Wreqr.RequestResponse = (function(Wreqr, _){
"use strict";
return Wreqr.Handlers.extend({
request: function(name){
if (this.hasHandler(name)) {
return this.getHandler(name).apply(this, _.rest(arguments));
}
}
});
})(Wreqr, _);
// Event Aggregator
// ----------------
// A pub-sub object that can be used to decouple various parts
// of an application through event-driven architecture.
Wreqr.EventAggregator = (function(Backbone, _){
"use strict";
var EA = function(){};
// Copy the `extend` function used by Backbone's classes
EA.extend = Backbone.Model.extend;
// Copy the basic Backbone.Events on to the event aggregator
_.extend(EA.prototype, Backbone.Events);
return EA;
})(Backbone, _);
// Wreqr.Channel
// --------------
//
// An object that wraps the three messaging systems:
// EventAggregator, RequestResponse, Commands
Wreqr.Channel = (function(Wreqr){
"use strict";
var Channel = function(channelName) {
this.vent = new Backbone.Wreqr.EventAggregator();
this.reqres = new Backbone.Wreqr.RequestResponse();
this.commands = new Backbone.Wreqr.Commands();
this.channelName = channelName;
};
_.extend(Channel.prototype, {
// Remove all handlers from the messaging systems of this channel
reset: function() {
this.vent.off();
this.vent.stopListening();
this.reqres.removeAllHandlers();
this.commands.removeAllHandlers();
return this;
},
// Connect a hash of events; one for each messaging system
connectEvents: function(hash, context) {
this._connect('vent', hash, context);
return this;
},
connectCommands: function(hash, context) {
this._connect('commands', hash, context);
return this;
},
connectRequests: function(hash, context) {
this._connect('reqres', hash, context);
return this;
},
// Attach the handlers to a given message system `type`
_connect: function(type, hash, context) {
if (!hash) {
return;
}
context = context || this;
var method = (type === 'vent') ? 'on' : 'setHandler';
_.each(hash, _.bind(function(fn, eventName) {
this[type][method](eventName, _.bind(fn, context));
}, this));
}
});
return Channel;
})(Wreqr);
// Wreqr.Radio
// --------------
//
// An object that lets you communicate with many channels.
Wreqr.radio = (function(Wreqr, _){
"use strict";
var Radio = function() {
this._channels = {};
this.vent = {};
this.commands = {};
this.reqres = {};
this._proxyMethods();
};
_.extend(Radio.prototype, {
channel: function(channelName) {
if (!channelName) {
throw new Error('Channel must receive a name');
}
return this._getChannel( channelName );
},
_getChannel: function(channelName) {
var channel = this._channels[channelName];
if(!channel) {
channel = new Wreqr.Channel(channelName);
this._channels[channelName] = channel;
}
return channel;
},
_proxyMethods: function() {
_.each(['vent', 'commands', 'reqres'], _.bind(function(system) {
_.each( messageSystems[system], _.bind(function(method) {
this[system][method] = proxyMethod(this, system, method);
}, this));
}, this));
}
});
var messageSystems = {
vent: [
'on',
'off',
'trigger',
'once',
'stopListening',
'listenTo',
'listenToOnce'
],
commands: [
'execute',
'setHandler',
'setHandlers',
'removeHandler',
'removeAllHandlers'
],
reqres: [
'request',
'setHandler',
'setHandlers',
'removeHandler',
'removeAllHandlers'
]
};
var proxyMethod = function(radio, system, method) {
return function(channelName) {
var messageSystem = radio._getChannel(channelName)[system];
return messageSystem[method].apply(messageSystem, _.rest(arguments));
};
};
return new Radio();
})(Wreqr, _);
return Backbone.Wreqr;
}));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
// Backbone.Wreqr (Backbone.Marionette)
// ----------------------------------
// v1.4.0
//
// Copyright (c)2016 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
//
// http://github.com/marionettejs/backbone.wreqr
!function(a,b){if("function"==typeof define&&define.amd)define(["backbone","underscore"],function(a,c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("backbone"),d=require("underscore");module.exports=b(c,d)}else b(a.Backbone,a._)}(this,function(a,b){"use strict";var c=a.Wreqr,d=a.Wreqr={};return a.Wreqr.VERSION="1.4.0",a.Wreqr.noConflict=function(){return a.Wreqr=c,this},d.Handlers=function(a,b){var c=function(a){this.options=a,this._wreqrHandlers={},b.isFunction(this.initialize)&&this.initialize(a)};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events,{setHandlers:function(a){b.each(a,b.bind(function(a,c){var d=null;b.isObject(a)&&!b.isFunction(a)&&(d=a.context,a=a.callback),this.setHandler(c,a,d)},this))},setHandler:function(a,b,c){var d={callback:b,context:c};this._wreqrHandlers[a]=d,this.trigger("handler:add",a,b,c)},hasHandler:function(a){return!!this._wreqrHandlers[a]},getHandler:function(a){var b=this._wreqrHandlers[a];if(b)return function(){return b.callback.apply(b.context,arguments)}},removeHandler:function(a){delete this._wreqrHandlers[a]},removeAllHandlers:function(){this._wreqrHandlers={}}}),c}(a,b),d.CommandStorage=function(){var c=function(a){this.options=a,this._commands={},b.isFunction(this.initialize)&&this.initialize(a)};return b.extend(c.prototype,a.Events,{getCommands:function(a){var b=this._commands[a];return b||(b={command:a,instances:[]},this._commands[a]=b),b},addCommand:function(a,b){var c=this.getCommands(a);c.instances.push(b)},clearCommands:function(a){var b=this.getCommands(a);b.instances=[]}}),c}(),d.Commands=function(a,b){return a.Handlers.extend({storageType:a.CommandStorage,constructor:function(b){this.options=b||{},this._initializeStorage(this.options),this.on("handler:add",this._executeCommands,this),a.Handlers.prototype.constructor.apply(this,arguments)},execute:function(a){a=arguments[0];var c=b.rest(arguments);this.hasHandler(a)?this.getHandler(a).apply(this,c):this.storage.addCommand(a,c)},_executeCommands:function(a,c,d){var e=this.storage.getCommands(a);b.each(e.instances,function(a){c.apply(d,a)}),this.storage.clearCommands(a)},_initializeStorage:function(a){var c,d=a.storageType||this.storageType;c=b.isFunction(d)?new d:d,this.storage=c}})}(d,b),d.RequestResponse=function(a,b){return a.Handlers.extend({request:function(a){return this.hasHandler(a)?this.getHandler(a).apply(this,b.rest(arguments)):void 0}})}(d,b),d.EventAggregator=function(a,b){var c=function(){};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events),c}(a,b),d.Channel=function(c){var d=function(b){this.vent=new a.Wreqr.EventAggregator,this.reqres=new a.Wreqr.RequestResponse,this.commands=new a.Wreqr.Commands,this.channelName=b};return b.extend(d.prototype,{reset:function(){return this.vent.off(),this.vent.stopListening(),this.reqres.removeAllHandlers(),this.commands.removeAllHandlers(),this},connectEvents:function(a,b){return this._connect("vent",a,b),this},connectCommands:function(a,b){return this._connect("commands",a,b),this},connectRequests:function(a,b){return this._connect("reqres",a,b),this},_connect:function(a,c,d){if(c){d=d||this;var e="vent"===a?"on":"setHandler";b.each(c,b.bind(function(c,f){this[a][e](f,b.bind(c,d))},this))}}}),d}(d),d.radio=function(a,b){var c=function(){this._channels={},this.vent={},this.commands={},this.reqres={},this._proxyMethods()};b.extend(c.prototype,{channel:function(a){if(!a)throw new Error("Channel must receive a name");return this._getChannel(a)},_getChannel:function(b){var c=this._channels[b];return c||(c=new a.Channel(b),this._channels[b]=c),c},_proxyMethods:function(){b.each(["vent","commands","reqres"],b.bind(function(a){b.each(d[a],b.bind(function(b){this[a][b]=e(this,a,b)},this))},this))}});var d={vent:["on","off","trigger","once","stopListening","listenTo","listenToOnce"],commands:["execute","setHandler","setHandlers","removeHandler","removeAllHandlers"],reqres:["request","setHandler","setHandlers","removeHandler","removeAllHandlers"]},e=function(a,c,d){return function(e){var f=a._getChannel(e)[c];return f[d].apply(f,b.rest(arguments))}};return new c}(d,b),a.Wreqr});
//# sourceMappingURL=backbone.wreqr.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,186 @@
<h1 align="center">Backbone.Wreqr</h1>
<p align="center">
<a title='Build Status' href="https://travis-ci.org/marionettejs/backbone.wreqr">
<img src='https://travis-ci.org/marionettejs/backbone.wreqr.svg' />
</a>
</p>
A simple infrastructure based on [messaging patterns](http://www.eaipatterns.com/)
and service bus implementations for decoupling [Backbone](http://backbonejs.org)
and [Backbone.Marionette](http://marionettejs.com) applications.
**Notice:** In the next major release of Marionette, v3, Wreqr will be swapped for an updated library,
[Radio](https://github.com/jmeas/backbone.radio). If you've already begun using Wreqr, don't worry. This change
isn't for quite some time: a few months, at the earliest. Also, we will support easily swapping the two libraries,
so you won't run into any problems if you decide to continue using Wreqr.
For an introduction to Radio, check out
[our blog post](http://blog.marionettejs.com/2014/07/11/introducing-backbone-radio/index.html). As of Marionette v2.1, you can easily
swap in Radio for Wreqr with [this shim](https://gist.github.com/jmeas/7992474cdb1c5672d88b). We think you'll really like the changes!
## Downloads And Source
Grab the source from the `src` folder above. Grab the most recent builds
from the links below.
### Standard Builds
* Development: [backbone.wreqr.js](https://raw.github.com/marionettejs/backbone.wreqr/master/lib/backbone.wreqr.js)
* Production: [backbone.wreqr.min.js](https://raw.github.com/marionettejs/backbone.wreqr/master/lib/backbone.wreqr.min.js)
## Basic Use
### Event Aggregator
An event aggregator implementation. It extends from `Backbone.Events` to
provide the core event handling code in an object that can itself be
extended and instantiated as needed.
```js
var vent = new Backbone.Wreqr.EventAggregator();
vent.on("foo", function(){
console.log("foo event");
});
vent.trigger("foo");
```
### Commands And Request / Response
Wreqr can be used by instantiating a `Backbone.Wreqr.Commands`
or `Backbone.Wreqr.RequestResponse` object. These objects provide a
`setHandler` method to add a handler for a named request or command.
Commands can then be executed with the `execute` method, and
request/response can be done through the `request` method.
### Commands
```js
var commands = new Backbone.Wreqr.Commands();
commands.setHandler("foo", function(){
console.log("the foo command was executed");
});
commands.execute("foo");
```
### Request/Response
```js
var reqres = new Backbone.Wreqr.RequestResponse();
reqres.setHandler("foo", function(){
return "foo requested. this is the response";
});
var result = reqres.request("foo");
console.log(result);
```
### Radio
Radio is a convenient way for emitting events through channels. Radio can be used to either retrieve a channel, or talk through a channel with either command, reqres, or vent.
```js
// channels
var globalChannel = Backbone.Wreqr.radio.channel('global');
var userChannel = Backbone.Wreqr.radio.channel('user');
// Wreqr events
Backbone.Wreqr.radio.commands.execute( 'global', 'shutdown' );
Backbone.Wreqr.radio.reqres.request( 'global', 'current-user' );
Backbone.Wreqr.radio.vent.trigger( 'global', 'game-over');
```
### Channel
Channel is an object that wraps EventAggregator, Commands, and Reqres. Channels provide a convenient way for the objects in your system to talk to one another without the global channel becoming too noisy.
```js
// global channel
var globalChannel = Backbone.Wreqr.radio.channel('global');
globalChannel.commands.execute('shutdown' );
globalChannel.reqres.request('current-user' );
globalChannel.vent.trigger('game-over');
// user channel
var userChannel = Backbone.Wreqr.radio.channel('user');
userChannel.commands.execute('punnish');
userChannel.reqres.request('user-avatar');
userChannel.vent.trigger('win', {
level: 2,
stars: 3
});
```
### Adding Multiple Handlers
Multiple handlers can be set on the Commands and RequestResponse
objects in a single call, using the `setHandlers` method and supplying
a `{"name": configuration}` hash where the `configuration` is an
object literal or a function.
```js
var reqres = new Backbone.Wreqr.RequestResponse();
reqres.setHandlers({
"foo": function(){ /* ... */ },
"bar": {
callback: function(){ /* ... */ },
context: someObject
}
});
var result = reqres.request("foo");
```
The "foo" handler is assigned directly to a function, while the
"bar" handler is assigned to a function with a specific context
to execute the function within.
This works for all `Handlers`, `Commands` and `RequestResponse`
objects.
### Removing Handlers
Removing handlers for commands or requests is done the
same way, with the `removeHandler` or `removeAllHandlers`
functions.
```js
reqres.removeHandler("foo");
commands.removeAllHandlers();
```
### Extending Wreqr Objects
The EventAggregator, Commands and RequestResponse objects can all be
extended using Backbone's standard `extend` method.
```js
var MyEventAgg = Backbone.Wreqr.EventAggregator.extend({
foo: function(){...}
});
var MyCommands = Backbone.Wreqr.Commands.extend({
foo: function(){...}
});
var MyReqRes = Backbone.Wreqr.RequestResponse.extend({
foo: function(){...}
});
```
## License
MIT - see [LICENSE.md](https://raw.github.com/marionettejs/backbone.wreqr/master/LICENSE.md)
## Dev
* `npm install`
* `npm install -g grunt-cli`
* `grunt`

View File

@@ -0,0 +1,39 @@
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['backbone', 'underscore'], function(Backbone, _) {
return factory(Backbone, _);
});
} else if (typeof exports !== 'undefined') {
var Backbone = require('backbone');
var _ = require('underscore');
module.exports = factory(Backbone, _);
} else {
factory(root.Backbone, root._);
}
}(this, function(Backbone, _) {
"use strict";
var previousWreqr = Backbone.Wreqr;
var Wreqr = Backbone.Wreqr = {};
Backbone.Wreqr.VERSION = '<%= version %>';
Backbone.Wreqr.noConflict = function () {
Backbone.Wreqr = previousWreqr;
return this;
};
// @include ../wreqr.handlers.js
// @include ../wreqr.commandStorage.js
// @include ../wreqr.commands.js
// @include ../wreqr.requestresponse.js
// @include ../wreqr.eventaggregator.js
// @include ../wreqr.channel.js
// @include ../wreqr.radio.js
return Backbone.Wreqr;
}));

View File

@@ -0,0 +1,60 @@
// Wreqr.Channel
// --------------
//
// An object that wraps the three messaging systems:
// EventAggregator, RequestResponse, Commands
Wreqr.Channel = (function(Wreqr){
"use strict";
var Channel = function(channelName) {
this.vent = new Backbone.Wreqr.EventAggregator();
this.reqres = new Backbone.Wreqr.RequestResponse();
this.commands = new Backbone.Wreqr.Commands();
this.channelName = channelName;
};
_.extend(Channel.prototype, {
// Remove all handlers from the messaging systems of this channel
reset: function() {
this.vent.off();
this.vent.stopListening();
this.reqres.removeAllHandlers();
this.commands.removeAllHandlers();
return this;
},
// Connect a hash of events; one for each messaging system
connectEvents: function(hash, context) {
this._connect('vent', hash, context);
return this;
},
connectCommands: function(hash, context) {
this._connect('commands', hash, context);
return this;
},
connectRequests: function(hash, context) {
this._connect('reqres', hash, context);
return this;
},
// Attach the handlers to a given message system `type`
_connect: function(type, hash, context) {
if (!hash) {
return;
}
context = context || this;
var method = (type === 'vent') ? 'on' : 'setHandler';
_.each(hash, _.bind(function(fn, eventName) {
this[type][method](eventName, _.bind(fn, context));
}, this));
}
});
return Channel;
})(Wreqr);

View File

@@ -0,0 +1,58 @@
// Wreqr.CommandStorage
// --------------------
//
// Store and retrieve commands for execution.
Wreqr.CommandStorage = (function(){
"use strict";
// Constructor function
var CommandStorage = function(options){
this.options = options;
this._commands = {};
if (_.isFunction(this.initialize)){
this.initialize(options);
}
};
// Instance methods
_.extend(CommandStorage.prototype, Backbone.Events, {
// Get an object literal by command name, that contains
// the `commandName` and the `instances` of all commands
// represented as an array of arguments to process
getCommands: function(commandName){
var commands = this._commands[commandName];
// we don't have it, so add it
if (!commands){
// build the configuration
commands = {
command: commandName,
instances: []
};
// store it
this._commands[commandName] = commands;
}
return commands;
},
// Add a command by name, to the storage and store the
// args for the command
addCommand: function(commandName, args){
var command = this.getCommands(commandName);
command.instances.push(args);
},
// Clear all commands for the given `commandName`
clearCommands: function(commandName){
var command = this.getCommands(commandName);
command.instances = [];
}
});
return CommandStorage;
})();

View File

@@ -0,0 +1,63 @@
// Wreqr.Commands
// --------------
//
// A simple command pattern implementation. Register a command
// handler and execute it.
Wreqr.Commands = (function(Wreqr, _){
"use strict";
return Wreqr.Handlers.extend({
// default storage type
storageType: Wreqr.CommandStorage,
constructor: function(options){
this.options = options || {};
this._initializeStorage(this.options);
this.on("handler:add", this._executeCommands, this);
Wreqr.Handlers.prototype.constructor.apply(this, arguments);
},
// Execute a named command with the supplied args
execute: function(name){
name = arguments[0];
var args = _.rest(arguments);
if (this.hasHandler(name)){
this.getHandler(name).apply(this, args);
} else {
this.storage.addCommand(name, args);
}
},
// Internal method to handle bulk execution of stored commands
_executeCommands: function(name, handler, context){
var command = this.storage.getCommands(name);
// loop through and execute all the stored command instances
_.each(command.instances, function(args){
handler.apply(context, args);
});
this.storage.clearCommands(name);
},
// Internal method to initialize storage either from the type's
// `storageType` or the instance `options.storageType`.
_initializeStorage: function(options){
var storage;
var StorageType = options.storageType || this.storageType;
if (_.isFunction(StorageType)){
storage = new StorageType();
} else {
storage = StorageType;
}
this.storage = storage;
}
});
})(Wreqr, _);

View File

@@ -0,0 +1,17 @@
// Event Aggregator
// ----------------
// A pub-sub object that can be used to decouple various parts
// of an application through event-driven architecture.
Wreqr.EventAggregator = (function(Backbone, _){
"use strict";
var EA = function(){};
// Copy the `extend` function used by Backbone's classes
EA.extend = Backbone.Model.extend;
// Copy the basic Backbone.Events on to the event aggregator
_.extend(EA.prototype, Backbone.Events);
return EA;
})(Backbone, _);

View File

@@ -0,0 +1,86 @@
// Handlers
// --------
// A registry of functions to call, given a name
Wreqr.Handlers = (function(Backbone, _){
"use strict";
// Constructor
// -----------
var Handlers = function(options){
this.options = options;
this._wreqrHandlers = {};
if (_.isFunction(this.initialize)){
this.initialize(options);
}
};
Handlers.extend = Backbone.Model.extend;
// Instance Members
// ----------------
_.extend(Handlers.prototype, Backbone.Events, {
// Add multiple handlers using an object literal configuration
setHandlers: function(handlers){
_.each(handlers, _.bind(function(handler, name){
var context = null;
if (_.isObject(handler) && !_.isFunction(handler)){
context = handler.context;
handler = handler.callback;
}
this.setHandler(name, handler, context);
}, this));
},
// Add a handler for the given name, with an
// optional context to run the handler within
setHandler: function(name, handler, context){
var config = {
callback: handler,
context: context
};
this._wreqrHandlers[name] = config;
this.trigger("handler:add", name, handler, context);
},
// Determine whether or not a handler is registered
hasHandler: function(name){
return !! this._wreqrHandlers[name];
},
// Get the currently registered handler for
// the specified name. Throws an exception if
// no handler is found.
getHandler: function(name){
var config = this._wreqrHandlers[name];
if (!config){
return;
}
return function(){
return config.callback.apply(config.context, arguments);
};
},
// Remove a handler for the specified name
removeHandler: function(name){
delete this._wreqrHandlers[name];
},
// Remove all handlers from this registry
removeAllHandlers: function(){
this._wreqrHandlers = {};
}
});
return Handlers;
})(Backbone, _);

View File

@@ -0,0 +1,85 @@
// Wreqr.Radio
// --------------
//
// An object that lets you communicate with many channels.
Wreqr.radio = (function(Wreqr, _){
"use strict";
var Radio = function() {
this._channels = {};
this.vent = {};
this.commands = {};
this.reqres = {};
this._proxyMethods();
};
_.extend(Radio.prototype, {
channel: function(channelName) {
if (!channelName) {
throw new Error('Channel must receive a name');
}
return this._getChannel( channelName );
},
_getChannel: function(channelName) {
var channel = this._channels[channelName];
if(!channel) {
channel = new Wreqr.Channel(channelName);
this._channels[channelName] = channel;
}
return channel;
},
_proxyMethods: function() {
_.each(['vent', 'commands', 'reqres'], _.bind(function(system) {
_.each( messageSystems[system], _.bind(function(method) {
this[system][method] = proxyMethod(this, system, method);
}, this));
}, this));
}
});
var messageSystems = {
vent: [
'on',
'off',
'trigger',
'once',
'stopListening',
'listenTo',
'listenToOnce'
],
commands: [
'execute',
'setHandler',
'setHandlers',
'removeHandler',
'removeAllHandlers'
],
reqres: [
'request',
'setHandler',
'setHandlers',
'removeHandler',
'removeAllHandlers'
]
};
var proxyMethod = function(radio, system, method) {
return function(channelName) {
var messageSystem = radio._getChannel(channelName)[system];
return messageSystem[method].apply(messageSystem, _.rest(arguments));
};
};
return new Radio();
})(Wreqr, _);

View File

@@ -0,0 +1,17 @@
// Wreqr.RequestResponse
// ---------------------
//
// A simple request/response implementation. Register a
// request handler, and return a response from it
Wreqr.RequestResponse = (function(Wreqr, _){
"use strict";
return Wreqr.Handlers.extend({
request: function(name){
if (this.hasHandler(name)) {
return this.getHandler(name).apply(this, _.rest(arguments));
}
}
});
})(Wreqr, _);

View File

@@ -0,0 +1,32 @@
{
"name": "backbone",
"main": "backbone.js",
"dependencies": {
"underscore": ">=1.7.0"
},
"ignore": [
"docs",
"examples",
"test",
"*.yml",
"*.html",
"*.ico",
"*.md",
"CNAME",
".*",
"karma.*",
"component.json",
"package.json"
],
"homepage": "https://github.com/jashkenas/backbone",
"version": "1.2.3",
"_release": "1.2.3",
"_resolution": {
"type": "version",
"tag": "1.2.3",
"commit": "05fde9e201f7e2137796663081105cd6dad12a98"
},
"_source": "https://github.com/jashkenas/backbone.git",
"_target": ">=0.9.9 <=1.3.x",
"_originalSource": "backbone"
}

22
docs/bower_components/backbone/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1894
docs/bower_components/backbone/backbone.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
{
"name" : "backbone",
"main" : "backbone.js",
"dependencies" : {
"underscore" : ">=1.7.0"
},
"ignore" : ["docs", "examples", "test", "*.yml", "*.html", "*.ico", "*.md", "CNAME", ".*", "karma.*", "component.json", "package.json"]
}

View File

@@ -0,0 +1,17 @@
{
"name": "handlebars",
"version": "4.7.6",
"main": "handlebars.js",
"license": "MIT",
"dependencies": {},
"homepage": "https://github.com/components/handlebars.js",
"_release": "4.7.6",
"_resolution": {
"type": "version",
"tag": "v4.7.6",
"commit": "c5c26b8040d726577f4aa1293b48fcaeab781821"
},
"_source": "https://github.com/components/handlebars.js.git",
"_target": "^4.0.5",
"_originalSource": "handlebars"
}

View File

@@ -0,0 +1,2 @@
vendor
composer.lock

View File

@@ -0,0 +1,12 @@
Handlebars.js
=============
Shim repository for [Handlebars.js](http://handlebarsjs.com).
Package Managers
----------------
* [Bower](http://twitter.github.com/bower/): `handlebars`
* [Component](http://github.com/component/component): `components/handlebars.js`
* [Composer](http://packagist.org/packages/components/handlebars.js): `components/handlebars.js`
* [jspm](http://jspm.io): `github:components/handlebars.js`

View File

@@ -0,0 +1,7 @@
{
"name": "handlebars",
"version": "4.7.6",
"main": "handlebars.js",
"license": "MIT",
"dependencies": {}
}

View File

@@ -0,0 +1,9 @@
{
"name": "handlebars",
"repo": "components/handlebars.js",
"version": "1.0.0",
"main": "handlebars.js",
"scripts": [
"handlebars.js"
]
}

View File

@@ -0,0 +1,35 @@
{
"name": "components/handlebars.js",
"description": "Handlebars.js and Mustache are both logicless templating languages that keep the view and the code separated like we all know they should be.",
"homepage": "http://handlebarsjs.com",
"license": "MIT",
"type": "component",
"keywords": [
"handlebars",
"mustache",
"html"
],
"authors": [
{
"name": "Chris Wanstrath",
"homepage": "http://chriswanstrath.com"
}
],
"require": {
"robloach/component-installer": "*"
},
"extra": {
"component": {
"name": "handlebars",
"scripts": [
"handlebars.js"
],
"files": [
"handlebars.runtime.js"
],
"shim": {
"exports": "Handlebars"
}
}
}
}

Binary file not shown.

View File

@@ -0,0 +1,22 @@
# -*- encoding: utf-8 -*-
require 'json'
package = JSON.parse(File.read('bower.json'))
Gem::Specification.new do |gem|
gem.name = "handlebars-source"
gem.authors = ["Yehuda Katz"]
gem.email = ["wycats@gmail.com"]
gem.date = Time.now.strftime("%Y-%m-%d")
gem.description = %q{Handlebars.js source code wrapper for (pre)compilation gems.}
gem.summary = %q{Handlebars.js source code wrapper}
gem.homepage = "https://github.com/wycats/handlebars.js/"
gem.version = package["version"].sub "-", "."
gem.license = "MIT"
gem.files = [
'handlebars.js',
'handlebars.runtime.js',
'lib/handlebars/source.rb'
]
end

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<package>
<metadata>
<id>handlebars.js</id>
<version>4.7.6</version>
<authors>handlebars.js Authors</authors>
<licenseUrl>https://github.com/wycats/handlebars.js/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/wycats/handlebars.js/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Extension of the Mustache logicless template language</description>
<releaseNotes></releaseNotes>
<tags>handlebars mustache template html</tags>
</metadata>
<files>
<file src="handlebars.js" target="Content\Scripts" />
</files>
</package>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
module Handlebars
module Source
def self.bundled_path
File.expand_path("../../../handlebars.js", __FILE__)
end
def self.runtime_bundled_path
File.expand_path("../../../handlebars.runtime.js", __FILE__)
end
end
end

Some files were not shown because too many files have changed in this diff Show More