mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-26 14:03:28 -04:00
Add translation tooltips for code
Tweak tooltips, add some translation keys Fixed not showing translations for English-speakers Remove comment
This commit is contained in:
parent
aa93a3ec6c
commit
66f99dd834
6 changed files with 174 additions and 1 deletions
app
locale
styles/play/level/tome
templates/play/level/tome
views/play/level/tome
|
@ -195,6 +195,50 @@
|
|||
campaign_multiplayer_description: "... in which you code head-to-head against other players."
|
||||
campaign_old_multiplayer: "(Deprecated) Old Multiplayer Arenas"
|
||||
campaign_old_multiplayer_description: "Relics of a more civilized age. No simulations are run for these older, hero-less multiplayer arenas."
|
||||
|
||||
code:
|
||||
if: "if" # Keywords
|
||||
else: "else"
|
||||
elif: "elif"
|
||||
while: "while"
|
||||
loop: "loop"
|
||||
for: "for"
|
||||
break: "break"
|
||||
continue: "continue"
|
||||
then: "then"
|
||||
do: "do"
|
||||
end: "end"
|
||||
function: "function"
|
||||
def: "def"
|
||||
self: "self"
|
||||
hero: "hero"
|
||||
this: "this"
|
||||
Date: "Date" # Globals
|
||||
Vector: "Vector"
|
||||
Array: "Array"
|
||||
Function: "Function"
|
||||
Math: "Math"
|
||||
Number: "Number"
|
||||
Object: "Object"
|
||||
RegExp: "RegExp"
|
||||
String: "String"
|
||||
isFinite: "isFinite" # Built-ins
|
||||
isNaN: "isNaN"
|
||||
parseFloat: "parseFloat"
|
||||
parseInt: "parseInt"
|
||||
decodeURI: "decodeURI"
|
||||
decodeURIComponent: "decodeURIComponent"
|
||||
encodeURI: "encodeURI"
|
||||
encodeURIComponent: "encodeURIComponent"
|
||||
escape: "escape"
|
||||
unescape: "unescape"
|
||||
Infinity: "Infinity"
|
||||
NaN: "NaN"
|
||||
undefined: "undefined"
|
||||
null: "null"
|
||||
Boolean: "Boolean"
|
||||
Error: "Error"
|
||||
arguments: "arguments"
|
||||
|
||||
share_progress_modal:
|
||||
blurb: "You’re making great progress! Tell your parent how much you've learned with CodeCombat."
|
||||
|
|
18
app/styles/play/level/tome/spell_translation.sass
Normal file
18
app/styles/play/level/tome/spell_translation.sass
Normal file
|
@ -0,0 +1,18 @@
|
|||
@import "app/styles/mixins"
|
||||
@import "app/styles/bootstrap/variables"
|
||||
|
||||
.spell-translation-view
|
||||
position: absolute
|
||||
z-index: 9001
|
||||
max-width: 400px
|
||||
pre
|
||||
margin-bottom: 0
|
||||
code
|
||||
white-space: nowrap
|
||||
|
||||
html.no-borderimage
|
||||
.spell-translation-view
|
||||
background: transparent url(/images/level/popover_background.png)
|
||||
background-size: 100% 100%
|
||||
border: 0
|
||||
|
3
app/templates/play/level/tome/spell_translation.jade
Normal file
3
app/templates/play/level/tome/spell_translation.jade
Normal file
|
@ -0,0 +1,3 @@
|
|||
pre
|
||||
|
||||
code
|
|
@ -48,7 +48,7 @@ module.exports = class Spell
|
|||
@source = @originalSource = p.aiSource
|
||||
@thangs = {}
|
||||
if @canRead() # We can avoid creating these views if we'll never use them.
|
||||
@view = new SpellView {spell: @, level: options.level, session: @session, otherSession: @otherSession, worker: @worker, god: options.god}
|
||||
@view = new SpellView {spell: @, level: options.level, session: @session, otherSession: @otherSession, worker: @worker, god: options.god, @supermodel}
|
||||
@view.render() # Get it ready and code loaded in advance
|
||||
@tabView = new SpellListTabEntryView spell: @, supermodel: @supermodel, codeLanguage: @language, level: options.level
|
||||
@tabView.render()
|
||||
|
|
99
app/views/play/level/tome/SpellTranslationView.coffee
Normal file
99
app/views/play/level/tome/SpellTranslationView.coffee
Normal file
|
@ -0,0 +1,99 @@
|
|||
CocoView = require 'views/core/CocoView'
|
||||
LevelComponent = require 'models/LevelComponent'
|
||||
template = require 'templates/play/level/tome/spell_translation'
|
||||
Range = ace.require('ace/range').Range
|
||||
TokenIterator = ace.require('ace/token_iterator').TokenIterator
|
||||
serializedClasses =
|
||||
Thang: require 'lib/world/thang'
|
||||
Vector: require 'lib/world/vector'
|
||||
Rectangle: require 'lib/world/rectangle'
|
||||
Ellipse: require 'lib/world/ellipse'
|
||||
LineSegment: require 'lib/world/line_segment'
|
||||
utils = require 'core/utils'
|
||||
|
||||
module.exports = class SpellTranslationView extends CocoView
|
||||
className: 'spell-translation-view'
|
||||
template: template
|
||||
|
||||
events:
|
||||
'mousemove': ->
|
||||
@$el.hide()
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@ace = options.ace
|
||||
@thang = options.thang
|
||||
@spell = options.spell
|
||||
@supermodel = options.supermodel
|
||||
|
||||
|
||||
levelComponents = @supermodel.getModels LevelComponent
|
||||
@componentTranslations = levelComponents.reduce((acc, lc) ->
|
||||
for doc in (lc.get('propertyDocumentation') ? [])
|
||||
translated = utils.i18n(doc, 'name', null, false)
|
||||
acc[doc.name] = translated if translated isnt doc.name
|
||||
acc
|
||||
, {})
|
||||
|
||||
@onMouseMove = _.throttle @onMouseMove, 25
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
@ace.on 'mousemove', @onMouseMove
|
||||
|
||||
setTooltipText: (text) =>
|
||||
@$el.find('code').text text
|
||||
@$el.show().css(@pos)
|
||||
|
||||
isIdentifier: (t) ->
|
||||
t and (t.type in ['identifier', 'keyword'] or t.value is 'this')
|
||||
|
||||
onMouseMove: (e) =>
|
||||
return if @destroyed
|
||||
pos = e.getDocumentPosition()
|
||||
it = new TokenIterator e.editor.session, pos.row, pos.column
|
||||
endOfLine = it.getCurrentToken()?.index is it.$rowTokens.length - 1
|
||||
while it.getCurrentTokenRow() is pos.row and not @isIdentifier(token = it.getCurrentToken())
|
||||
break if endOfLine or not token # Don't iterate beyond end or beginning of line
|
||||
it.stepBackward()
|
||||
unless @isIdentifier(token)
|
||||
@word = null
|
||||
@update()
|
||||
return
|
||||
try
|
||||
# Ace was breaking under some (?) conditions, dependent on mouse location.
|
||||
# with $rowTokens = [] (but should have things)
|
||||
start = it.getCurrentTokenColumn()
|
||||
catch error
|
||||
start = 0
|
||||
end = start + token.value.length
|
||||
if @isIdentifier(token)
|
||||
@word = token.value
|
||||
@markerRange = new Range pos.row, start, pos.row, end
|
||||
@reposition(e.domEvent)
|
||||
@update()
|
||||
|
||||
reposition: (e) ->
|
||||
offsetX = e.offsetX ? e.clientX - $(e.target).offset().left
|
||||
offsetY = e.offsetY ? e.clientY - $(e.target).offset().top
|
||||
w = $(document).width() - 20
|
||||
offsetX = w - $(e.target).offset().left - @$el.width() if e.clientX + @$el.width() > w
|
||||
@pos = {left: offsetX + 80, top: offsetY - 20}
|
||||
@$el.css(@pos)
|
||||
|
||||
onMouseOut: ->
|
||||
@word = null
|
||||
@markerRange = null
|
||||
@update()
|
||||
|
||||
update: ->
|
||||
i18nKey = 'code.'+@word
|
||||
translation = @componentTranslations[@word] or $.t(i18nKey)
|
||||
if @word and translation and translation not in [i18nKey, @word]
|
||||
@setTooltipText translation
|
||||
else
|
||||
@$el.hide()
|
||||
|
||||
destroy: ->
|
||||
@ace?.removeEventListener 'mousemove', @onMouseMove
|
||||
super()
|
|
@ -6,6 +6,7 @@ Range = ace.require('ace/range').Range
|
|||
UndoManager = ace.require('ace/undomanager').UndoManager
|
||||
Problem = require './Problem'
|
||||
SpellDebugView = require './SpellDebugView'
|
||||
SpellTranslationView = require './SpellTranslationView'
|
||||
SpellToolbarView = require './SpellToolbarView'
|
||||
LevelComponent = require 'models/LevelComponent'
|
||||
UserCodeProblem = require 'models/UserCodeProblem'
|
||||
|
@ -56,6 +57,7 @@ module.exports = class SpellView extends CocoView
|
|||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@supermodel = options.supermodel
|
||||
@worker = options.worker
|
||||
@session = options.session
|
||||
@listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
|
||||
|
@ -638,6 +640,10 @@ module.exports = class SpellView extends CocoView
|
|||
return if @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder'] # We'll turn this on later, maybe, but not yet.
|
||||
@debugView = new SpellDebugView ace: @ace, thang: @thang, spell:@spell
|
||||
@$el.append @debugView.render().$el.hide()
|
||||
|
||||
createTranslationView: ->
|
||||
@translationView = new SpellTranslationView { @ace, @thang, @spell, @supermodel }
|
||||
@$el.append @translationView.render().$el.hide()
|
||||
|
||||
createToolbarView: ->
|
||||
@toolbarView = new SpellToolbarView ace: @ace
|
||||
|
@ -661,6 +667,8 @@ module.exports = class SpellView extends CocoView
|
|||
@spellThang = @spell.thangs[@thang.id]
|
||||
@createDebugView() unless @debugView
|
||||
@debugView?.thang = @thang
|
||||
@createTranslationView() unless @translationView
|
||||
@translationView?.thang = @thang
|
||||
@toolbarView?.toggleFlow false
|
||||
@updateAether false, false
|
||||
# @addZatannaSnippets()
|
||||
|
@ -1336,6 +1344,7 @@ module.exports = class SpellView extends CocoView
|
|||
@aceSession?.selection.off 'changeCursor', @onCursorActivity
|
||||
@destroyAceEditor(@ace)
|
||||
@debugView?.destroy()
|
||||
@translationView?.destroy()
|
||||
@toolbarView?.destroy()
|
||||
@zatanna.addSnippets [], @editorLang if @editorLang?
|
||||
$(window).off 'resize', @onWindowResize
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue