From 2e850dba788c5a69beb3157bc14bcedd63f707fb Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 19 Jun 2014 08:06:34 -0700 Subject: [PATCH 01/10] Working on home language selection. --- .../pages/home/language_background_small.png | Bin 0 -> 2047 bytes .../pages/home/language_beta_sticker.png | Bin 0 -> 1409 bytes app/assets/images/pages/home/language_js.png | Bin 0 -> 9586 bytes .../pages/home/language_logo_coffeescript.png | Bin 0 -> 16254 bytes .../images/pages/home/language_logo_io.png | Bin 0 -> 15390 bytes .../images/pages/home/language_logo_lua.png | Bin 0 -> 1510 bytes .../pages/home/language_logo_python.png | Bin 0 -> 17483 bytes .../images/pages/home/language_python.png | Bin 0 -> 7633 bytes app/assets/images/pages/home/wizard.png | Bin 0 -> 20562 bytes app/styles/home.sass | 24 ++++++++++ app/templates/home.jade | 42 +++++++++--------- app/views/home_view.coffee | 4 -- app/views/play/level/hud_view.coffee | 2 +- 13 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 app/assets/images/pages/home/language_background_small.png create mode 100644 app/assets/images/pages/home/language_beta_sticker.png create mode 100644 app/assets/images/pages/home/language_js.png create mode 100644 app/assets/images/pages/home/language_logo_coffeescript.png create mode 100644 app/assets/images/pages/home/language_logo_io.png create mode 100644 app/assets/images/pages/home/language_logo_lua.png create mode 100644 app/assets/images/pages/home/language_logo_python.png create mode 100644 app/assets/images/pages/home/language_python.png create mode 100644 app/assets/images/pages/home/wizard.png diff --git a/app/assets/images/pages/home/language_background_small.png b/app/assets/images/pages/home/language_background_small.png new file mode 100644 index 0000000000000000000000000000000000000000..32063a95408367d898ba5d86275b6f0241c20c83 GIT binary patch literal 2047 zcmVaOZ`IGvUHJ5TXg*z>SjNg-B#TgWEtP zWE;kn7)OADz$^O+7WkX1 z3OWlpZ_h8J+jL2Jc{#PWw^K_?3x*URk3yj^_4W1A;NW1cm%CZmPyJ)i(;@#w-lp5_ z?R5P3aXN6|07e)I z{2V=>oFMnaB#n-bQ#=vJCl;X0s-w=X&g`(;S=jqkvXFPA zTlS1f?tA`B2>Ja756Jm@FFj+Q9I;poBMp#ewY9ZmGMlNgqJr!;8*Q;}CSz?KeSGqy zP~p>VvY;Q52c3t!L%b(HfBrm;jkw6~^UhR@zurM!}gNjgF0rrx`WrjrYYPd}dv%R*{#5JP-`hB^L5TA|YLP=W9e; zO+-2^1{ok#tMTL>7 zs_HP}0RJJs-%B$y0rGezm$&gXM1PJhZcn?rLskwQ_s}H(fUxttaD9F~WJEWHWl?9z&6abVL_G}wAl)hZhH5#qZDgc18 z@QSWu-F9ZsH@sZXH&)=M;sBJYp}z6eweA3*OuAJ(0YlIM3S7l1I&K6VU>!iv0oHTS z@#BvGg^7PncGW?TMxz)pfC7~3>*;9S0dS8F07V;g-s9)$^8uiUf<8Ghj>$NH0+lPf z%Yx2-Z;Jnn6aW;aT=`uV^k6W6kpd`Su^dm#mi?5Je|icd1yI0vvDWGJ8S`xF?A{)e zZ~%pkXV~ZUWc==~af)0S70|0^!00=q&Am{*qpaTGc4gmi)=yUUNj0ixn2R*s4 zK#|xSMg^b<$P4$f);%1JVT1sRfV^lg`(5{7I6|dbEk+5Tn1h~7rN}+yr`YT)Mhc)n z#S=;4R(!?QT@;IBVh*5C`9tB1eLP+RC^F$ljHYK0bbz9jN-YSt-q{dzfFiE$9i^OuI(2^yJMo7QjdWDAZF~KIOTU=ULtFblwzq!r`Tvy7KaJX*(Q^ z)5Ae8MifASdLB;Z&aEuZVnq++da<^yPTIcw<712{fWq(s{BXdVGqbsZE>-n_e`#ud zQ&ZE@1=+>EymViv?f{^Ske~aeN7^@5Rb^Ckd6vb7{#Ujf=-5r-x!O>3^bjmk8;fn24Dy7Aw!Z*xU1< ztJRC0{kGOt+R@fZ!y|vmKP3Pl&sv+C>EuTrlH2R0*+_)MuG}LFJ@cMQ++tOo2fdGX z?BY$mZPza8%>51rS-(IXOz^nIsO zetLJm(|JlIKf=P^#a3U5`@E`)eZN+#rG0igwXy0B057I4DIvXKX)dco*e_c{pl2zW zOiJNSvF&hZCgYr8R(PF#eNxE#dwbHZLMu&-^LG81 zSjk@)^mN!e*owFERtznG;&rp-9KR>eenGXGceB9rHvUMuok#Bupd7q%f6JC@EZ`$6 do%FW=0{}}5wR-YN^hN*x002ovPDHLkV1mYn=nnt@ literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_beta_sticker.png b/app/assets/images/pages/home/language_beta_sticker.png new file mode 100644 index 0000000000000000000000000000000000000000..fb24c3d1246d98d94d598814fa8317a7954a9f44 GIT binary patch literal 1409 zcmV-{1%CR8P)#B-#U&PVnY9sA7#tjS^WMGLZMo5)5`zfv6Bf75Rl|jO2Sp)QXwt>t4$3`h&`WNNmBw4L z7&eTVOO`UcVV3GT{(rdhGMOzvAj5=wJz>fm*ozl$u zQ9}JS`EJ4qaLjrzj16z?K&l`@x6J}QHuFD@Pv%8%ng07sitgn8)%%|X#!LVa5rx@h zP1lGABW!@PtSn+25J3?>yuV1VY7BW?Ff|sS^_i6feED#d)2`!(|J)I%7(-qc>*Ik}>}3>$MadZr{ay>-s0eK)Ys8R=4=%^x>TwT5 zk~RP>;I@!odn*{9O8J$76M?PmIZ zgMqK#_NvLyRCC9%gw_?ZCr)~hU=O>eq~e%xLW-dNc3aK!BTvH-&E(k3K7VTt!f}cG37q+aRFb$!AqceF>)I<5tr3lE z67XHoj6mx|wBREt@_HO*?tbqr2t8|SVi`DUptMG;2#?(LWbEjyOydE&t{h=g&}nCVN<>(y1Tb**TSB?MAmwtIUv#9htp0wWOIqi1BFrquVR~tk=7VTj8FTl| zvk>U8)z}@`R0MIhG}FEmz9(F1AM!czw*aiRLd0T;n;{ENGps(~b-;Wqjk7(& z`d;fk#7HGLb*Qz*Ub585ku!+I%l$t*-ehBfk7BgQD54lV{jN^l8bR^}eujlsl{Nmt z_Y3g5Di@3$aZ}sm9P&b&wXUu68;Yn$@boQ@nO;sP2QjY`R`5W$QrSSf-09%z_r8MU z@FyYSt`Q!wChNI6C&s;||={Q0G_ohBlE zd*LM9h^)em@L#m8AeOlLT`hw~5P_3n54W?Bs`_mQuKyoA?}NAf9%|Q8Qpq1=?1Q}Y z0qC^b%IsF}!k)u}A8Eg{y3OAGQiq+kZDk9ZRYBk`$R0UlSKt%6OGyDd9J89cFJcE#NT^I#wn_HWj;649g8XWz@iXtvoyE;3ZkV>VX zSS+##8C_pr^QY4(zfKK5pdgDrU)Q4inRA>R0d!ipVh+o%@<)`6&c^{s^engN;Gf@B zf;`cqgu56TLCAjhcIB$0v4~f=r>Oq#(u9TVwvOsNH3Vd3T2u$Z-vSH(_uCy?FYD~p P00000NkvXXu0mjf{>Y~6 literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_js.png b/app/assets/images/pages/home/language_js.png new file mode 100644 index 0000000000000000000000000000000000000000..75db0f254b6ce29a7e5b869ec1d8ed2e98ee2c80 GIT binary patch literal 9586 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_coffeescript.png b/app/assets/images/pages/home/language_logo_coffeescript.png new file mode 100644 index 0000000000000000000000000000000000000000..8eb9742ea08e235aed90b0c7f9d0e422f6ff380e GIT binary patch literal 16254 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 DznCwh literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_lua.png b/app/assets/images/pages/home/language_logo_lua.png new file mode 100644 index 0000000000000000000000000000000000000000..724fa0cfc30ce8bbad793a608edab7f234e6d28e GIT binary patch literal 1510 zcmV z_fe!w-H{YeqMY^t6sbEN?|pnf`J{mDh~hYo#4w{VT1aEGIgMu`*>nVM7sh{~^z9n{=$$nGGQQs)8f$#AL zYX2D82Pvgs3lP|)OX^ck62;DUgz62&)oc2Q);tQy*MpKTYd|%8F>j+Nid$*QMvl|F zl`?8XUGp(OfCxkxRXq)M;IBfV4xuo9l_41BNAM|()w*@`(R0OJbo-HKB20(0x~$uTw1;U)v0VdldlvQ|w+@&()+hr8VgJIOkqjQevIU zEmVugjh-P^Y-}3XI9gk5Ts#$EZA5e9dc~kpu{kb4-S`Uzo;cV1YR%@s@~iIs;wZ4M1Ckih4{t8k1;jGvIQ=#k&$M2&zXC+qMreuHk4}ne8P#63 z=ZX?xb@WL<@F-()!&@N;?(JRh1}C6N7FC*<@-GQwVyK!-e4Rh?1}yDh zGI_g<@Q{e*%#s<7ygcEpDyJ=-_9eo&LS3q&rWlgoHs!A3SPMp z4j&wR!7eU-&^tfsM z4V<6#dyC?kp9&CL{BE8Yc&RBH&0JJ#B_-15VSGtikO!l>*u`xCv=>DMD~LfUW6x)m z7MHA~)!diw3HwPL)DCM77b?mDtlJ1UpRVmR>+F6-pd6Mv8pn|)U&>0n6Na6-yt53D zP>8p^i*vp%YE$=CXV^Yp5-R`x@xHd&yHaJt_dz0&EFgOV&=FFoDJhdP1)i9IbR7P& zwDL?tB%+z?Gd8Mv0+I@&jMPk81~~D@vw2DZBF~`d5Gf0N0g=FAV{bv;Y7A M07*qoM6N<$g2-^tOaK4? literal 0 HcmV?d00001 diff --git a/app/assets/images/pages/home/language_logo_python.png b/app/assets/images/pages/home/language_logo_python.png new file mode 100644 index 0000000000000000000000000000000000000000..f16d48c07a02e5f23d0a79e76c64ef0e53037dfd GIT binary patch literal 17483 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 U7x{o6@ - img(src="/images/pages/home/video_border.png") - #mobile-trailer-wrapper - - else - #trailer-wrapper - - img(src="/images/pages/home/video_border.png") - #mobile-trailer-wrapper - - hr + .code-languages + .primary-code-languages.row + .code-language.col-md-6#javascript(data-code-language='javascript') + h2 JavaScript + p language of web yo - else if frontPageContent == 'screenshot' - #front-screenshot - img(src="/images/pages/home/front_screenshot_01.png", alt="") + .code-language.beta.col-md-6#python(data-code-language='python') + h2 Python + p language of badassery + + .secondary-code-languages.row + .code-language.beta.col-md-4#clojure(data-code-language='clojure') + h3 Clojure + p language of geekery + + .code-language.beta.col-md-4#clojure(data-code-language='lua') + h3 Lua + p language of game scripting + + .code-language.beta.col-md-4#clojure(data-code-language='io') + h3 Io + p language of simplicity - else if frontPageContent == 'nothing' - p   .alert.alert-danger.lt-ie10 strong(data-i18n="home.no_ie") CodeCombat does not run in Internet Explorer 9 or older. Sorry! diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee index 1e314aed0..ef36bac52 100644 --- a/app/views/home_view.coffee +++ b/app/views/home_view.coffee @@ -25,10 +25,6 @@ module.exports = class HomeView extends View console.warn 'no more jquery browser version...' c.isEnglish = (me.get('preferredLanguage') or 'en').startsWith 'en' c.languageName = me.get('preferredLanguage') - # A/B test: https://github.com/codecombat/codecombat/issues/769 - c.frontPageContent = {0: "video", 1: "screenshot", 2: "nothing"}[me.get('testGroupNumber') % 3] - application.tracker.identify frontPageContent: c.frontPageContent - application.tracker.trackEvent 'Front Page Content', frontPageContent: c.frontPageContent c afterRender: -> diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index 87625d631..ca03899fc 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -126,7 +126,7 @@ module.exports = class HUDView extends View if thangType.get('raster') wrapper.empty().append($('').attr('src', '/file/'+thangType.get('raster'))) else - stage = thangType.getPortraitStage options + return unless stage = thangType.getPortraitStage options newCanvas = $(stage.canvas).addClass('thang-canvas') wrapper.empty().append(newCanvas) stage.update() From a58f3e0fb6f9a8ebe03e1c7aa73c7a3f64d04397 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 19 Jun 2014 12:31:56 -0700 Subject: [PATCH 02/10] More styling work on code language selector. --- .../pages/home/language_logo_clojure.png | Bin 0 -> 6228 bytes app/locale/bg.coffee | 2 +- app/locale/ca.coffee | 2 +- app/locale/cs.coffee | 2 +- app/locale/da.coffee | 2 +- app/locale/de-DE.coffee | 2 +- app/locale/de.coffee | 2 +- app/locale/el.coffee | 2 +- app/locale/en.coffee | 2 +- app/locale/es-419.coffee | 2 +- app/locale/es-ES.coffee | 2 +- app/locale/es.coffee | 2 +- app/locale/fa.coffee | 2 +- app/locale/fr.coffee | 2 +- app/locale/hu.coffee | 2 +- app/locale/it.coffee | 2 +- app/locale/ja.coffee | 2 +- app/locale/ko.coffee | 2 +- app/locale/ms.coffee | 2 +- app/locale/nb.coffee | 2 +- app/locale/nl-BE.coffee | 2 +- app/locale/nl-NL.coffee | 2 +- app/locale/nl.coffee | 2 +- app/locale/no.coffee | 2 +- app/locale/pl.coffee | 2 +- app/locale/pt-BR.coffee | 2 +- app/locale/pt-PT.coffee | 2 +- app/locale/pt.coffee | 2 +- app/locale/ro.coffee | 2 +- app/locale/ru.coffee | 2 +- app/locale/sk.coffee | 2 +- app/locale/sr.coffee | 2 +- app/locale/sv.coffee | 2 +- app/locale/tr.coffee | 2 +- app/locale/uk.coffee | 2 +- app/locale/vi.coffee | 2 +- app/locale/zh-HANS.coffee | 2 +- app/locale/zh-HANT.coffee | 2 +- app/locale/zh-WUU-HANT.coffee | 2 +- app/locale/zh.coffee | 2 +- app/styles/home.sass | 120 +++++++++++++++++- app/templates/home.jade | 57 ++++++--- 42 files changed, 194 insertions(+), 61 deletions(-) create mode 100644 app/assets/images/pages/home/language_logo_clojure.png diff --git a/app/assets/images/pages/home/language_logo_clojure.png b/app/assets/images/pages/home/language_logo_clojure.png new file mode 100644 index 0000000000000000000000000000000000000000..38f4ae07ac830431c6b5c30c2a193fd13382541f GIT binary patch literal 6228 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 y;axo2fOl}T7O0(6X9O?Vu?X literal 0 HcmV?d00001 diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee index b35435274..583c3dbb9 100644 --- a/app/locale/bg.coffee +++ b/app/locale/bg.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "български език", englishDescri # required: "You need to log in before you can go that way." home: - slogan: "Научи се да програмираш на JavaScript, докато играеш игра " + slogan: "Научи се да програмираш, докато играеш игра " no_ie: "CodeCombat не работи под Internet Explorer 9 или по-стар. Съжалявам!" no_mobile: "CodeCombat не е направен за мобилни устройства и може да не работи!" play: "Играй" diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee index 816e4b3a7..458b6922b 100644 --- a/app/locale/ca.coffee +++ b/app/locale/ca.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr # required: "You need to log in before you can go that way." home: - slogan: "Aprén a programar JavaScript tot Jugant" + slogan: "Aprén a programar tot Jugant" no_ie: "CodeCombat no funciona en Internet Explorer 9 o versions anteriors. Perdó!" no_mobile: "CodeCombat no ha estat dissenyat per dispositius mòbils i per tant no funcionarà!" play: "Jugar" diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee index 61a28e0b9..038d1116e 100644 --- a/app/locale/cs.coffee +++ b/app/locale/cs.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr # required: "You need to log in before you can go that way." home: - slogan: "Naučte se programování JavaScriptu při hraní více-hráčové programovací hry." + slogan: "Naučte se programování tu při hraní více-hráčové programovací hry." no_ie: "Omlouváme se, ale CodeCombat boužel nefunguje v Internet Exploreru 9 nebo starším." no_mobile: "CodeCombat není navržen pro mobilní zařízení a nemusí fungovat správně!" play: "Hrát" diff --git a/app/locale/da.coffee b/app/locale/da.coffee index e26fdf63e..ac2f76026 100644 --- a/app/locale/da.coffee +++ b/app/locale/da.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans # required: "You need to log in before you can go that way." home: - slogan: "Lær at Kode Javascript ved at Spille et Spil" + slogan: "Lær at Kode ved at Spille et Spil" no_ie: "CodeCombat kan desværre ikke køre i Internet Explorer 9 eller ældre. Beklager!" no_mobile: "CodeCombat er ikke designet til mobile enheder og vil måske ikke virke!" play: "Spil" diff --git a/app/locale/de-DE.coffee b/app/locale/de-DE.coffee index 8cfa9ca78..4c2e08eeb 100644 --- a/app/locale/de-DE.coffee +++ b/app/locale/de-DE.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription: # required: "You need to log in before you can go that way." home: - slogan: "Lerne spielend JavaScript" + slogan: "Lerne spielend Programmieren" no_ie: "CodeCombat läuft nicht im IE8 oder älteren Browsern. Tut uns Leid!" no_mobile: "CodeCombat ist nicht für Mobilgeräte optimiert und funktioniert möglicherweise nicht." play: "Spielen" diff --git a/app/locale/de.coffee b/app/locale/de.coffee index 27eb096cb..522292f58 100644 --- a/app/locale/de.coffee +++ b/app/locale/de.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra # required: "You need to log in before you can go that way." home: - slogan: "Lerne spielend JavaScript" + slogan: "Lerne spielend Programmieren" no_ie: "CodeCombat läuft nicht im IE8 oder älteren Browsern. Tut uns Leid!" no_mobile: "CodeCombat ist nicht für Mobilgeräte optimiert und funktioniert möglicherweise nicht." play: "Spielen" diff --git a/app/locale/el.coffee b/app/locale/el.coffee index a87b94be2..af059cf3e 100644 --- a/app/locale/el.coffee +++ b/app/locale/el.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre # required: "You need to log in before you can go that way." home: - slogan: "Μάθε να προγραμμάτιζεις με JavaScript μέσω ενός παιχνιδιού" + slogan: "Μάθε να προγραμμάτιζεις μέσω ενός παιχνιδιού" no_ie: "Το CodeCombat δεν παίζει με το Internet Explorer 9 ή κάποια παλαιότερη έκδοση.Συγνώμη!" no_mobile: "Το CodeCombat δεν σχεδιάστηκε για κινητά και μπορεί να μην δουλεύει!" play: "Παίξε" diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 3ea886e85..000514aa4 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -90,7 +90,7 @@ required: "You need to log in before you can go that way." home: - slogan: "Learn to Code JavaScript by Playing a Game" + slogan: "Learn to Code by Playing a Game" no_ie: "CodeCombat does not run in Internet Explorer 9 or older. Sorry!" no_mobile: "CodeCombat wasn't designed for mobile devices and may not work!" play: "Play" diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index c235b5cf1..a4fa878ec 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip # required: "You need to log in before you can go that way." home: - slogan: "Aprende a programar en JavaScript jugando" + slogan: "Aprende a programar jugando" no_ie: "¡Lo sentimos! CodeCombat no funciona en Internet Explorer 9 o versiones anteriores." no_mobile: "¡CodeCombat no fue diseñado para dispositivos móviles y quizás no funcione!" play: "Jugar" diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee index fc686baf7..445127153 100644 --- a/app/locale/es-ES.coffee +++ b/app/locale/es-ES.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis # required: "You need to log in before you can go that way." home: - slogan: "Aprende a programar JavaScript jugando" + slogan: "Aprende a programar jugando" no_ie: "CodeCombat no funciona en Internet Explorer 9 o anteriores. ¡Lo sentimos!" no_mobile: "¡CodeCombat no fue diseñado para dispositivos móviles y puede que no funcione!" play: "Jugar" diff --git a/app/locale/es.coffee b/app/locale/es.coffee index afda29139..ef5f74793 100644 --- a/app/locale/es.coffee +++ b/app/locale/es.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t # required: "You need to log in before you can go that way." home: - slogan: "Aprende a programar en JavaScript jugando" + slogan: "Aprende a programar jugando" no_ie: "CodeCombat no funciona en Internet Explorer 9 o versiones anteriores. ¡Lo sentimos!" no_mobile: "¡CodeCombat no fue diseñado para dispositivos móviles y quizás no funcione!" play: "Jugar" diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee index a7f597b3f..7d24100ff 100644 --- a/app/locale/fa.coffee +++ b/app/locale/fa.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian", # required: "You need to log in before you can go that way." home: - slogan: "کد نویسی به زبان جاوااسکریپت را با بازی بیاموزید" + slogan: "کد نویسیا با بازی بیاموزید" no_ie: "متاسفیم اما بازی بر روی مرورگر های اینترنت اکسپلورر نسخه ۹ به قبل اجرا نمی شود" no_mobile: "این بازی برای دستگاه های موبایل طراحی نشده است و بر روی آن ها اجرا نمی شود" play: "شروع بازی" diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee index dce3be2d7..5a55252d0 100644 --- a/app/locale/fr.coffee +++ b/app/locale/fr.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t required: "Vous devez être connecté pour voir cela" home: - slogan: "Apprenez à coder en JavaScript tout en jouant" + slogan: "Apprenez à coder tout en jouant" no_ie: "CodeCombat ne fonctionnera pas sous Internet Explorer 9 ou moins. Désolé !" no_mobile: "CodeCombat n'a pas été créé pour les plateformes mobiles donc il est possible qu'il ne fonctionne pas correctement ! " play: "Jouer" diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee index debe8466e..4ddb9c8b2 100644 --- a/app/locale/hu.coffee +++ b/app/locale/hu.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t required: "Csak akkor mehetsz arra, ha már bejelentkeztél." home: - slogan: "Tanulj meg JavaScript nyelven programozni, miközben játszol!" + slogan: "Tanulj meg nyelven programozni, miközben játszol!" no_ie: "A CodeCombat nem támogatja az Internet Explorer 9, vagy korábbi verzióit. Bocsi!" no_mobile: "A CodeCombat nem mobil eszközökre lett tervezve. Valószínűleg nem működik helyesen." play: "Játssz!" diff --git a/app/locale/it.coffee b/app/locale/it.coffee index 31bd039a1..35e60ccfb 100644 --- a/app/locale/it.coffee +++ b/app/locale/it.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t # required: "You need to log in before you can go that way." home: - slogan: "Impara a programmare in JavaScript giocando" + slogan: "Impara a programmare giocando" no_ie: "CodeCombat non supporta Internet Explorer 9 o browser precedenti. Ci dispiace!" no_mobile: "CodeCombat non è stato progettato per dispositivi mobile e potrebbe non funzionare!" play: "Gioca" diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee index 626da7b17..8f19ae524 100644 --- a/app/locale/ja.coffee +++ b/app/locale/ja.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese", # required: "You need to log in before you can go that way." home: - slogan: "ゲームをプレイしてJavaScriptを学びましょう" + slogan: "ゲームをプレイして学びましょう" no_ie: "大変申し訳ありませんが、ご利用のブラウザ(IE8以下)はサポートされていません。(ChromeやFirefoxをご利用ください)" no_mobile: "CodeCombat は携帯端末向けに制作されていないため、動作しない可能性があります。" play: "ゲームスタート" diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee index 59398d961..e54338064 100644 --- a/app/locale/ko.coffee +++ b/app/locale/ko.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t # required: "You need to log in before you can go that way." home: - slogan: "쉽고 간단한 게임으로 자바스크립트 배우기" + slogan: "쉽고 간단한 게임배우기" no_ie: "죄송하지만 코드컴뱃은 인터넷 익스플로러 9에서는 동작하지 않습니다." no_mobile: "코드 컴뱃은 모바일 기기용으로 제작되지 않았습니다. 아마 동작하지 않을 가능성이 높습니다." play: "시작" diff --git a/app/locale/ms.coffee b/app/locale/ms.coffee index 8cf0fe7ce..008d2863f 100644 --- a/app/locale/ms.coffee +++ b/app/locale/ms.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa # required: "You need to log in before you can go that way." home: - slogan: "Belajar Kod JavaScript Dengan Permainan" + slogan: "Belajar Kod bDengan Permainan" no_ie: "CodeCombat tidak berfungsi dalam Internet Explorer 9 dan terdahulu. Maaf!" no_mobile: "CodeCombat tidak dibangunkan untuk telefon mudah-alih dan tablet dan tidak akan berfungsi!" play: "Mula" diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee index aac749e37..7fbf4a07c 100644 --- a/app/locale/nb.coffee +++ b/app/locale/nb.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg # required: "You need to log in before you can go that way." home: - slogan: "Lær å Kode JavaScript ved å Spille et Spill" + slogan: "Lær å Kode ved å Spille et Spill" no_ie: "CodeCombat kjører ikke på IE8 eller eldre. Beklager!" no_mobile: "CodeCombat ble ikke designet for mobile enheter, og vil muligens ikke virke!" play: "Spill" diff --git a/app/locale/nl-BE.coffee b/app/locale/nl-BE.coffee index ce073b57f..ab53bcce0 100644 --- a/app/locale/nl-BE.coffee +++ b/app/locale/nl-BE.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription: # required: "You need to log in before you can go that way." home: - slogan: "Leer programmeren in JavaScript door het spelen van een spel" + slogan: "Leer programmeren door het spelen van een spel" no_ie: "CodeCombat werkt niet in IE8 of ouder. Sorry!" no_mobile: "CodeCombat is niet gemaakt voor mobiele apparaten en werkt misschien niet!" play: "Speel" diff --git a/app/locale/nl-NL.coffee b/app/locale/nl-NL.coffee index 8a724813b..acbd7856a 100644 --- a/app/locale/nl-NL.coffee +++ b/app/locale/nl-NL.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription # required: "You need to log in before you can go that way." home: - slogan: "Leer programmeren in JavaScript door het spelen van een spel" + slogan: "Leer programmeren door het spelen van een spel" no_ie: "CodeCombat werkt niet in IE8 of ouder. Sorry!" no_mobile: "CodeCombat is niet gemaakt voor mobiele apparaten en werkt misschien niet!" play: "Speel" diff --git a/app/locale/nl.coffee b/app/locale/nl.coffee index 6ac0bc5f7..ecc068641 100644 --- a/app/locale/nl.coffee +++ b/app/locale/nl.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t # required: "You need to log in before you can go that way." home: - slogan: "Leer programmeren in JavaScript door het spelen van een spel" + slogan: "Leer programmeren door het spelen van een spel" no_ie: "CodeCombat werkt niet in IE8 of ouder. Sorry!" no_mobile: "CodeCombat is niet gemaakt voor mobiele apparaten en werkt misschien niet!" play: "Speel" diff --git a/app/locale/no.coffee b/app/locale/no.coffee index 38938726f..9764e3f23 100644 --- a/app/locale/no.coffee +++ b/app/locale/no.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr # required: "You need to log in before you can go that way." home: - slogan: "Lær å Kode JavaScript ved å Spille et Spill" + slogan: "Lær å Kode ved å Spille et Spill" no_ie: "CodeCombat kjører ikke på IE8 eller eldre. Beklager!" no_mobile: "CodeCombat ble ikke designet for mobile enheter, og vil muligens ikke virke!" play: "Spill" diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee index a7c1f6328..14ed9cec5 100644 --- a/app/locale/pl.coffee +++ b/app/locale/pl.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish # required: "You need to log in before you can go that way." home: - slogan: "Naucz się JavaScript grając" + slogan: "Naucz się programowania grając" no_ie: "CodeCombat nie działa na Internet Explorer 9 lub starszym. Przepraszamy!" no_mobile: "CodeCombat nie został zaprojektowany dla użądzeń przenośnych więc może nie działać!" play: "Graj" diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index 544660f63..4fe1996e4 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: # required: "You need to log in before you can go that way." home: - slogan: "Aprenda a programar em JavaScript enquanto se diverte com um jogo." + slogan: "Aprenda a programar enquanto se diverte com um jogo." no_ie: "CodeCombat não roda em versões mais antigas que o Internet Explorer 10. Desculpe!" no_mobile: "CodeCombat não foi projetado para dispositivos móveis e pode não funcionar!" play: "Jogar" diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 74ec2ffcf..82293b01e 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Português europeu", englishDescription: "P # required: "You need to log in before you can go that way." home: - slogan: "Aprende a Programar JavaScript ao Jogar um Jogo" + slogan: "Aprende a Programar ao Jogar um Jogo" no_ie: "O CodeCombat não corre em Internet Explorer 9 ou anterior. Desculpa!" no_mobile: "O CodeCombat não foi desenhado para dispositivos móveis e pode não funcionar!" play: "Jogar" diff --git a/app/locale/pt.coffee b/app/locale/pt.coffee index 72ed1081b..f2c55aa9f 100644 --- a/app/locale/pt.coffee +++ b/app/locale/pt.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues # required: "You need to log in before you can go that way." home: - slogan: "Aprenda a programar em JavaScript enquanto se diverte com um jogo." + slogan: "Aprenda a programar enquanto se diverte com um jogo." no_ie: "CodeCombat não roda em versões mais antigas que o Internet Explorer 10. Desculpe!" no_mobile: "CodeCombat não foi projetado para dispositivos móveis e pode não funcionar!" play: "Jogar" diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee index 8d8de592c..23f636da2 100644 --- a/app/locale/ro.coffee +++ b/app/locale/ro.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman # required: "You need to log in before you can go that way." home: - slogan: "Învață sa scrii JavaScript jucându-te" + slogan: "Învață sa scrii cod jucându-te" no_ie: "CodeCombat nu merge pe Internet Explorer 9 sau mai vechi. Scuze!" no_mobile: "CodeCombat nu a fost proiectat pentru dispozitive mobile si s-ar putea sa nu meargă!" play: "Joacă" diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index b6abadad7..c81a59da9 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi # required: "You need to log in before you can go that way." home: - slogan: "Научитесь программировать на JavaScript, играя в игру" + slogan: "Научитесь программировать, играя в игру" no_ie: "CodeCombat не работает в IE8 или более старых версиях. Нам очень жаль!" no_mobile: "CodeCombat не приспособлен для работы на мобильных устройствах и может не работать!" play: "Играть" diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee index 2471695a7..06fc9ed5f 100644 --- a/app/locale/sk.coffee +++ b/app/locale/sk.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak", # required: "You need to log in before you can go that way." home: - slogan: "Nauč sa programovať v Javascripte pomocou hry" + slogan: "Nauč sa programovať pomocou hry" no_ie: "CodeCombat nefunguje v prehliadači Internet Explorer 9 a jeho starších verziách. Ospravedlňujeme sa." no_mobile: "CodeCombat nebol navrhnutý pre mobilné zariadenia a nemusí na nich fungovať správne!" play: "Hraj" diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee index 54bff9052..3bea2b668 100644 --- a/app/locale/sr.coffee +++ b/app/locale/sr.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian # required: "You need to log in before you can go that way." home: - slogan: "Научи да пишеш JavaScript играјући игру" + slogan: "Научи да пишеш код играјући игру" no_ie: "CodeCombat не ради у IE8 и старијим верзијама. Жао нам је!" no_mobile: "CodeCombat није дизајниран за мобилне уређаје и може да се деси да не ради!" play: "Играј" diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee index 0a63ee522..bc9240252 100644 --- a/app/locale/sv.coffee +++ b/app/locale/sv.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr # required: "You need to log in before you can go that way." home: - slogan: "Lär dig att koda Javascript genom att spela ett spel." + slogan: "Lär dig att koda genom att spela ett spel." no_ie: "CodeCombat fungerar tyvärr inte i IE8 eller äldre." no_mobile: "CodeCombat är inte designat för mobila enhter och fungerar kanske inte!" play: "Spela" diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee index 2fb215019..5cd97dc2d 100644 --- a/app/locale/tr.coffee +++ b/app/locale/tr.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t # required: "You need to log in before you can go that way." home: - slogan: "Oyun oynayarak JavaScript kodlamayı öğrenin" + slogan: "Oyun oynayarak kodlamayı öğrenin" no_ie: "CodeCombat maalesef Internet Explorer 9 veya daha eski sürümlerde çalışmaz." no_mobile: "CodeCombat mobil cihazlar için tasarlanmamıştır bu sebeple mobil cihazlarda çalışmayabilir." play: "Oyna" diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee index 479b98fcc..11af81570 100644 --- a/app/locale/uk.coffee +++ b/app/locale/uk.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "українська мова", englishDesc # required: "You need to log in before you can go that way." home: - slogan: "Навчіться програмувати на JavaScript, граючи у гру" + slogan: "Навчіться програмувати, граючи у гру" no_ie: "На жаль, CodeCombat не працює в IE8 чи більш старих версіях!" no_mobile: "CodeCombat не призначений для мобільних приладів і може не працювати!" play: "Грати" diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee index 93b0773a2..032d39202 100644 --- a/app/locale/vi.coffee +++ b/app/locale/vi.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn # required: "You need to log in before you can go that way." home: - slogan: "Học mã Javascript bằng chơi Games" + slogan: "Học mã bằng chơi Games" no_ie: "Codecombat không chạy trong Internet Explorer 9 hoặc cũ hơn. Xin lỗi!" no_mobile: "Codecombat không được thiết kế cho các thiết bị di động và có thể không hoạt động được!" play: "Chơi" diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index 4299c857b..dfb9549bb 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese # required: "You need to log in before you can go that way." home: - slogan: "通过游戏学习 Javascript" + slogan: "通过游戏学习编程" no_ie: "抱歉! Internet Explorer 9 等旧式预览器无法使用本网站。" no_mobile: "CodeCombat 不是针对手机设备设计的,所以可能无法达到最好的体验!" play: "开始游戏" diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee index 0f7399056..05ab6d070 100644 --- a/app/locale/zh-HANT.coffee +++ b/app/locale/zh-HANT.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese # required: "You need to log in before you can go that way." home: - slogan: "通過玩遊戲學習Javascript 腳本語言" + slogan: "通過玩遊戲學習編程" no_ie: "抱歉!Internet Explorer 9 等舊的瀏覽器打不開此網站" no_mobile: "CodeCombat 不是針對手機設備設計的,所以可能會出問題!" play: "開始遊戲" diff --git a/app/locale/zh-WUU-HANT.coffee b/app/locale/zh-WUU-HANT.coffee index 6bce76545..4180369c3 100644 --- a/app/locale/zh-WUU-HANT.coffee +++ b/app/locale/zh-WUU-HANT.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio # required: "You need to log in before you can go that way." home: - slogan: "打遊戲來學 Javascript" + slogan: "打遊戲來學編程" no_ie: "對弗住!箇網站叻 Internet Explorer 9 箇粒老個瀏覽器嘸處用。" no_mobile: "CodeCombat 勿是照手機設備設計個,怪得嘸數达弗到頂讚個享受!" play: "遊戲開打" diff --git a/app/locale/zh.coffee b/app/locale/zh.coffee index fa6818af4..0a5bf7396 100644 --- a/app/locale/zh.coffee +++ b/app/locale/zh.coffee @@ -90,7 +90,7 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra # required: "You need to log in before you can go that way." home: - slogan: "通过游戏学习Javascript脚本语言" + slogan: "通过游戏学习编程" no_ie: "抱歉!Internet Explorer 9等更旧的预览器打不开此网站" no_mobile: "CodeCombat暂时没有手机版本,可能无法运行!" play: "玩" diff --git a/app/styles/home.sass b/app/styles/home.sass index dc56a39b7..b03fa5097 100644 --- a/app/styles/home.sass +++ b/app/styles/home.sass @@ -68,27 +68,135 @@ box-shadow: 0 0 5px black .code-languages + margin: 10px 0 30px 0 + + &:hover + .code-language + opacity: 0.6 + + .code-language.selected-language:not(:hover) + opacity: 0.8 + + h2, h3 + text-shadow: none + + .code-wizard + display: none + + .code-language + cursor: pointer + text-align: center + position: relative + opacity: 0.6 + + &:hover + opacity: 1 + + h2, h3 + text-shadow: 0px 0px 5px white + + .code-wizard + display: block + + &.selected-language + opacity: 1 + + h2, h3 + text-shadow: 0px 0px 5px white + + .code-wizard + display: block + + .code-wizard + position: absolute + background: transparent url(/images/pages/home/wizard.png) no-repeat + background-size: contain + width: 111px + height: 97px + display: none + + .code-language-beta + background: transparent url(/images/pages/home/language_beta_sticker.png) no-repeat + background-size: contain + width: 100px + height: 32px + position: absolute + right: 20px + top: -7px + .primary-code-languages #javascript - background: transparent url(/images/pages/home/language_js.png) + background: transparent url(/images/pages/home/language_js.png) no-repeat padding-right: 150px + .code-wizard + left: 120px + #python - background: transparent url(/images/pages/home/language_python.png) + background: transparent url(/images/pages/home/language_python.png) no-repeat padding-left: 150px + .code-wizard + right: 120px + .code-language - text-align: center width: 498px height: 153px padding: 30px - margin-left: 11px + margin: 0px 0 0 -6px + + .code-wizard + top: -65px + + h2 + margin: 15px 0 5px .secondary-code-languages + margin-left: -10px + + .col-md-3 + padding: 0px + .code-language - text-align: center - + background: transparent url(/images/pages/home/language_background_small.png) no-repeat + width: 250px + height: 80px + margin: 20px 0 20px 0 + padding: 20px 20px 20px 70px + + .code-wizard + top: -51px + left: 89px + height: 63px + + .code-language-logo + position: absolute + left: 15px + top: 17px + width: 50px + height: 50px + + .code-language-beta + right: -15px + top: -16px + height: 24px + + h3 + margin: 0 + padding: 0 + + #coffeescript .code-language-logo + background: transparent url(/images/pages/home/language_logo_coffeescript.png) no-repeat center + + #clojure .code-language-logo + background: transparent url(/images/pages/home/language_logo_clojure.png) no-repeat center + + #lua .code-language-logo + background: transparent url(/images/pages/home/language_logo_lua.png) no-repeat center + + #io .code-language-logo + background: transparent url(/images/pages/home/language_logo_io.png) no-repeat center #multiplayer-launch-modal diff --git a/app/templates/home.jade b/app/templates/home.jade index 56a293ffd..8be32e95d 100644 --- a/app/templates/home.jade +++ b/app/templates/home.jade @@ -2,30 +2,55 @@ extends /templates/base block content - h1#site-slogan(data-i18n="home.slogan") Learn to Code JavaScript by Playing a Game + h1#site-slogan(data-i18n="home.slogan") Learn to Code by Playing a Game .code-languages .primary-code-languages.row - .code-language.col-md-6#javascript(data-code-language='javascript') - h2 JavaScript - p language of web yo + .col-md-6 + .code-language.selected-language#javascript(data-code-language='javascript') + .code-wizard + h2 JavaScript + p The language of the web. Great for writing websites, web apps, HTML5 games, and servers. - .code-language.beta.col-md-6#python(data-code-language='python') - h2 Python - p language of badassery + .col-md-6 + .code-language.beta#python(data-code-language='python') + .code-wizard + .code-language-beta + h2 Python + p Simple yet powerful, Python is a great general purpose programming language. .secondary-code-languages.row - .code-language.beta.col-md-4#clojure(data-code-language='clojure') - h3 Clojure - p language of geekery + .col-md-3 + .code-language.beta#coffeescript(data-code-language='coffeescript') + .code-language-logo + .code-wizard + .code-language-beta + h3 CoffeeScript + p Nicer JavaScript syntax - .code-language.beta.col-md-4#clojure(data-code-language='lua') - h3 Lua - p language of game scripting + .col-md-3 + .code-language.beta#clojure(data-code-language='clojure') + .code-language-logo + .code-wizard + .code-language-beta + h3 Clojure + p A modern Lisp - .code-language.beta.col-md-4#clojure(data-code-language='io') - h3 Io - p language of simplicity + .col-md-3 + .code-language.beta#lua(data-code-language='lua') + .code-language-logo + .code-wizard + .code-language-beta + h3 Lua + p Game scripting language + + .col-md-3 + .code-language.beta#io(data-code-language='io') + .code-language-logo + .code-wizard + .code-language-beta + h3 Io + p Simple but obscure .alert.alert-danger.lt-ie10 From 666c0203890d6032b50ec205696256a35ac383a3 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 19 Jun 2014 13:42:25 -0700 Subject: [PATCH 03/10] Switching code language based on selection now. --- app/styles/home.sass | 3 ++- app/templates/home.jade | 2 +- app/views/home_view.coffee | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/styles/home.sass b/app/styles/home.sass index b03fa5097..2e0d77fdd 100644 --- a/app/styles/home.sass +++ b/app/styles/home.sass @@ -81,7 +81,7 @@ text-shadow: none .code-wizard - display: none + opacity: 0.5 .code-language cursor: pointer @@ -97,6 +97,7 @@ .code-wizard display: block + opacity: 1 &.selected-language opacity: 1 diff --git a/app/templates/home.jade b/app/templates/home.jade index 8be32e95d..d854013fc 100644 --- a/app/templates/home.jade +++ b/app/templates/home.jade @@ -7,7 +7,7 @@ block content .code-languages .primary-code-languages.row .col-md-6 - .code-language.selected-language#javascript(data-code-language='javascript') + .code-language#javascript(data-code-language='javascript') .code-wizard h2 JavaScript p The language of the web. Great for writing websites, web apps, HTML5 games, and servers. diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee index ef36bac52..a117d9469 100644 --- a/app/views/home_view.coffee +++ b/app/views/home_view.coffee @@ -10,6 +10,9 @@ module.exports = class HomeView extends View id: 'home-view' template: template + events: + 'click .code-language': 'onCodeLanguageSelected' + constructor: -> super(arguments...) ThangType.loadUniversalWizard() @@ -25,6 +28,7 @@ module.exports = class HomeView extends View console.warn 'no more jquery browser version...' c.isEnglish = (me.get('preferredLanguage') or 'en').startsWith 'en' c.languageName = me.get('preferredLanguage') + c.codeLanguage = (me.get('aceConfig') ? {}).language or 'javascript' c afterRender: -> @@ -42,3 +46,17 @@ module.exports = class HomeView extends View href[href.length-1] = lastLevel if href.length isnt 0 href = href.join("/") playLink.attr("href", href) + + codeLanguage = (me.get('aceConfig') ? {}).language or 'javascript' + @$el.find(".code-language[data-code-language=#{codeLanguage}]").addClass 'selected-language' + + onCodeLanguageSelected: (e) -> + target = $(e.target).closest('.code-language') + codeLanguage = target.data('code-language') + @$el.find('.code-language').removeClass 'selected-language' + target.addClass 'selected-language' + aceConfig = me.get('aceConfig') ? {} + return if (aceConfig.language or 'javascript') is codeLanguage + aceConfig.language = codeLanguage + me.set 'aceConfig', aceConfig + me.save() # me.patch() doesn't work if aceConfig previously existed and we switched just once From 1e9b403ce5bf6e2a9fb99eb9a6eea3d9c5c6dd30 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 19 Jun 2014 14:55:16 -0700 Subject: [PATCH 04/10] More zazz for home page code language selection. --- .../pages/home/language_logo_javascript.png | Bin 0 -> 3828 bytes app/styles/home.sass | 22 ++++++++++++++---- app/templates/home.jade | 2 ++ app/views/home_view.coffee | 9 +++++++ 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 app/assets/images/pages/home/language_logo_javascript.png diff --git a/app/assets/images/pages/home/language_logo_javascript.png b/app/assets/images/pages/home/language_logo_javascript.png new file mode 100644 index 0000000000000000000000000000000000000000..ec8b134ae20775085642757fb04bcee548e1e15a GIT binary patch literal 3828 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 literal 0 HcmV?d00001 diff --git a/app/styles/home.sass b/app/styles/home.sass index 2e0d77fdd..c58133fb8 100644 --- a/app/styles/home.sass +++ b/app/styles/home.sass @@ -32,6 +32,7 @@ img display: block margin: 0 auto + @include transition(box-shadow .50s ease-in-out) text-shadow: 2px 2px 5px black @@ -58,14 +59,27 @@ color: $yellow font-size: 90px font-family: Bangers - @include transition(color .10s linear) + @include transition(color .25s ease-in-out) - &:hover div + &:hover div, &.hovered div color: lighten($yellow, 20%) - &:hover img + &:hover img, &.hovered img filter: brightness(1.2) -webkit-filter: brightness(1.2) - box-shadow: 0 0 5px black + box-shadow: 0 0 15px black + + .code-language-logo + background-color: transparent + background-repeat: no-repeat + position: absolute + right: 35px + top: 15px + width: 50px + height: 50px + + &.inverted + filter: invert(100%) + -webkit-filter: invert(100%) .code-languages margin: 10px 0 30px 0 diff --git a/app/templates/home.jade b/app/templates/home.jade index d854013fc..217a40df2 100644 --- a/app/templates/home.jade +++ b/app/templates/home.jade @@ -74,6 +74,7 @@ block content h3(data-i18n="home.campaign") Campaign h4(data-i18n="home.for_beginners") For Beginners .play-text(data-i18n="home.play") Play + .code-language-logo a#multiplayer(href="/play/ladder") div.game-mode-wrapper @@ -84,5 +85,6 @@ block content h3(data-i18n="home.multiplayer") Multiplayer h4(data-i18n="home.for_developers") For Developers .play-text(data-i18n="home.play") Play + .code-language-logo .clearfix diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee index a117d9469..7899d7bf4 100644 --- a/app/views/home_view.coffee +++ b/app/views/home_view.coffee @@ -49,6 +49,10 @@ module.exports = class HomeView extends View codeLanguage = (me.get('aceConfig') ? {}).language or 'javascript' @$el.find(".code-language[data-code-language=#{codeLanguage}]").addClass 'selected-language' + @updateLanguageLogos codeLanguage + + updateLanguageLogos: (codeLanguage) -> + @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/pages/home/language_logo_#{codeLanguage}.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript']) onCodeLanguageSelected: (e) -> target = $(e.target).closest('.code-language') @@ -60,3 +64,8 @@ module.exports = class HomeView extends View aceConfig.language = codeLanguage me.set 'aceConfig', aceConfig me.save() # me.patch() doesn't work if aceConfig previously existed and we switched just once + + firstButton = @$el.find('#beginner-campaign .game-mode-wrapper').delay(500).addClass('hovered', 500).delay(500).removeClass('hovered', 500) + lastButton = @$el.find('#multiplayer .game-mode-wrapper').delay(1000).addClass('hovered', 500).delay(500).removeClass('hovered', 500) + $('#page-container').animate {scrollTop: firstButton.offset().top - 100, easing: 'easeInOutCubic'}, 500 + @updateLanguageLogos codeLanguage From 04976a7b14733c4b90581fbc9e1ed13c654d65eb Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 24 Jun 2014 21:07:36 -0700 Subject: [PATCH 05/10] Working on the Tome displaying the proper syntax for the selected programming language. Fixed #1225. --- app/schemas/subscriptions/play.coffee | 9 ++--- app/schemas/subscriptions/tome.coffee | 24 +++++++++++- app/styles/play/level/tome/spell_palette.sass | 26 +++++++++++++ .../play/level/tome/spell_list_tab_entry.jade | 2 +- .../play/level/tome/spell_palette.jade | 1 + app/views/play/level/control_bar_view.coffee | 2 +- app/views/play/level/hud_view.coffee | 2 +- app/views/play/level/playback_view.coffee | 2 +- .../play/level/tome/cast_button_view.coffee | 2 +- app/views/play/level/tome/spell.coffee | 1 + .../level/tome/spell_list_entry_view.coffee | 38 +++++++++++++++++-- .../play/level/tome/spell_palette_view.coffee | 18 ++++++++- app/views/play/level/tome/spell_view.coffee | 2 +- app/views/play/level/tome/tome_view.coffee | 4 +- 14 files changed, 113 insertions(+), 20 deletions(-) diff --git a/app/schemas/subscriptions/play.coffee b/app/schemas/subscriptions/play.coffee index 04764da5f..0db11f30d 100644 --- a/app/schemas/subscriptions/play.coffee +++ b/app/schemas/subscriptions/play.coffee @@ -63,9 +63,6 @@ module.exports = "next-game-pressed": {} # TODO schema - "focus-editor": - {} # TODO schema - "end-current-script": {} # TODO schema @@ -87,14 +84,14 @@ module.exports = scriptRunning: { type: 'string' } noteGroupRunning: { type: 'string' } timeSinceLastScriptEnded: { type: 'number' } - scriptStates: + scriptStates: type: 'object' additionalProperties: title: 'Script State' type: 'object' additionalProperties: false properties: - timeSinceLastEnded: + timeSinceLastEnded: type: 'number' description: 'seconds since this script ended last' timeSinceLastTriggered: @@ -143,7 +140,7 @@ module.exports = additionalProperties: false properties: showModal: { type: 'boolean' } - + "level-highlight-dom": type: 'object' additionalProperties: false diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee index 7c6a5a11f..aa5f96eb1 100644 --- a/app/schemas/subscriptions/tome.coffee +++ b/app/schemas/subscriptions/tome.coffee @@ -67,7 +67,27 @@ module.exports = "tome:spell-shown": {} # TODO schema - # TODO proposition: add tome to name - "focus-editor": + "tome:focus-editor": {} # TODO schema + "tome:change-language": + title: "Tome Change Language" + $schema: "http://json-schema.org/draft-04/schema#" + description: "Published when the Tome should update its programming language." + type: "object" + additionalProperties: false + properties: + language: + type: "string" + required: ["language"] + + "tome:spell-changed-language": + title: "Spell Changed Language" + $schema: "http://json-schema.org/draft-04/schema#" + description: "Published when an individual spell has updated its code language." + type: "object" + additionalProperties: false + properties: + spell: + type: "object" + required: ["spell"] diff --git a/app/styles/play/level/tome/spell_palette.sass b/app/styles/play/level/tome/spell_palette.sass index 52ce37658..5e19cc0ce 100644 --- a/app/styles/play/level/tome/spell_palette.sass +++ b/app/styles/play/level/tome/spell_palette.sass @@ -60,3 +60,29 @@ display: inline-block margin-right: 3px vertical-align: top + + .code-language-logo + position: absolute + width: 20px + height: 20px + left: 12px + top: 34px + z-index: 10 + background-color: transparent + background-repeat: no-repeat + background-size: contain + cursor: pointer + + &.javascript + background-image: url(/images/pages/home/language_logo_javascript.png) + &.python + background-image: url(/images/pages/home/language_logo_python.png) + &.coffeescript + background-image: url(/images/pages/home/language_logo_coffeescript.png) + &.clojure + background-image: url(/images/pages/home/language_logo_clojure.png) + &.lua + background-image: url(/images/pages/home/language_logo_lua.png) + &.io + background-image: url(/images/pages/home/language_logo_io.png) + diff --git a/app/templates/play/level/tome/spell_list_tab_entry.jade b/app/templates/play/level/tome/spell_list_tab_entry.jade index eb9d01e0c..8ebad097f 100644 --- a/app/templates/play/level/tome/spell_list_tab_entry.jade +++ b/app/templates/play/level/tome/spell_list_tab_entry.jade @@ -2,7 +2,7 @@ i.icon-chevron-down .thang-avatar-placeholder -code #{spell.name}(#{parameters}) +code #{methodSignature} .btn.btn-small.reload-code(title="Reload original code for " + spell.name) i.icon-repeat diff --git a/app/templates/play/level/tome/spell_palette.jade b/app/templates/play/level/tome/spell_palette.jade index f87259d77..03450f9c2 100644 --- a/app/templates/play/level/tome/spell_palette.jade +++ b/app/templates/play/level/tome/spell_palette.jade @@ -1,4 +1,5 @@ img(src="/images/level/code_palette_background.png").code-palette-background +.code-language-logo ul(class="nav nav-pills" + (tabbed ? ' multiple-tabs' : '')) each slug, group in entryGroupSlugs li(class=group == "this" || slug == "available-spells" ? "active" : "") diff --git a/app/views/play/level/control_bar_view.coffee b/app/views/play/level/control_bar_view.coffee index 9c1076edb..d5102c60b 100644 --- a/app/views/play/level/control_bar_view.coffee +++ b/app/views/play/level/control_bar_view.coffee @@ -28,7 +28,7 @@ module.exports = class ControlBarView extends View 'click #next-game-button': -> Backbone.Mediator.publish 'next-game-pressed' - 'click': -> Backbone.Mediator.publish 'focus-editor' + 'click': -> Backbone.Mediator.publish 'tome:focus-editor' constructor: (options) -> @worldName = options.worldName diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index ca03899fc..612dcae41 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -31,7 +31,7 @@ module.exports = class HUDView extends View @$el.addClass 'no-selection' onClick: (e) -> - Backbone.Mediator.publish 'focus-editor' unless $(e.target).parents('.thang-props').length + Backbone.Mediator.publish 'tome:focus-editor' unless $(e.target).parents('.thang-props').length onFrameChanged: (e) -> @timeProgress = e.progress diff --git a/app/views/play/level/playback_view.coffee b/app/views/play/level/playback_view.coffee index d3f66d89d..fb0ba5fd7 100644 --- a/app/views/play/level/playback_view.coffee +++ b/app/views/play/level/playback_view.coffee @@ -36,7 +36,7 @@ module.exports = class PlaybackView extends View 'click #zoom-out-button': -> Backbone.Mediator.publish('camera-zoom-out') unless @shouldIgnore() 'click #volume-button': 'onToggleVolume' 'click #play-button': 'onTogglePlay' - 'click': -> Backbone.Mediator.publish 'focus-editor' + 'click': -> Backbone.Mediator.publish 'tome:focus-editor' 'mouseenter #timeProgress': 'onProgressEnter' 'mouseleave #timeProgress': 'onProgressLeave' 'mousemove #timeProgress': 'onProgressHover' diff --git a/app/views/play/level/tome/cast_button_view.coffee b/app/views/play/level/tome/cast_button_view.coffee index 5f368a51c..560de1dbe 100644 --- a/app/views/play/level/tome/cast_button_view.coffee +++ b/app/views/play/level/tome/cast_button_view.coffee @@ -46,7 +46,7 @@ module.exports = class CastButtonView extends View Backbone.Mediator.publish 'tome:manual-cast', {} onCastOptionsClick: (e) => - Backbone.Mediator.publish 'focus-editor' + Backbone.Mediator.publish 'tome:focus-editor' @castButtonGroup.removeClass 'open' @setAutocastDelay $(e.target).attr 'data-delay' false diff --git a/app/views/play/level/tome/spell.coffee b/app/views/play/level/tome/spell.coffee index 5e3501014..98077a4e0 100644 --- a/app/views/play/level/tome/spell.coffee +++ b/app/views/play/level/tome/spell.coffee @@ -146,6 +146,7 @@ module.exports = class Spell for thangId, spellThang of @thangs spellThang.aether?.setLanguage @language spellThang.castAether = null + Backbone.Mediator.publish 'tome:spell-changed-language', spell: @ workerMessage = function: "updateLanguageAether" newLanguage: @language diff --git a/app/views/play/level/tome/spell_list_entry_view.coffee b/app/views/play/level/tome/spell_list_entry_view.coffee index 7f72cab5d..76354fe84 100644 --- a/app/views/play/level/tome/spell_list_entry_view.coffee +++ b/app/views/play/level/tome/spell_list_entry_view.coffee @@ -13,6 +13,7 @@ module.exports = class SpellListEntryView extends View subscriptions: 'tome:problems-updated': "onProblemsUpdated" + 'tome:spell-changed-language': 'onSpellChangedLanguage' 'level-disable-controls': 'onDisableControls' 'level-enable-controls': 'onEnableControls' 'god:new-world-created': 'onNewWorld' @@ -30,11 +31,38 @@ module.exports = class SpellListEntryView extends View getRenderData: (context={}) -> context = super context context.spell = @spell - context.parameters = (@spell.parameters or []).join ', ' + context.methodSignature = @createMethodSignature() context.thangNames = (thangID for thangID, spellThang of @spell.thangs when spellThang.thang.exists).join(', ') # + ", Marcus, Robert, Phoebe, Will Smith, Zap Brannigan, You, Gandaaaaalf" context.showTopDivider = @showTopDivider context + createMethodSignature: -> + parameters = (@spell.parameters or []).slice() + if @spell.language in ['python', 'lua'] + parameters.unshift 'self' + else if @spell.language is 'io' + parameters.unshift '...' + paramString = parameters.join ', ' + name = @spell.name + switch @spell.language + when 'io' + "#{name} := method(#{paramString})" + when 'clojure' + "(defn #{name} [#{paramString}] ...)" + when 'python' + "def #{name}(#{paramString}):" + when 'lua' + "function #{name}(#{paramString}) ... end" + when 'coffeescript' + if parameters.length + "@#{name} = (#{paramString}) ->" + else + "@#{name} = ->" + when 'javascript' + "function #{name}(#{paramString}) { ... }" + else + "#{name}(#{paramString})" + getPrimarySpellThang: -> if @lastSelectedThang spellThang = _.find @spell.thangs, (spellThang) => spellThang.thang.id is @lastSelectedThang.id @@ -42,7 +70,7 @@ module.exports = class SpellListEntryView extends View for thangID, spellThang of @spell.thangs continue unless spellThang.thang.exists return spellThang # Just do the first one else - + afterRender: -> super() return unless @options.showTopDivider # Don't repeat Thang avatars when not changed from previous entry @@ -92,6 +120,10 @@ module.exports = class SpellListEntryView extends View return unless e.spell is @spell @$el.toggleClass "user-code-problem", e.problems.length + onSpellChangedLanguage: (e) -> + return unless e.spell is @spell + @render() # So that we can update parameters if needed + onDisableControls: (e) -> @toggleControls e, false onEnableControls: (e) -> @toggleControls e, true toggleControls: (e, enabled) -> @@ -105,7 +137,7 @@ module.exports = class SpellListEntryView extends View onNewWorld: (e) -> @lastSelectedThang = e.world.thangMap[@lastSelectedThang.id] if @lastSelectedThang - + destroy: -> @avatar?.destroy() super() diff --git a/app/views/play/level/tome/spell_palette_view.coffee b/app/views/play/level/tome/spell_palette_view.coffee index e14ff1507..d8746f80e 100644 --- a/app/views/play/level/tome/spell_palette_view.coffee +++ b/app/views/play/level/tome/spell_palette_view.coffee @@ -4,6 +4,7 @@ template = require 'templates/play/level/tome/spell_palette' filters = require 'lib/image_filter' SpellPaletteEntryView = require './spell_palette_entry_view' LevelComponent = require 'models/LevelComponent' +EditorConfigModal = require '../modal/editor_config_modal' N_ROWS = 4 @@ -16,6 +17,10 @@ module.exports = class SpellPaletteView extends View 'level-disable-controls': 'onDisableControls' 'level-enable-controls': 'onEnableControls' 'surface:frame-changed': "onFrameChanged" + 'tome:change-language': 'onTomeChangedLanguage' + + events: + 'click .code-language-logo': 'onEditEditorConfig' constructor: (options) -> super options @@ -39,7 +44,12 @@ module.exports = class SpellPaletteView extends View for entry in entryColumn col.append entry.el entry.render() # Render after appending so that we can access parent container for popover - $('.nano').nanoScroller() + $('.nano').nanoScroller() + @updateCodeLanguage @options.language + + updateCodeLanguage: (language) -> + @options.language = language + @$el.find('.code-language-logo').removeClass().addClass 'code-language-logo ' + language createPalette: -> lcs = @supermodel.getModels LevelComponent @@ -128,6 +138,12 @@ module.exports = class SpellPaletteView extends View return unless e.selectedThang?.id is @thang.id @options.thang = @thang = e.selectedThang # Update our thang to the current version + onTomeChangedLanguage: (e) -> + @updateCodeLanguage e.language + + onEditEditorConfig: (e) -> + @openModalView new EditorConfigModal session: @options.session + destroy: -> entry.destroy() for entry in @entries @toggleBackground = null diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee index 3c69d79c2..c519f7558 100644 --- a/app/views/play/level/tome/spell_view.coffee +++ b/app/views/play/level/tome/spell_view.coffee @@ -41,7 +41,7 @@ module.exports = class SpellView extends View 'tome:spell-changed': 'onSpellChanged' 'level:session-will-save': 'onSessionWillSave' 'modal-closed': 'focus' - 'focus-editor': 'focus' + 'tome:focus-editor': 'focus' 'tome:spell-statement-index-updated': 'onStatementIndexUpdated' 'tome:change-language': 'onChangeLanguage' 'tome:change-config': 'onChangeEditorConfig' diff --git a/app/views/play/level/tome/tome_view.coffee b/app/views/play/level/tome/tome_view.coffee index 1366722e8..1fca60902 100644 --- a/app/views/play/level/tome/tome_view.coffee +++ b/app/views/play/level/tome/tome_view.coffee @@ -162,7 +162,7 @@ module.exports = class TomeView extends View @spellList.$el.hide() onClick: (e) -> - Backbone.Mediator.publish 'focus-editor' unless $(e.target).parents('.popover').length + Backbone.Mediator.publish 'tome:focus-editor' unless $(e.target).parents('.popover').length clearSpellView: -> @spellView?.dismiss() @@ -201,7 +201,7 @@ module.exports = class TomeView extends View updateSpellPalette: (thang, spell) -> return unless thang and @spellPaletteView?.thang isnt thang and thang.programmableProperties or thang.apiProperties - @spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead() + @spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead(), language: spell.language, session: @options.session @spellPaletteView.toggleControls {}, spell.view.controlsEnabled if spell # TODO: know when palette should have been disabled but didn't exist spellFor: (thang, spellName) -> From a127cb7a5b71e02b89640c0d4c770dcedf3b4615 Mon Sep 17 00:00:00 2001 From: Darredevil Date: Thu, 26 Jun 2014 02:11:15 +0300 Subject: [PATCH 06/10] Added a joke tip --- app/templates/play/level/level_loading.jade | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/templates/play/level/level_loading.jade b/app/templates/play/level/level_loading.jade index 9cfc3622d..33de4253e 100644 --- a/app/templates/play/level/level_loading.jade +++ b/app/templates/play/level/level_loading.jade @@ -25,6 +25,7 @@ strong.tip(data-i18n='play_level.tip_impossible') It always seems impossible until it's done. - Nelson Mandela strong.tip.rare(data-i18n='play_level.tip_baby_coders') In the future, even babies will be Archmages. + strong.tip.rare(data-i18n='play_level.tip_hardware_problem') Q: How many programmers does it take to change a light bulb? A: None, it's a hardware problem. strong.tip.rare(data-i18n='play_level.tip_morale_improves') Loading will continue until morale improves. strong.tip.rare(data-i18n='play_level.tip_all_species') We believe in equal opportunities to learn programming for all species. strong.tip.rare(data-i18n='play_level.tip_reticulating') Reticulating spines. @@ -42,4 +43,4 @@ span= me.get('name') || 'Anoner' .errors - \ No newline at end of file + From 8c6ee66684613c5b892c2a476c1436f478c7ca6c Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 25 Jun 2014 20:19:11 -0700 Subject: [PATCH 07/10] Better handling of alternate spell palette documentation syntax for other code languages. --- app/schemas/models/level_component.coffee | 11 ++++- .../play/level/tome/spell_palette.jade | 2 +- .../tome/spell_palette_entry_view.coffee | 43 +++++++++++++++---- .../play/level/tome/spell_palette_view.coffee | 15 +++++-- app/views/play/level/tome/spell_view.coffee | 5 ++- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/app/schemas/models/level_component.coffee b/app/schemas/models/level_component.coffee index e1b101ebe..8612d8219 100644 --- a/app/schemas/models/level_component.coffee +++ b/app/schemas/models/level_component.coffee @@ -29,7 +29,16 @@ PropertyDocumentationSchema = c.object { description: {title: "Description", type: 'string', description: "Description of the property.", format: 'markdown', maxLength: 1000} args: c.array {title: "Arguments", description: "If this property has type 'function', then provide documentation for any function arguments."}, c.FunctionArgumentSchema owner: {title: "Owner", type: 'string', description: 'Owner of the property, like "this" or "Math".'} - example: {title: "Example", type: 'string', description: 'An optional example code block.', format: 'javascript'} + example: + oneOf: [ + {title: "Example", type: 'string', description: 'An optional example code block.', format: 'javascript'} + { + type: 'object', + title: "Language Examples", + description: "Examples by code language.", + additionalProperties: {type: 'string', description: 'An example code block.', format: 'javascript'} # TODO: not JS + } + ] returns: c.object { title: "Return Value" description: 'Optional documentation of any return value.' diff --git a/app/templates/play/level/tome/spell_palette.jade b/app/templates/play/level/tome/spell_palette.jade index 03450f9c2..2164a970b 100644 --- a/app/templates/play/level/tome/spell_palette.jade +++ b/app/templates/play/level/tome/spell_palette.jade @@ -4,7 +4,7 @@ ul(class="nav nav-pills" + (tabbed ? ' multiple-tabs' : '')) each slug, group in entryGroupSlugs li(class=group == "this" || slug == "available-spells" ? "active" : "") a(data-toggle="pill", data-target='#palette-tab-' + slug) - h4= group + h4= entryGroupNames[group] .tab-content each slug, group in entryGroupSlugs div(id="palette-tab-" + slug, class="tab-pane nano" + (group == "this" || slug == defaultGroupSlug ? " active" : "")) diff --git a/app/views/play/level/tome/spell_palette_entry_view.coffee b/app/views/play/level/tome/spell_palette_entry_view.coffee index 5a610d984..8e50bdea9 100644 --- a/app/views/play/level/tome/spell_palette_entry_view.coffee +++ b/app/views/play/level/tome/spell_palette_entry_view.coffee @@ -77,22 +77,49 @@ module.exports = class SpellPaletteEntryView extends View if _.isString @doc @doc = name: @doc, type: typeof @thang[@doc] if options.isSnippet - @doc.type = @doc.owner = 'snippet' + @doc.type = 'snippet' + @doc.owner = 'snippets' @doc.shortName = @doc.shorterName = @doc.title = @doc.name else @doc.owner ?= 'this' - suffix = '' + ownerName = @doc.ownerName = if @doc.owner isnt 'this' then @doc.owner else switch options.language + when 'python', 'lua' then 'self' + when 'coffeescript' then '@' + else 'this' if @doc.type is 'function' - argNames = (arg.name for arg in @doc.args ? []).join(', ') - argNames = '...' if argNames.length > 6 - suffix = "(#{argNames})" - @doc.shortName = "#{@doc.owner}.#{@doc.name}#{suffix};" - if @doc.owner is 'this' or options.tabbify - @doc.shorterName = "#{@doc.name}#{suffix}" + sep = {clojure: ' '}[options.language] ? ', ' + argNames = (arg.name for arg in @doc.args ? []).join sep + argString = if argNames then '__ARGS__' else '' + @doc.shortName = switch options.language + when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{@doc.name}#{if argString then ' ' + argString else '()'}" + when 'python' then "#{ownerName}.#{@doc.name}(#{argString})" + when 'lua' then "#{ownerName}:#{@doc.name}(#{argString})" + when 'clojure' then "(#{@doc.name} #{ownerName}#{if argNames then ' ' + argString else ''})" + when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{@doc.name}#{if argNames then '(' + argNames + ')' else ''}" + else "#{ownerName}.#{@doc.name}(#{argString});" else + @doc.shortName = switch options.language + when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{@doc.name}" + when 'python' then "#{ownerName}.#{@doc.name}" + when 'lua' then "#{ownerName}.#{@doc.name}" + when 'clojure' then "(#{@doc.name} #{ownerName})" + when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{@doc.name}" + else "#{ownerName}.#{@doc.name};" + @doc.shorterName = @doc.shortName + if @doc.type is 'function' and argString + @doc.shortName = @doc.shorterName.replace argString, argNames + @doc.shorterName = @doc.shorterName.replace argString, (if argNames.length > 6 then '...' else argNames) + if @options.language is 'javascript' @doc.shorterName = @doc.shortName.replace ';', '' + if @doc.owner is 'this' or options.tabbify + @doc.shorterName = @doc.shorterName.replace /^this\./, '' @doc.title = if options.shortenize then @doc.shorterName else @doc.shortName + if example = @doc.example?[options.language] + @doc.example = example + else unless _.isString @doc.example + @doc.example = null + getRenderData: -> c = super() c.doc = @doc diff --git a/app/views/play/level/tome/spell_palette_view.coffee b/app/views/play/level/tome/spell_palette_view.coffee index d8746f80e..41f529499 100644 --- a/app/views/play/level/tome/spell_palette_view.coffee +++ b/app/views/play/level/tome/spell_palette_view.coffee @@ -31,6 +31,7 @@ module.exports = class SpellPaletteView extends View c = super() c.entryGroups = @entryGroups c.entryGroupSlugs = @entryGroupSlugs + c.entryGroupNames = @entryGroupNames c.tabbed = _.size(@entryGroups) > 1 c.defaultGroupSlug = @defaultGroupSlug c @@ -96,7 +97,7 @@ module.exports = class SpellPaletteView extends View return 'more' if entry.doc.owner is 'this' and entry.doc.name in (propGroups.more ? []) entry.doc.owner @entries = _.sortBy @entries, (entry) -> - order = ['this', 'more', 'Math', 'Vector', 'snippets'] + order = ['this', 'more', 'Math', 'Vector', 'String', 'Object', 'Array', 'Function', 'snippets'] index = order.indexOf groupForEntry entry index = String.fromCharCode if index is -1 then order.length else index index += entry.doc.name @@ -108,13 +109,18 @@ module.exports = class SpellPaletteView extends View @entryGroups[defaultGroup] = @entries @defaultGroupSlug = _.string.slugify defaultGroup @entryGroupSlugs = {} + @entryGroupNames = {} for group, entries of @entryGroups - @entryGroupSlugs[group] = _.string.slugify group @entryGroups[group] = _.groupBy entries, (entry, i) -> Math.floor i / N_ROWS + @entryGroupSlugs[group] = _.string.slugify group + @entryGroupNames[group] = group + if thisName = {coffeescript: '@', lua: 'self', clojure: 'self'}[@options.language] + if @entryGroupNames.this + @entryGroupNames.this = thisName null addEntry: (doc, shortenize, tabbify, isSnippet=false) -> - new SpellPaletteEntryView doc: doc, thang: @thang, shortenize: shortenize, tabbify: tabbify, isSnippet: isSnippet + new SpellPaletteEntryView doc: doc, thang: @thang, shortenize: shortenize, tabbify: tabbify, isSnippet: isSnippet, language: @options.language onDisableControls: (e) -> @toggleControls e, false onEnableControls: (e) -> @toggleControls e, true @@ -140,6 +146,9 @@ module.exports = class SpellPaletteView extends View onTomeChangedLanguage: (e) -> @updateCodeLanguage e.language + entry.destroy() for entry in @entries + @createPalette() + @render() onEditEditorConfig: (e) -> @openModalView new EditorConfigModal session: @options.session diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee index c519f7558..4c8213ace 100644 --- a/app/views/play/level/tome/spell_view.coffee +++ b/app/views/play/level/tome/spell_view.coffee @@ -272,7 +272,10 @@ module.exports = class SpellView extends View else @ace.setValue source @eventsSuppressed = false - @ace.resize true # hack: @ace may not have updated its text properly, so we force it to refresh + try + @ace.resize true # hack: @ace may not have updated its text properly, so we force it to refresh + catch error + console.warn "Error resizing ACE after an update:", error # Called from CastButtonView initially and whenever the delay is changed setAutocastDelay: (@autocastDelay) -> From c6f19f7d3a90eb6fc237c98b6f5f4954954b6d25 Mon Sep 17 00:00:00 2001 From: Darredevil Date: Thu, 26 Jun 2014 06:23:36 +0300 Subject: [PATCH 08/10] Added new tip tag --- app/locale/en.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 99f807094..ba4f80c7e 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -426,6 +426,7 @@ tip_impossible: "It always seems impossible until it's done. - Nelson Mandela" tip_talk_is_cheap: "Talk is cheap. Show me the code. - Linus Torvalds" tip_first_language: "The most disastrous thing that you can ever learn is your first programming language. - Alan Kay" + tip_hardware_problem: "Q: How many programmers does it take to change a light bulb? A: None, it's a hardware problem." time_current: "Now:" time_total: "Max:" time_goto: "Go to:" From aee95ac5c0f373255445f7205ea10d18cc0496c1 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 25 Jun 2014 22:56:39 -0700 Subject: [PATCH 09/10] Improved per-language spell palette and tab documentation. --- app/schemas/models/level_component.coffee | 33 ++++- app/schemas/schemas.coffee | 22 ++- app/schemas/subscriptions/tome.coffee | 2 + app/templates/home.jade | 101 ++++++------- .../tome/spell_palette_entry_popover.jade | 15 +- .../play/level/tome/doc_formatter.coffee | 124 ++++++++++++++++ app/views/play/level/tome/spell.coffee | 4 +- .../tome/spell_list_tab_entry_view.coffee | 43 ++---- .../tome/spell_palette_entry_view.coffee | 136 +----------------- .../play/level/tome/spell_palette_view.coffee | 1 - app/views/play/level/tome/tome_view.coffee | 2 +- 11 files changed, 263 insertions(+), 220 deletions(-) create mode 100644 app/views/play/level/tome/doc_formatter.coffee diff --git a/app/schemas/models/level_component.coffee b/app/schemas/models/level_component.coffee index 8612d8219..3069b16b1 100644 --- a/app/schemas/models/level_component.coffee +++ b/app/schemas/models/level_component.coffee @@ -26,7 +26,16 @@ PropertyDocumentationSchema = c.object { name: {type: 'string', title: "Name", description: "Name of the property."} # not actual JS types, just whatever they describe... type: c.shortString(title: "Type", description: "Intended type of the property.") - description: {title: "Description", type: 'string', description: "Description of the property.", format: 'markdown', maxLength: 1000} + description: + oneOf: [ + {title: "Description", type: 'string', description: "Description of the property.", maxLength: 1000, format: 'markdown'} + { + type: 'object', + title: "Language Descriptions", + description: "Property descriptions by code language.", + additionalProperties: {type: 'string', description: "Description of the property.", maxLength: 1000, format: 'markdown'} + } + ] args: c.array {title: "Arguments", description: "If this property has type 'function', then provide documentation for any function arguments."}, c.FunctionArgumentSchema owner: {title: "Owner", type: 'string', description: 'Owner of the property, like "this" or "Math".'} example: @@ -46,8 +55,26 @@ PropertyDocumentationSchema = c.object { default: {type: 'null'} }, type: c.shortString(title: "Type", description: "Type of the return value") - example: c.shortString(title: "Example", description: "Example return value") - description: {title: "Description", type: 'string', description: "Description of the return value.", maxLength: 1000} + example: + oneOf: [ + c.shortString(title: "Example", description: "Example return value") + { + type: 'object', + title: "Language Examples", + description: "Example return values by code language.", + additionalProperties: c.shortString(description: 'Example return value.', format: 'javascript') # TODO: not JS + } + ] + description: + oneOf: [ + {title: "Description", type: 'string', description: "Description of the return value.", maxLength: 1000} + { + type: 'object', + title: "Language Descriptions", + description: "Example return values by code language.", + additionalProperties: {type: 'string', description: "Description of the return value.", maxLength: 1000} + } + ] DependencySchema = c.object { title: "Component Dependency" diff --git a/app/schemas/schemas.coffee b/app/schemas/schemas.coffee index a6c7591e9..e9197ee90 100644 --- a/app/schemas/schemas.coffee +++ b/app/schemas/schemas.coffee @@ -164,8 +164,26 @@ me.FunctionArgumentSchema = me.object { name: {type: 'string', pattern: me.identifierPattern, title: "Name", description: "Name of the function argument."} # not actual JS types, just whatever they describe... type: me.shortString(title: "Type", description: "Intended type of the argument.") - example: me.shortString(title: "Example", description: "Example value for the argument.") - description: {title: "Description", type: 'string', description: "Description of the argument.", maxLength: 1000} + example: + oneOf: [ + me.shortString(title: "Example", description: "Example value for the argument.") + { + type: 'object', + title: "Language Examples", + description: "Examples by code language.", + additionalProperties: me.shortString(description: 'Example value for the argument.') + } + ] + description: + oneOf: [ + {title: "Description", type: 'string', description: "Description of the argument.", maxLength: 1000} + { + type: 'object', + title: "Language Descriptions", + description: "Example argument descriptions by code language.", + additionalProperties: {type: 'string', description: "Description of the argument.", maxLength: 1000} + } + ] "default": title: "Default" description: "Default value of the argument. (Your code should set this.)" diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee index aa5f96eb1..3f73c188f 100644 --- a/app/schemas/subscriptions/tome.coffee +++ b/app/schemas/subscriptions/tome.coffee @@ -90,4 +90,6 @@ module.exports = properties: spell: type: "object" + language: + type: "string" required: ["spell"] diff --git a/app/templates/home.jade b/app/templates/home.jade index 217a40df2..20c683190 100644 --- a/app/templates/home.jade +++ b/app/templates/home.jade @@ -4,54 +4,59 @@ block content h1#site-slogan(data-i18n="home.slogan") Learn to Code by Playing a Game - .code-languages - .primary-code-languages.row - .col-md-6 - .code-language#javascript(data-code-language='javascript') - .code-wizard - h2 JavaScript - p The language of the web. Great for writing websites, web apps, HTML5 games, and servers. - - .col-md-6 - .code-language.beta#python(data-code-language='python') - .code-wizard - .code-language-beta - h2 Python - p Simple yet powerful, Python is a great general purpose programming language. - - .secondary-code-languages.row - .col-md-3 - .code-language.beta#coffeescript(data-code-language='coffeescript') - .code-language-logo - .code-wizard - .code-language-beta - h3 CoffeeScript - p Nicer JavaScript syntax - - .col-md-3 - .code-language.beta#clojure(data-code-language='clojure') - .code-language-logo - .code-wizard - .code-language-beta - h3 Clojure - p A modern Lisp - - .col-md-3 - .code-language.beta#lua(data-code-language='lua') - .code-language-logo - .code-wizard - .code-language-beta - h3 Lua - p Game scripting language - - .col-md-3 - .code-language.beta#io(data-code-language='io') - .code-language-logo - .code-wizard - .code-language-beta - h3 Io - p Simple but obscure - + if me.isAdmin() + // Admin gate until fully tested + .code-languages + .primary-code-languages.row + .col-md-6 + .code-language#javascript(data-code-language='javascript') + .code-wizard + h2 JavaScript + p The language of the web. Great for writing websites, web apps, HTML5 games, and servers. + + .col-md-6 + .code-language.beta#python(data-code-language='python') + .code-wizard + .code-language-beta + h2 Python + p Simple yet powerful, Python is a great general purpose programming language. + + .secondary-code-languages.row + .col-md-3 + .code-language.beta#coffeescript(data-code-language='coffeescript') + .code-language-logo + .code-wizard + .code-language-beta + h3 CoffeeScript + p Nicer JavaScript syntax + + .col-md-3 + .code-language.beta#clojure(data-code-language='clojure') + .code-language-logo + .code-wizard + .code-language-beta + h3 Clojure + p A modern Lisp + + .col-md-3 + .code-language.beta#lua(data-code-language='lua') + .code-language-logo + .code-wizard + .code-language-beta + h3 Lua + p Game scripting language + + .col-md-3 + .code-language.beta#io(data-code-language='io') + .code-language-logo + .code-wizard + .code-language-beta + h3 Io + p Simple but obscure + else + // Old + #front-screenshot + img(src="/images/pages/home/front_screenshot_01.png", alt="") .alert.alert-danger.lt-ie10 strong(data-i18n="home.no_ie") CodeCombat does not run in Internet Explorer 9 or older. Sorry! diff --git a/app/templates/play/level/tome/spell_palette_entry_popover.jade b/app/templates/play/level/tome/spell_palette_entry_popover.jade index 56577c4e7..a8a79503e 100644 --- a/app/templates/play/level/tome/spell_palette_entry_popover.jade +++ b/app/templates/play/level/tome/spell_palette_entry_popover.jade @@ -11,11 +11,22 @@ if doc.example p.example strong Example: div!= marked("```\n" + doc.example + "```") -else if doc.type == 'function' +else if doc.type == 'function' && argumentExamples.length p.example strong Example: div - code= doc.owner + '.' + doc.name + '(' + argumentExamples.join(', ') + ');' + if language == 'javascript' + code= doc.owner + '.' + doc.name + '(' + argumentExamples.join(', ') + ');' + else if language == 'coffeescript' + code= doc.ownerName + (doc.ownerName == '@' ? '' : '.') + doc.name + ' ' + argumentExamples.join(', ') + else if language == 'python' + code= doc.ownerName + '.' + doc.name + '(' + argumentExamples.join(', ') + ')' + else if language == 'clojure' + code= '(.' + doc.name + ' ' + doc.ownerName + ' ' + argumentExamples.join(', ') + ')' + else if language == 'lua' + code= doc.ownerName + ':' + doc.name + '(' + argumentExamples.join(', ') + ')' + else if language == 'io' + code= (doc.ownerName == 'this' ? '' : doc.ownerName + ' ') + doc.name + '(' + argumentExamples.join(', ') + ')' if (doc.type != 'function' && doc.type != 'snippet') || doc.name == 'now' p.value diff --git a/app/views/play/level/tome/doc_formatter.coffee b/app/views/play/level/tome/doc_formatter.coffee new file mode 100644 index 000000000..20923916a --- /dev/null +++ b/app/views/play/level/tome/doc_formatter.coffee @@ -0,0 +1,124 @@ +popoverTemplate = require 'templates/play/level/tome/spell_palette_entry_popover' +{downTheChain} = require 'lib/world/world_utils' +window.Vector = require 'lib/world/vector' # So we can document it + +safeJSONStringify = (input, maxDepth) -> + recursion = (input, path, depth) -> + output = {} + pPath = undefined + refIdx = undefined + path = path or "" + depth = depth or 0 + depth++ + return "{depth over " + maxDepth + "}" if maxDepth and depth > maxDepth + for p of input + pPath = ((if path then (path + ".") else "")) + p + if typeof input[p] is "function" + output[p] = "{function}" + else if typeof input[p] is "object" + refIdx = refs.indexOf(input[p]) + if -1 isnt refIdx + output[p] = "{reference to " + refsPaths[refIdx] + "}" + else + refs.push input[p] + refsPaths.push pPath + output[p] = recursion(input[p], pPath, depth) + else + output[p] = input[p] + output + refs = [] + refsPaths = [] + maxDepth = maxDepth or 5 + if typeof input is "object" + output = recursion(input) + else + output = input + JSON.stringify output, null, 1 + +module.exports = class DocFormatter + constructor: (@options) -> + @doc = _.cloneDeep options.doc + @fillOutDoc() + + fillOutDoc: -> + if _.isString @doc + @doc = name: @doc, type: typeof @options.thang[@doc] + if @options.isSnippet + @doc.type = 'snippet' + @doc.owner = 'snippets' + @doc.shortName = @doc.shorterName = @doc.title = @doc.name + else + @doc.owner ?= 'this' + ownerName = @doc.ownerName = if @doc.owner isnt 'this' then @doc.owner else switch @options.language + when 'python', 'lua' then 'self' + when 'coffeescript' then '@' + else 'this' + if @doc.type is 'function' + sep = {clojure: ' '}[@options.language] ? ', ' + argNames = (arg.name for arg in @doc.args ? []).join sep + argString = if argNames then '__ARGS__' else '' + @doc.shortName = switch @options.language + when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{@doc.name}#{if argString then ' ' + argString else '()'}" + when 'python' then "#{ownerName}.#{@doc.name}(#{argString})" + when 'lua' then "#{ownerName}:#{@doc.name}(#{argString})" + when 'clojure' then "(.#{@doc.name} #{ownerName}#{if argNames then ' ' + argString else ''})" + when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{@doc.name}#{if argNames then '(' + argNames + ')' else ''}" + else "#{ownerName}.#{@doc.name}(#{argString});" + else + @doc.shortName = switch @options.language + when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{@doc.name}" + when 'python' then "#{ownerName}.#{@doc.name}" + when 'lua' then "#{ownerName}.#{@doc.name}" + when 'clojure' then "(.#{@doc.name} #{ownerName})" + when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{@doc.name}" + else "#{ownerName}.#{@doc.name};" + @doc.shorterName = @doc.shortName + if @doc.type is 'function' and argString + @doc.shortName = @doc.shorterName.replace argString, argNames + @doc.shorterName = @doc.shorterName.replace argString, (if argNames.length > 6 then '...' else argNames) + if @options.language is 'javascript' + @doc.shorterName = @doc.shortName.replace ';', '' + if @doc.owner is 'this' or @options.tabbify + @doc.shorterName = @doc.shorterName.replace /^this\./, '' + @doc.title = if @options.shortenize then @doc.shorterName else @doc.shortName + + # Grab the language-specific documentation for some sub-properties, if we have it. + toTranslate = [{obj: @doc, prop: 'example'}, {obj: @doc, prop: 'returns'}] + for arg in (@doc.args ? []) + toTranslate.push {obj: arg, prop: 'example'}, {obj: arg, prop: 'description'} + for {obj, prop} in toTranslate + if val = obj[prop]?[@options.language] + obj[prop] = val + else unless _.isString obj[prop] + obj[prop] = null + + formatPopover: -> + content = popoverTemplate doc: @doc, language: @options.language, value: @formatValue(), marked: marked, argumentExamples: (arg.example or arg.default or arg.name for arg in @doc.args ? []) + owner = if @doc.owner is 'this' then @options.thang else window[@doc.owner] + content = content.replace /#{spriteName}/g, @options.thang.type ? @options.thang.spriteName # Prefer type, and excluded the quotes we'd get with @formatValue + content.replace /\#\{(.*?)\}/g, (s, properties) => @formatValue downTheChain(owner, properties.split('.')) + + formatValue: (v) -> + return null if @doc.type is 'snippet' + return @options.thang.now() if @doc.name is 'now' + return '[Function]' if not v and @doc.type is 'function' + unless v? + if @doc.owner is 'this' + v = @options.thang[@doc.name] + else + v = window[@doc.owner][@doc.name] # grab Math or Vector + if @doc.type is 'number' and not isNaN v + if v == Math.round v + return v + return v.toFixed 2 + if _.isString v + return "\"#{v}\"" + if v?.id + return v.id + if v?.name + return v.name + if _.isArray v + return '[' + (@formatValue v2 for v2 in v).join(', ') + ']' + if _.isPlainObject v + return safeJSONStringify v, 2 + v diff --git a/app/views/play/level/tome/spell.coffee b/app/views/play/level/tome/spell.coffee index 98077a4e0..6abab9dc0 100644 --- a/app/views/play/level/tome/spell.coffee +++ b/app/views/play/level/tome/spell.coffee @@ -34,7 +34,7 @@ module.exports = class Spell @thangs = {} @view = new SpellView {spell: @, session: @session, worker: @worker} @view.render() # Get it ready and code loaded in advance - @tabView = new SpellListTabEntryView spell: @, supermodel: @supermodel + @tabView = new SpellListTabEntryView spell: @, supermodel: @supermodel, language: @language @tabView.render() @team = @permissions.readwrite[0] ? "common" Backbone.Mediator.publish 'tome:spell-created', spell: @ @@ -146,7 +146,7 @@ module.exports = class Spell for thangId, spellThang of @thangs spellThang.aether?.setLanguage @language spellThang.castAether = null - Backbone.Mediator.publish 'tome:spell-changed-language', spell: @ + Backbone.Mediator.publish 'tome:spell-changed-language', spell: @, language: @language workerMessage = function: "updateLanguageAether" newLanguage: @language diff --git a/app/views/play/level/tome/spell_list_tab_entry_view.coffee b/app/views/play/level/tome/spell_list_tab_entry_view.coffee index 51c54263a..df5710d2b 100644 --- a/app/views/play/level/tome/spell_list_tab_entry_view.coffee +++ b/app/views/play/level/tome/spell_list_tab_entry_view.coffee @@ -1,9 +1,8 @@ SpellListEntryView = require './spell_list_entry_view' ThangAvatarView = require 'views/play/level/thang_avatar_view' template = require 'templates/play/level/tome/spell_list_tab_entry' -popoverTemplate = require 'templates/play/level/tome/spell_palette_entry_popover' LevelComponent = require 'models/LevelComponent' -{downTheChain} = require 'lib/world/world_utils' +DocFormatter = require './doc_formatter' module.exports = class SpellListTabEntryView extends SpellListEntryView template: template @@ -13,6 +12,7 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView 'tome:spell-loaded': "onSpellLoaded" 'tome:spell-changed': "onSpellChanged" 'god:new-world-created': 'onNewWorld' + 'tome:spell-changed-language': 'onSpellChangedLanguage' events: 'click .spell-list-button': 'onDropdownClick' @@ -60,43 +60,16 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView found = true break return unless found - doc = _.clone doc - doc.owner = 'this' - doc.shortName = doc.shorterName = doc.title = "this.#{doc.name}();" + docFormatter = new DocFormatter doc: doc, thang: @thang, language: @options.language @$el.find('code').popover( animation: true html: true placement: 'bottom' trigger: 'hover' - content: @formatPopover doc + content: docFormatter.formatPopover() container: @$el.parent() ) - formatPopover: (doc) -> - content = popoverTemplate doc: doc, marked: marked, argumentExamples: (arg.example or arg.default or arg.name for arg in doc.args ? []) - owner = @thang - content = content.replace /#{spriteName}/g, @thang.type ? @thang.spriteName # Prefer type, and excluded the quotes we'd get with @formatValue - content.replace /\#\{(.*?)\}/g, (s, properties) => @formatValue downTheChain(owner, properties.split('.')) - - formatValue: (v) -> - # TODO: refactor and move spell_palette_entry_view version of this somewhere else - # maybe think about making it common with what Aether does and the SpellDebugView, too - if _.isNumber v - if v == Math.round v - return v - return v.toFixed 2 - if _.isString v - return "\"#{v}\"" - if v?.id - return v.id - if v?.name - return v.name - if _.isArray v - return '[' + (@formatValue v2 for v2 in v).join(', ') + ']' - if _.isPlainObject v - return safeJSONStringify v, 2 - v - onMouseEnterAvatar: (e) -> # Don't call super onMouseLeaveAvatar: (e) -> # Don't call super onClick: (e) -> # Don't call super @@ -125,6 +98,14 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView return unless e.spell is @spell @updateReloadButton() + onSpellChangedLanguage: (e) -> + return unless e.spell is @spell + @options.language = e.language + @$el.find('code').popover 'destroy' + @render() + @docsBuilt = false + @buildDocs() if @thang + toggleControls: (e, enabled) -> # Don't call super; do it differently return if e.controls and not ('editor' in e.controls) diff --git a/app/views/play/level/tome/spell_palette_entry_view.coffee b/app/views/play/level/tome/spell_palette_entry_view.coffee index 8e50bdea9..fe8e0cab0 100644 --- a/app/views/play/level/tome/spell_palette_entry_view.coffee +++ b/app/views/play/level/tome/spell_palette_entry_view.coffee @@ -1,57 +1,8 @@ View = require 'views/kinds/CocoView' template = require 'templates/play/level/tome/spell_palette_entry' -popoverTemplate = require 'templates/play/level/tome/spell_palette_entry_popover' {me} = require 'lib/auth' filters = require 'lib/image_filter' -{downTheChain} = require 'lib/world/world_utils' -window.Vector = require 'lib/world/vector' # So we can document it - -safeJSONStringify = (input, maxDepth) -> - recursion = (input, path, depth) -> - output = {} - pPath = undefined - refIdx = undefined - path = path or "" - depth = depth or 0 - depth++ - return "{depth over " + maxDepth + "}" if maxDepth and depth > maxDepth - for p of input - pPath = ((if path then (path + ".") else "")) + p - if typeof input[p] is "function" - output[p] = "{function}" - else if typeof input[p] is "object" - refIdx = refs.indexOf(input[p]) - if -1 isnt refIdx - output[p] = "{reference to " + refsPaths[refIdx] + "}" - else - refs.push input[p] - refsPaths.push pPath - output[p] = recursion(input[p], pPath, depth) - else - output[p] = input[p] - output - refs = [] - refsPaths = [] - maxDepth = maxDepth or 5 - if typeof input is "object" - output = recursion(input) - else - output = input - JSON.stringify output, null, 1 - -# http://stackoverflow.com/a/987376/540620 -$.fn.selectText = -> - el = @[0] - if document.body.createTextRange - range = document.body.createTextRange() - range.moveToElementText(el) - range.select() - else if window.getSelection - selection = window.getSelection() - range = document.createRange() - range.selectNodeContents(el) - selection.removeAllRanges() - selection.addRange(range) +DocFormatter = require './doc_formatter' module.exports = class SpellPaletteEntryView extends View tagName: 'div' # Could also try instead of
, but would need to adjust colors @@ -73,52 +24,8 @@ module.exports = class SpellPaletteEntryView extends View constructor: (options) -> super options @thang = options.thang - @doc = options.doc - if _.isString @doc - @doc = name: @doc, type: typeof @thang[@doc] - if options.isSnippet - @doc.type = 'snippet' - @doc.owner = 'snippets' - @doc.shortName = @doc.shorterName = @doc.title = @doc.name - else - @doc.owner ?= 'this' - ownerName = @doc.ownerName = if @doc.owner isnt 'this' then @doc.owner else switch options.language - when 'python', 'lua' then 'self' - when 'coffeescript' then '@' - else 'this' - if @doc.type is 'function' - sep = {clojure: ' '}[options.language] ? ', ' - argNames = (arg.name for arg in @doc.args ? []).join sep - argString = if argNames then '__ARGS__' else '' - @doc.shortName = switch options.language - when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{@doc.name}#{if argString then ' ' + argString else '()'}" - when 'python' then "#{ownerName}.#{@doc.name}(#{argString})" - when 'lua' then "#{ownerName}:#{@doc.name}(#{argString})" - when 'clojure' then "(#{@doc.name} #{ownerName}#{if argNames then ' ' + argString else ''})" - when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{@doc.name}#{if argNames then '(' + argNames + ')' else ''}" - else "#{ownerName}.#{@doc.name}(#{argString});" - else - @doc.shortName = switch options.language - when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{@doc.name}" - when 'python' then "#{ownerName}.#{@doc.name}" - when 'lua' then "#{ownerName}.#{@doc.name}" - when 'clojure' then "(#{@doc.name} #{ownerName})" - when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{@doc.name}" - else "#{ownerName}.#{@doc.name};" - @doc.shorterName = @doc.shortName - if @doc.type is 'function' and argString - @doc.shortName = @doc.shorterName.replace argString, argNames - @doc.shorterName = @doc.shorterName.replace argString, (if argNames.length > 6 then '...' else argNames) - if @options.language is 'javascript' - @doc.shorterName = @doc.shortName.replace ';', '' - if @doc.owner is 'this' or options.tabbify - @doc.shorterName = @doc.shorterName.replace /^this\./, '' - @doc.title = if options.shortenize then @doc.shorterName else @doc.shortName - - if example = @doc.example?[options.language] - @doc.example = example - else unless _.isString @doc.example - @doc.example = null + @docFormatter = new DocFormatter options + @doc = @docFormatter.doc getRenderData: -> c = super() @@ -133,46 +40,15 @@ module.exports = class SpellPaletteEntryView extends View html: true placement: 'top' trigger: 'manual' # Hover, until they click, which will then pin it until unclick. - content: @formatPopover() + content: @docFormatter.formatPopover() container: '#tome-view' ) @$el.on 'show.bs.popover', => Backbone.Mediator.publish 'tome:palette-hovered', thang: @thang, prop: @doc.name, entry: @ - formatPopover: -> - content = popoverTemplate doc: @doc, value: @formatValue(), marked: marked, argumentExamples: (arg.example or arg.default or arg.name for arg in @doc.args ? []) - owner = if @doc.owner is 'this' then @thang else window[@doc.owner] - content = content.replace /#{spriteName}/g, @thang.type ? @thang.spriteName # Prefer type, and excluded the quotes we'd get with @formatValue - content.replace /\#\{(.*?)\}/g, (s, properties) => @formatValue downTheChain(owner, properties.split('.')) - - formatValue: (v) -> - return null if @doc.type is 'snippet' - return @thang.now() if @doc.name is 'now' - return '[Function]' if not v and @doc.type is 'function' - unless v? - if @doc.owner is 'this' - v = @thang[@doc.name] - else - v = window[@doc.owner][@doc.name] # grab Math or Vector - if @doc.type is 'number' and not isNaN v - if v == Math.round v - return v - return v.toFixed 2 - if _.isString v - return "\"#{v}\"" - if v?.id - return v.id - if v?.name - return v.name - if _.isArray v - return '[' + (@formatValue v2 for v2 in v).join(', ') + ']' - if _.isPlainObject v - return safeJSONStringify v, 2 - v - onMouseEnter: (e) -> # Make sure the doc has the updated Thang so it can regenerate its prop value - @$el.data('bs.popover').options.content = @formatPopover() + @$el.data('bs.popover').options.content = @docFormatter.formatPopover() @$el.popover('setContent') @$el.popover 'show' unless @popoverPinned or @otherPopoverPinned @@ -200,7 +76,7 @@ module.exports = class SpellPaletteEntryView extends View onFrameChanged: (e) -> return unless e.selectedThang?.id is @thang.id - @options.thang = @thang = e.selectedThang # Update our thang to the current version + @options.thang = @thang = @docFormatter.options.thang = e.selectedThang # Update our thang to the current version onPaletteHovered: (e) -> return if e.entry is @ diff --git a/app/views/play/level/tome/spell_palette_view.coffee b/app/views/play/level/tome/spell_palette_view.coffee index 41f529499..83e007238 100644 --- a/app/views/play/level/tome/spell_palette_view.coffee +++ b/app/views/play/level/tome/spell_palette_view.coffee @@ -57,7 +57,6 @@ module.exports = class SpellPaletteView extends View allDocs = {} for lc in lcs for doc in (lc.get('propertyDocumentation') ? []) - doc = _.clone doc allDocs['__' + doc.name] ?= [] allDocs['__' + doc.name].push doc if doc.type is 'snippet' then doc.owner = 'snippets' diff --git a/app/views/play/level/tome/tome_view.coffee b/app/views/play/level/tome/tome_view.coffee index 1fca60902..5f628e842 100644 --- a/app/views/play/level/tome/tome_view.coffee +++ b/app/views/play/level/tome/tome_view.coffee @@ -201,7 +201,7 @@ module.exports = class TomeView extends View updateSpellPalette: (thang, spell) -> return unless thang and @spellPaletteView?.thang isnt thang and thang.programmableProperties or thang.apiProperties - @spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead(), language: spell.language, session: @options.session + @spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead(), language: spell?.language ? @options.session.get('codeLanguage'), session: @options.session @spellPaletteView.toggleControls {}, spell.view.controlsEnabled if spell # TODO: know when palette should have been disabled but didn't exist spellFor: (thang, spellName) -> From e294133bcfba05f2e05efbb4ad47d44e5fbbe882 Mon Sep 17 00:00:00 2001 From: George Saines Date: Thu, 26 Jun 2014 10:38:13 -0700 Subject: [PATCH 10/10] adding the files I forgot --- .../images/pages/employer/employer_icon5.png | Bin 0 -> 1990 bytes .../images/pages/employer/employer_icon6.png | Bin 0 -> 2171 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 app/assets/images/pages/employer/employer_icon5.png create mode 100644 app/assets/images/pages/employer/employer_icon6.png diff --git a/app/assets/images/pages/employer/employer_icon5.png b/app/assets/images/pages/employer/employer_icon5.png new file mode 100644 index 0000000000000000000000000000000000000000..85d94b04c309db5f6c9027fefc3397934892158d GIT binary patch literal 1990 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 EXD=(6M*si- literal 0 HcmV?d00001