i18n, comments, misc cleanup

This commit is contained in:
Nick Winter 2016-07-17 00:53:17 -07:00
parent 320aa0f3d9
commit 6e65171a83
23 changed files with 112 additions and 129 deletions

View file

@ -51,6 +51,7 @@ function create(dom) {
virtualDOM = dom;
concreteDOM = deku.dom.create(dom);
// TODO: target the actual HTML tag and combine our initial structure for styles/scripts/tags with theirs
// TODO: :after elements don't seem to work? (:before do)
$('body').empty().append(concreteDOM);
}

View file

@ -420,7 +420,8 @@ module.exports = class LevelLoader extends CocoClass
resource.markLoaded() if resource.spriteSheetKeys.length is 0
denormalizeSession: ->
return if @headless or @sessionDenormalized or @spectateMode or @sessionless or me.isSessionless()
return if @sessionDenormalized or @spectateMode or @sessionless or me.isSessionless()
return if @headless and not @level.isType('web-dev')
# This is a way (the way?) PUT /db/level.sessions/undefined was happening
# See commit c242317d9
return if not @session.id

View file

@ -450,8 +450,6 @@
incomplete: "Incomplete"
timed_out: "Ran out of time"
failing: "Failing"
control_bar_multiplayer: "Multiplayer"
control_bar_join_game: "Join Game"
reload: "Reload"
reload_title: "Reload All Code?"
reload_really: "Are you sure you want to reload this level back to the beginning?"
@ -480,8 +478,7 @@
tome_cast_button_running: "Running"
tome_cast_button_ran: "Ran"
tome_submit_button: "Submit"
tome_reload_method: "Reload original code for this method" # Title text for individual method reload button.
tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methods).
tome_reload_method: "Reload original code to restart the level" # {change}
tome_available_spells: "Available Spells"
tome_your_skills: "Your Skills"
tome_current_method: "Current Method"
@ -1475,6 +1472,29 @@
status_not_enrolled: "Not Enrolled"
status_enrolled: "Expires on {{date}}"
select_all: "Select All"
projects: "Projects"
sharing:
game: "Game"
webpage: "Webpage"
share_game: "Share This Game"
share_web: "Share This Webpage"
victory_share_prefix: "Share this link to invite your friends & family to"
victory_share_game: "play your game level"
victory_share_web: "view your webpage"
victory_share_suffix: "."
victory_course_share_prefix: "This link will let your friends & family"
victory_course_share_game: "play the game"
victory_course_share_web: "view the webpage"
victory_course_share_suffix: "you just created."
copy_url: "Copy URL"
game_dev:
creator: "Creator"
web_dev:
image_gallery_title: "Image Gallery"
image_gallery_description: "Copy these images into your webpage, or find your own image URLs online."
classes:
archmage_title: "Archmage"

View file

@ -264,4 +264,12 @@ me.concept = me.shortString enum: [
'basic_html'
'basic_css'
'basic_web_scripting'
'intermediate_html'
'intermediate_css'
'intermediate_web_scripting'
'advanced_html'
'advanced_css'
'advanced_web_scripting'
'jquery'
'bootstrap'
]

View file

@ -17,3 +17,6 @@
canvas#webgl-surface, canvas#normal-surface
display: block
z-index: 2
#play-btn
text-transform: uppercase

View file

@ -4,50 +4,3 @@
iframe
width: 100%
height: 100%
//
// body
// background-color: initial
// color: initial
//
// html, body, div, span, applet, object, iframe,
// h1, h2, h3, h4, h5, h6, p, blockquote, pre,
// a, abbr, acronym, address, big, cite, code,
// del, dfn, em, img, ins, kbd, q, s, samp,
// small, strike, strong, sub, sup, tt, var,
// b, u, i, center,
// dl, dt, dd, ol, ul, li,
// fieldset, form, label, legend,
// table, caption, tbody, tfoot, thead, tr, th, td,
// article, aside, canvas, details, embed,
// figure, figcaption, footer, header, hgroup,
// menu, nav, output, ruby, section, summary,
// time, mark, audio, video
// margin: initial
// padding: initial
// border: initial
// font-size: innitial
// font: initial
// vertical-align: baseline
//
// // HTML5 display-role reset for older browsers
// article, aside, details, figcaption, figure,
// footer, header, hgroup, menu, nav, section
// display: block
//
// body
// line-height: 1
//
// ol, ul
// list-style: none
//
// blockquote, q
// quotes: none
//
// blockquote:before, blockquote:after, q:before, q:after
// content: ''
// content: none
//
// table
// border-collapse: collapse
// border-spacing: 0
//

View file

@ -104,8 +104,8 @@ block content
tr
td
if previousLevelCompleted || view.teacherMode || !passedLastCompletedLevel || levelStatus
- var i18n = level.isType('course-ladder') ? 'play.compete' : 'home.play';
button.btn.btn-success.btn-play-level(data-level-slug=level.get('slug'), data-i18n=i18n, data-level-id=level.get('original'))
- var i18nTag = level.isType('course-ladder') ? 'play.compete' : 'home.play';
button.btn.btn-success.btn-play-level(data-level-slug=level.get('slug'), data-i18n=i18nTag, data-level-id=level.get('original'))
if level.get('shareable')
- var levelOriginal = level.get('original');
- var session = view.levelSessions.find(function(session) { return session.get('level').original === levelOriginal });
@ -113,14 +113,14 @@ block content
- var url = '/play/' + level.get('type') + '-level/' + level.get('slug') + '/' + session.id + '?course=' + view.courseID;
a.btn.btn-warning.btn-view-project-level(href=url)
if level.isType('game-dev')
span(data-i18n='') Game
span(data-i18n='sharing.game')
else
span(data-i18n='') Webpage
span(data-i18n='sharing.webpage')
td
if view.userLevelStateMap[me.id]
div= view.userLevelStateMap[me.id][level.get('original')]
td #{level.get('practice') ? 'practice' : 'required'}
td #{levelNumber}. #{level.get('name').replace('Course: ', '')}
td #{levelNumber}. #{i18n(level.attributes, 'name').replace('Course: ', '')}
td
if view.levelConceptMap[level.get('original')]
each concept in view.course.get('concepts')

View file

@ -125,7 +125,7 @@ block content
.tab-spacer
li(class=(activeTab === "#student-projects-tab" ? 'active' : ''))
a.course-progress-tab-btn(href='#student-projects-tab')
.small-details.text-center(data-i18n='') Projects
.small-details.text-center(data-i18n='teacher.projects')
.tab-filler
.tab-content
@ -156,11 +156,10 @@ mixin breadcrumbs
mixin longLevelName(data)
if data
div.level-name
span.spr Course
span= data.courseNumber
span.spr , Level
span= data.levelNumber
span.spr :
span(data-i18n="courses.course")
span= ' ' + data.courseNumber + ', '
span(data-i18n="play_level.level")
span= ' ' + data.levelNumber + ': '
span= data.levelName
else
div.level-name(data-i18n='teacher.not_applicable')
@ -345,7 +344,7 @@ mixin studentCourseProgressDot(progress, levelsTotal, level, label)
mixin allStudentsLevelProgressDot(progress, level, levelNumber)
- dotClass = progress.completed ? 'forest' : (progress.started ? 'gold' : '');
- levelName = level.get('name')
- levelName = i18n(level.attributes, 'name')
- context = _.merge(progress, { levelName: levelName, levelNumber: levelNumber, numStudents: view.students.length })
.progress-dot.level-progress-dot(class=dotClass, data-html='true', data-title=view.allStudentsLevelProgressDotTemplate(context))
+progressDotLabel(levelNumber)
@ -353,7 +352,7 @@ mixin allStudentsLevelProgressDot(progress, level, levelNumber)
mixin studentLevelProgressDot(progress, level, levelNumber)
//- TODO: Refactor with TeacherClassesView jade
- dotClass = progress.completed ? 'forest' : (progress.started ? 'gold' : '');
- levelName = level.get('name')
- levelName = i18n(level.attributes, 'name')
- context = _.merge(progress, { levelName: levelName, levelNumber: levelNumber, moment: moment })
.progress-dot.level-progress-dot(class=dotClass, data-html='true', data-title=view.singleStudentLevelProgressDotTemplate(context))
+progressDotLabel(levelNumber)
@ -465,7 +464,7 @@ mixin studentProjectsRow(student)
mixin studentProjectLink(progress, level, levelNumber, course)
- var colorClass = progress.completed ? 'btn-primary' : (progress.started ? 'btn-warning' : 'btn-primary');
- var levelName = level.get('name')
- var levelName = i18n(level.attributes, 'name')
- var context = _.merge(progress, { levelName: levelName, levelNumber: levelNumber, moment: moment })
- var title = view.singleStudentLevelProgressDotTemplate(context);
if context.session

View file

@ -111,19 +111,20 @@ block modal-footer-content
if view.shareURL
#share-level-container
span.share-level-label
span(data-i18n='') Share this link to invite your friends & family to
span(data-i18n='sharing.victory_share_prefix') Share this link to invite your friends & family to
span= ' '
a(href=view.shareURL, target='_blank')
if view.level.isType('game-dev')
span(data-i18n='') play your game level
span(data-i18n='sharing.victory_share_game') play your game level
else
span(data-i18n='') view your webpage
span(data-i18n='sharing.victory_share_web') view your webpage
span(data-i18n='sharing.victory_share_suffix') .
.row
.col-sm-9
input.text-h4.semibold.form-control.input-md#share-level-input(value=view.shareURL)
.col-sm-3
button#share-level-btn.btn.btn-md.btn-success.btn-illustrated
span(data-i18n='') Copy URL
span(data-i18n='sharing.copy_url') Copy URL
if me.get('anonymous')
.sign-up-poke.hide

View file

@ -1,8 +1,8 @@
extends /templates/core/modal-base-flat
block modal-header-content
h3(data-i18n='') Image Gallery
| Copy these images into your webpage, or find your own image URLs online.
h3(data-i18n="web_dev.image_gallery_title")
span(data-i18n="web_dev.image_gallery_description")
block modal-body-content
dl.dl-horizontal

View file

@ -44,25 +44,25 @@
.well.well-sm.well-parchment
h3.text-uppercase
if view.level.isType('game-dev')
span(data-i18n='') Share This Game
span(data-i18n='sharing.share_game')
else
span(data-i18n='') Share This Webpage
span(data-i18n='sharing.share_web')
p
span(data-i18n='') This link will let your friends & family
span(data-i18n='sharing.victory_course_share_prefix')
span= ' '
a(href=view.shareURL, target='_blank')
if view.level.isType('game-dev')
span(data-i18n='') play the game
span(data-i18n='sharing.victory_course_share_game')
else
span(data-i18n='') view the webpage
span(data-i18n='sharing.victory_course_share_web')
span= ' '
span(data-i18n='') you just created.
span(data-i18n='sharing.victory_course_share_suffix')
.row
.col-sm-9
input.text-h4.semibold.form-control.input-lg#share-level-input(value=view.shareURL)
.col-sm-3
button#share-level-btn.btn.btn-lg.btn-success.btn-illustrated
span(data-i18n='') Copy URL
span(data-i18n='sharing.copy_url')
.row
.col-sm-5.col-sm-offset-2

View file

@ -10,7 +10,7 @@
.alert.alert-danger= view.state.get('errorMessage')
else if view.state.get('loading')
h1.m-y-1 Loading...
h1.m-y-1(data-i18n="common.loading")
.progress
.progress-bar(style="width: #{view.state.get('progress')}")
@ -18,17 +18,21 @@
h1.m-y-1 Info
ul
li
b Level Name:
| #{view.level.get('name')}
b
span(data-i18n="play_level.level")
span= ': '
| #{view.level.get('name')}
li
b Creator:
| #{view.session.get('creatorName')}
b
span(data-i18n="game_dev.creator")
span= ': '
| #{view.session.get('creatorName')}
- var playing = view.state.get('playing')
.m-y-3
if playing
button#play-btn.btn.btn-lg.btn-burgandy RESTART
button#play-btn.btn.btn-lg.btn-burgandy(data-i18n="play_level.restart")
else
button#play-btn.btn.btn-lg.btn-navy PLAY
button#play-btn.btn.btn-lg.btn-navy(data-i18n="common.play")

View file

@ -6,5 +6,6 @@
else
h1
span Creator:
| #{view.session.get('creatorName')}
span(data-i18n="game_dev.creator")
span= ': '
| #{view.session.get('creatorName')}

View file

@ -4,9 +4,9 @@
.hinge.hinge-3
.spell-tool-buttons
.btn.btn-small.btn-illustrated.btn-warning.reload-code(data-i18n="[title]play_level.tome_reload_method", title="Reload original code for this method")
.btn.btn-small.btn-illustrated.btn-warning.reload-code(data-i18n="[title]play_level.tome_reload_method")
.glyphicon.glyphicon-repeat
span.spl(data-i18n="play_level.reload") Reload
span.spl(data-i18n="play_level.restart")
if me.level() >= 15
.btn.btn-small.btn-illustrated.fullscreen-code(title=maximizeShortcutVerbose)
@ -23,15 +23,15 @@
if view.options.level.isType('web-dev')
.btn.btn-small.btn-illustrated.image-gallery-button
span(data-i18n='') Image Gallery
span(data-i18n='web_dev.image_gallery_title')
if view.options.level.get('shareable')
- var url = '/play/' + view.options.level.get('type') + '-level/' + view.options.level.get('slug') + '/' + view.options.session.id;
- if (view.options.courseID) url += '?course=' + view.options.courseID;
a.btn.btn-small.btn-illustrated(href=url)
if view.options.level.isType('game-dev')
span(data-i18n='') Game
span(data-i18n='sharing.game')
else
span(data-i18n='') Webpage
span(data-i18n='sharing.webpage')
.clearfix

View file

@ -52,7 +52,7 @@ module.exports = class CourseDetailsView extends RootView
@supermodel.trackRequest(@classroom.fetch())
levelsLoaded = @supermodel.trackRequest(@levels.fetchForClassroomAndCourse(classroomID, @courseID, {
data: { project: 'concepts,practice,type,slug,name,original,description,shareable' }
data: { project: 'concepts,practice,type,slug,name,original,description,shareable,i18n' }
}))
@supermodel.trackRequest($.when(levelsLoaded, sessionsLoaded).then(=>

View file

@ -43,7 +43,7 @@ module.exports = class TeacherClassView extends RootView
'click .student-checkbox': 'onClickStudentCheckbox'
'keyup #student-search': 'onKeyPressStudentSearch'
'change .course-select, .bulk-course-select': 'onChangeCourseSelect'
getInitialState: ->
{
sortAttribute: 'name'
@ -72,21 +72,21 @@ module.exports = class TeacherClassView extends RootView
@singleStudentCourseProgressDotTemplate = require 'templates/teachers/hovers/progress-dot-single-student-course'
@singleStudentLevelProgressDotTemplate = require 'templates/teachers/hovers/progress-dot-single-student-level'
@allStudentsLevelProgressDotTemplate = require 'templates/teachers/hovers/progress-dot-all-students-single-level'
@debouncedRender = _.debounce @render
@state = new State(@getInitialState())
@updateHash @state.get('activeTab') # TODO: Don't push to URL history (maybe don't use url fragment for default tab)
@classroom = new Classroom({ _id: classroomID })
@supermodel.trackRequest @classroom.fetch()
@onKeyPressStudentSearch = _.debounce(@onKeyPressStudentSearch, 200)
@students = new Users()
@listenTo @classroom, 'sync', ->
jqxhrs = @students.fetchForClassroom(@classroom, removeDeleted: true)
@supermodel.trackRequests jqxhrs
@classroom.sessions = new LevelSessions()
requests = @classroom.sessions.fetchForAllClassroomMembers(@classroom)
@supermodel.trackRequests(requests)
@ -96,7 +96,7 @@ module.exports = class TeacherClassView extends RootView
value = @state.get('sortValue')
if value is 'name'
return (if student1.broadName().toLowerCase() < student2.broadName().toLowerCase() then -dir else dir)
if value is 'progress'
# TODO: I would like for this to be in the Level model,
# but it doesn't know about its own courseNumber.
@ -105,7 +105,7 @@ module.exports = class TeacherClassView extends RootView
return -dir if not level1
return dir if not level2
return dir * (level1.courseNumber - level2.courseNumber or level1.levelNumber - level2.levelNumber)
if value is 'status'
statusMap = { expired: 0, 'not-enrolled': 1, enrolled: 2 }
diff = statusMap[student1.prepaidStatus()] - statusMap[student2.prepaidStatus()]
@ -119,7 +119,7 @@ module.exports = class TeacherClassView extends RootView
@supermodel.trackRequest @courseInstances.fetchForClassroom(classroomID)
@levels = new Levels()
@supermodel.trackRequest @levels.fetchForClassroom(classroomID, {data: {project: 'original,concepts,practice,shareable'}})
@supermodel.trackRequest @levels.fetchForClassroom(classroomID, {data: {project: 'original,concepts,practice,shareable,i18n'}})
@attachMediatorEvents()
window.tracker?.trackEvent 'Teachers Class Loaded', category: 'Teachers', classroomID: @classroom.id, ['Mixpanel']
@ -160,11 +160,11 @@ module.exports = class TeacherClassView extends RootView
course.instance = @courseInstances.findWhere({ courseID: course.id, classroomID: @classroom.id })
course.members = course.instance?.get('members') or []
null
onLoaded: ->
@removeDeletedStudents() # TODO: Move this to mediator listeners? For both classroom and students?
@calculateProgressAndLevels()
# render callback setup
@listenTo @courseInstances, 'sync change update', @debouncedRender
@listenTo @state, 'sync change', ->
@ -192,14 +192,14 @@ module.exports = class TeacherClassView extends RootView
# TODO: this is a weird hack
studentsStub = new Users([ student ])
student.latestCompleteLevel = helper.calculateLatestComplete(@classroom, @courses, @courseInstances, studentsStub)
earliestIncompleteLevel = helper.calculateEarliestIncomplete(@classroom, @courses, @courseInstances, @students)
latestCompleteLevel = helper.calculateLatestComplete(@classroom, @courses, @courseInstances, @students)
classroomsStub = new Classrooms([ @classroom ])
progressData = helper.calculateAllProgress(classroomsStub, @courses, @courseInstances, @students)
# conceptData: helper.calculateConceptsCovered(classroomsStub, @courses, @campaigns, @courseInstances, @students)
@state.set {
earliestIncompleteLevel
latestCompleteLevel
@ -212,7 +212,7 @@ module.exports = class TeacherClassView extends RootView
hash = $(e.target).closest('a').attr('href')
@updateHash(hash)
@state.set activeTab: hash
updateHash: (hash) ->
return if application.testing
window.location.hash = hash
@ -230,7 +230,7 @@ module.exports = class TeacherClassView extends RootView
onClickUnarchive: ->
window.tracker?.trackEvent 'Teachers Class Unarchive', category: 'Teachers', classroomID: @classroom.id, ['Mixpanel']
@classroom.save { archived: false }
onClickEditClassroom: (e) ->
window.tracker?.trackEvent 'Teachers Class Edit Class Started', category: 'Teachers', classroomID: @classroom.id, ['Mixpanel']
classroom = @classroom
@ -455,7 +455,7 @@ module.exports = class TeacherClassView extends RootView
enrolledUsers = @students.filter (user) -> user.isEnrolled()
stats.enrolledUsers = _.size(enrolledUsers)
return stats
studentStatusString: (student) ->

View file

@ -8,9 +8,6 @@ module.exports = class PlayWebDevLevelView extends RootView
id: 'play-web-dev-level-view'
template: require 'templates/play/level/play-web-dev-level-view'
# events:
# 'click #play-btn': 'onClickPlayButton'
initialize: (@options, @levelID, @sessionID) ->
@courseID = @getQueryVariable 'course'
@level = @supermodel.loadModel(new Level _id: @levelID).model
@ -21,7 +18,7 @@ module.exports = class PlayWebDevLevelView extends RootView
@insertSubView @webSurface = new WebSurfaceView {level: @level}
Backbone.Mediator.publish 'tome:html-updated', html: @getHTML() ? '<h1>Player has no HTML</h1>', create: true
@$el.find('#info-bar').delay(4000).fadeOut(2000)
$('body').css('overflow', 'hidden')
$('body').css('overflow', 'hidden') # Don't show tiny scroll bar from our minimal additions to the iframe
showError: (jqxhr) ->
$('h1').text jqxhr.statusText
@ -34,5 +31,5 @@ module.exports = class PlayWebDevLevelView extends RootView
destroy: ->
@webSurface?.destroy()
$('body').css('overflow', 'initial')
$('body').css('overflow', 'initial') # Recover from our modifications to body overflow before we leave
super()

View file

@ -1,5 +1,4 @@
CocoView = require 'views/core/CocoView'
State = require 'models/State'
template = require 'templates/play/level/web-surface-view'
module.exports = class WebSurfaceView extends CocoView
@ -10,8 +9,6 @@ module.exports = class WebSurfaceView extends CocoView
'tome:html-updated': 'onHTMLUpdated'
initialize: (options) ->
@state = new State
blah: 'blah'
@goals = (goal for goal in options.goalManager?.goals ? [] when goal.html)
# Consider https://www.npmjs.com/package/css-select to do this on virtualDOM instead of in iframe on concreteDOM
super(options)
@ -21,7 +18,6 @@ module.exports = class WebSurfaceView extends CocoView
@iframe = @$('iframe')[0]
$(@iframe).on 'load', (e) =>
window.addEventListener 'message', @onIframeMessage
#@iframe.contentWindow.postMessage {type: 'log', text: 'Player HTML iframe is ready.'}, "*"
@iframeLoaded = true
@onIframeLoaded?()
@onIframeLoaded = null

View file

@ -157,7 +157,6 @@ module.exports = class HeroVictoryModal extends ModalView
getRenderData: ->
c = super()
c.levelName = utils.i18n @level.attributes, 'name'
# TODO: support 'game-dev', 'web-dev'
if @level.isType('hero', 'game-dev', 'web-dev')
c.victoryText = utils.i18n @level.get('victory') ? {}, 'body'
earnedAchievementMap = _.indexBy(@newEarnedAchievements or [], (ea) -> ea.get('achievement'))
@ -226,7 +225,7 @@ module.exports = class HeroVictoryModal extends ModalView
afterRender: ->
super()
@$el.toggleClass 'with-achievements', @level.isType('hero', 'hero-ladder', 'game-dev', 'web-dev') # TODO: support game-dev, web-dev
@$el.toggleClass 'with-achievements', @level.isType('hero', 'hero-ladder', 'game-dev', 'web-dev')
return unless @supermodel.finished()
@playSelectionSound hero, true for original, hero of @thangTypes # Preload them
@updateSavingProgressStatus()
@ -236,7 +235,7 @@ module.exports = class HeroVictoryModal extends ModalView
@insertSubView @ladderSubmissionView, @$el.find('.ladder-submission-view')
initializeAnimations: ->
return @endSequentialAnimations() unless @level.isType('hero', 'hero-ladder', 'game-dev', 'web-dev') # TODO: support game-dev, web-dev
return @endSequentialAnimations() unless @level.isType('hero', 'hero-ladder', 'game-dev', 'web-dev')
@updateXPBars 0
#playVictorySound = => @playSound 'victory-title-appear' # TODO: actually add this
@$el.find('#victory-header').delay(250).queue(->
@ -267,7 +266,7 @@ module.exports = class HeroVictoryModal extends ModalView
beginSequentialAnimations: ->
return if @destroyed
return unless @level.isType('hero', 'hero-ladder', 'game-dev', 'web-dev') # TODO: support game-dev, web-dev
return unless @level.isType('hero', 'hero-ladder', 'game-dev', 'web-dev')
@sequentialAnimatedPanels = _.map(@animatedPanels.find('.reward-panel'), (panel) -> {
number: $(panel).data('number')
previousNumber: $(panel).data('previous-number')
@ -417,7 +416,7 @@ module.exports = class HeroVictoryModal extends ModalView
{'kithgard-gates': 'forest', 'kithgard-mastery': 'forest', 'siege-of-stonehold': 'desert', 'clash-of-clones': 'mountain', 'summits-gate': 'glacier'}[@level.get('slug')] or @level.get 'campaign' # Much easier to just keep this updated than to dynamically figure it out.
getNextLevelLink: (returnToCourse=false) ->
if @level.isType('course', 'game-dev', 'web-dev') and nextLevel = @level.get('nextLevel') and not returnToCourse # TODO: support game-dev and web-dev
if @level.isType('course', 'game-dev', 'web-dev') and nextLevel = @level.get('nextLevel') and not returnToCourse
# need to do something more complicated to load its slug
console.log 'have @nextLevel', @nextLevel, 'from nextLevel', nextLevel
link = "/play/level/#{@nextLevel.get('slug')}"

View file

@ -42,7 +42,7 @@ module.exports = class DocFormatter
@fillOutDoc()
fillOutDoc: ->
# TODO: figure out how to do html docs for web-dev levels
# TODO: figure out better ways to format html/css/scripting docs for web-dev levels
if _.isString @doc
@doc = name: @doc, type: typeof @options.thang[@doc]
if @options.isSnippet

View file

@ -72,11 +72,12 @@ module.exports = class Spell
@originalSource = @addPicoCTFProblem() if window.serverConfig.picoCTF
if @level.isType('web-dev')
# Pull apart the structural wrapper code and the player code, remember the wrapper code, and strip indentation on player code.
playerCode = @originalSource.match(/<playercode>\n([\s\S]*)\n *<\/playercode>/)[1]
playerCodeLines = playerCode.split('\n')
indentation = playerCodeLines[0].length - playerCodeLines[0].trim().length
playerCode = (line.substr(indentation) for line in playerCodeLines).join('\n')
@wrapperCode = @originalSource.replace /<playercode>[\s\S]*<\/playercode>/, ''
@wrapperCode = @originalSource.replace /<playercode>[\s\S]*<\/playercode>/, '' # serves as placeholder for constructHTML
@originalSource = playerCode
# Translate comments chosen spoken language.

View file

@ -210,7 +210,6 @@ module.exports = class TomeView extends CocoView
@setSpellView @spells['hero-placeholder/plan'], @fakeProgrammableThang
return
# This is fired by PlayLevelView
# TODO: Don't hard code these hero names
if @options.session.get('team') is 'ogres'
Backbone.Mediator.publish 'level:select-sprite', thangID: 'Hero Placeholder 1'
else

View file

@ -19,7 +19,7 @@ module.exports = class LevelGuideView extends CocoView
@levelSlug = options.level.get('slug')
@sessionID = options.session.get('_id')
@requiresSubscription = not me.isPremium()
@isCourseLevel = options.level.isType('course', 'course-ladder') # TODO: figure this out for game-dev, web-dev levels
@isCourseLevel = options.level.isType('course', 'course-ladder')
@helpVideos = if @isCourseLevel then [] else options.level.get('helpVideos') ? []
@trackedHelpVideoStart = @trackedHelpVideoFinish = false
# A/B Testing video tutorial styles