diff --git a/app/core/utils.coffee b/app/core/utils.coffee index 175bd2537..b53adeeb9 100644 --- a/app/core/utils.coffee +++ b/app/core/utils.coffee @@ -18,6 +18,17 @@ module.exports.combineAncestralObject = (obj, propertyName) -> obj = Object.getPrototypeOf(obj) combined +module.exports.courseIDs = courseIDs = + INTRODUCTION_TO_COMPUTER_SCIENCE: '560f1a9f22961295f9427742' + COMPUTER_SCIENCE_2: '5632661322961295f9428638' + GAME_DEVELOPMENT_1: '5789587aad86a6efb573701e' + WEB_DEVELOPMENT_1: '5789587aad86a6efb573701f' + COMPUTER_SCIENCE_3: '56462f935afde0c6fd30fc8c' + GAME_DEVELOPMENT_2: '57b621e7ad86a6efb5737e64' + WEB_DEVELOPMENT_2: '5789587aad86a6efb5737020' + COMPUTER_SCIENCE_4: '56462f935afde0c6fd30fc8d' + COMPUTER_SCIENCE_5: '569ed916efa72b0ced971447' + module.exports.normalizeFunc = (func_thing, object) -> # func could be a string to a function in this class # or a function in its own right @@ -382,6 +393,24 @@ module.exports.findNextLevel = (levels, currentIndex, needsPractice) -> module.exports.needsPractice = (playtime=0, threshold=2) -> playtime / 60 > threshold +module.exports.sortCourses = (courses) -> + orderedIDs = [ + courseIDs.INTRODUCTION_TO_COMPUTER_SCIENCE + courseIDs.COMPUTER_SCIENCE_2 + courseIDs.GAME_DEVELOPMENT_1 + courseIDs.WEB_DEVELOPMENT_1 + courseIDs.COMPUTER_SCIENCE_3 + courseIDs.GAME_DEVELOPMENT_2 + courseIDs.WEB_DEVELOPMENT_2 + courseIDs.COMPUTER_SCIENCE_4 + courseIDs.COMPUTER_SCIENCE_5 + ] + _.sortBy courses, (course) -> + # ._id can be from classroom.courses, otherwise it's probably .id + index = orderedIDs.indexOf(course.id ? course._id) + index = 9001 if index is -1 + index + module.exports.usStateCodes = # https://github.com/mdzhang/us-state-codes # generated by js2coffee 2.2.0 @@ -481,3 +510,4 @@ module.exports.usStateCodes = getStateCodeByStateName: getStateCodeByStateName } )() + diff --git a/app/lib/surface/LayerAdapter.coffee b/app/lib/surface/LayerAdapter.coffee index 52569ac7f..a7b379754 100644 --- a/app/lib/surface/LayerAdapter.coffee +++ b/app/lib/surface/LayerAdapter.coffee @@ -358,6 +358,9 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass prerenderedSpriteSheet = thangType.getPrerenderedSpriteSheet(colorConfig, 'segmented') if prerenderedSpriteSheet and not prerenderedSpriteSheet.loadedImage return + else if prerenderedSpriteSheet + animations = prerenderedSpriteSheet.spriteSheet._animations + renderedActions = _.zipObject(animations, _.times(animations.length, -> true)) containersToRender = thangType.getContainersForActions(actionNames) #console.log 'render segmented', thangType.get('name'), actionNames, colorConfig, 'because we do not have prerendered sprite sheet?', prerenderedSpriteSheet spriteBuilder = new SpriteBuilder(thangType, {colorConfig: colorConfig}) @@ -367,7 +370,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass container = new createjs.Sprite(@spriteSheet) container.gotoAndStop(containerKey) frame = spriteSheetBuilder.addFrame(container) - else if prerenderedSpriteSheet + else if prerenderedSpriteSheet and renderedActions[containerGlobalName] container = new createjs.Sprite(prerenderedSpriteSheet.spriteSheet) container.gotoAndStop(containerGlobalName) scale = @resolutionFactor / (prerenderedSpriteSheet.get('resolutionFactor') or 1) diff --git a/app/locale/en.coffee b/app/locale/en.coffee index f05c6568e..f8abf1e2d 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -652,7 +652,6 @@ feature2: "__heroesCount__ powerful new heroes with unique skills!" feature3: "__bonusLevelsCount__+ bonus levels" feature4: "{{gems}} bonus gems every month!" - feature5: "Video tutorials" feature6: "Premium email support" feature7: "Private Clans" feature8: "No ads!" diff --git a/app/models/Classroom.coffee b/app/models/Classroom.coffee index 3016f45c3..78c84183a 100644 --- a/app/models/Classroom.coffee +++ b/app/models/Classroom.coffee @@ -186,6 +186,9 @@ module.exports = class Classroom extends CocoModel options.type = 'POST' @fetch(options) + getSortedCourses: -> + utils.sortCourses(@get('courses') ? []) + updateCourses: (options={}) -> options.url = @url() + '/update-courses' options.type = 'POST' diff --git a/app/schemas/models/campaign.schema.coffee b/app/schemas/models/campaign.schema.coffee index feada8d08..22a4b8343 100644 --- a/app/schemas/models/campaign.schema.coffee +++ b/app/schemas/models/campaign.schema.coffee @@ -42,7 +42,14 @@ _.extend CampaignSchema.properties, { position: c.point2d() rotation: { type: 'number', format: 'degrees' } color: { type: 'string' } - showIfUnlocked: { type: 'string', links: [{rel: 'db', href: '/db/level/{($)}/version'}], format: 'latest-version-original-reference' } + showIfUnlocked: + oneOf: [ + { type: 'string', links: [{rel: 'db', href: '/db/level/{($)}/version'}], format: 'latest-version-original-reference' } + { + type: 'array', + items: { type: 'string', links: [{rel: 'db', href: '/db/level/{($)}/version'}], format: 'latest-version-original-reference' } + } + ] } }} levelsUpdated: c.date() diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee index f51853c76..cff846e0c 100644 --- a/app/schemas/subscriptions/tome.coffee +++ b/app/schemas/subscriptions/tome.coffee @@ -103,12 +103,12 @@ module.exports = 'tome:change-config': c.object {title: 'Change Config', description: 'Published when you change your tome settings'} - 'tome:update-snippets': c.object {title: 'Update Snippets', description: 'Published when we need to add Zatanna snippets', required: ['propGroups', 'allDocs']}, + 'tome:update-snippets': c.object {title: 'Update Snippets', description: 'Published when we need to add autocomplete snippets', required: ['propGroups', 'allDocs']}, propGroups: {type: 'object'} allDocs: {type: 'object'} language: {type: 'string'} - 'tome:insert-snippet': c.object {title: 'Insert Snippet', description: 'Published when we need to insert a Zatanna snippet', required: ['doc', 'language', 'formatted']}, + 'tome:insert-snippet': c.object {title: 'Insert Snippet', description: 'Published when we need to insert a autocomplete snippet', required: ['doc', 'language', 'formatted']}, doc: {type: 'object'} language: {type: 'string'} formatted: {type: 'object'} diff --git a/app/styles/play/play-level-view.sass b/app/styles/play/play-level-view.sass index ba0ff6a37..0ea675490 100644 --- a/app/styles/play/play-level-view.sass +++ b/app/styles/play/play-level-view.sass @@ -289,8 +289,11 @@ $level-resize-transition-time: 0.5s .game-container, .level-content, #game-area, #canvas-wrapper height: 100% + #canvas-wrapper + height: calc(100% - 50px) + #canvas-wrapper canvas - display: none + display: none #web-surface-view position: absolute diff --git a/app/templates/core/subscribe-modal.jade b/app/templates/core/subscribe-modal.jade index a14674e4d..753d4f8f8 100644 --- a/app/templates/core/subscribe-modal.jade +++ b/app/templates/core/subscribe-modal.jade @@ -59,13 +59,6 @@ td.free-cell td.center-ok span.glyphicon.glyphicon-ok - tr - td.feature-description - span(data-i18n="subscribe.feature5") - if !me.isOnPremiumServer() - td.free-cell - td.center-ok - span.glyphicon.glyphicon-ok tr td.feature-description span(data-i18n="[html]subscribe.feature7") diff --git a/app/templates/courses/teacher-class-view.jade b/app/templates/courses/teacher-class-view.jade index 3bf78c3be..791cde44e 100644 --- a/app/templates/courses/teacher-class-view.jade +++ b/app/templates/courses/teacher-class-view.jade @@ -220,9 +220,9 @@ mixin studentRow(student) +longLevelName(student.latestCompleteLevel) td if state.get('progressData') - - var courses = view.classroom.get('courses').map(function(c) { return view.courses.get(c._id); }); + - var courses = view.sortedCourses.map(function(c) { return view.courses.get(c._id); }); - var courseLabelsArray = view.helper.courseLabelsArray(courses); - each trimCourse, index in view.classroom.get('courses') + each trimCourse, index in view.sortedCourses - var course = view.courses.get(trimCourse._id); - var instance = view.courseInstances.findWhere({ courseID: course.id, classroomID: classroom.id }) if instance && instance.hasMember(student) @@ -255,7 +255,7 @@ mixin courseProgressTab span(data-i18n='teacher.select_course') span.spr : select.course-select - each trimCourse in view.classroom.get('courses') + each trimCourse in view.sortedCourses - var course = view.courses.get(trimCourse._id); option(value=course.id selected=(course===state.get('selectedCourse'))) = i18n(course.attributes, 'name') @@ -423,7 +423,7 @@ mixin bulkAssignControls span(data-i18n='teacher.bulk_assign') span : select.bulk-course-select.form-control - each trimCourse in _.rest(view.classroom.get('courses')) + each trimCourse in _.rest(view.sortedCourses) - var course = view.courses.get(trimCourse._id) option(value=course.id selected=(course===state.get('selectedCourse'))) = i18n(course.attributes, 'name') diff --git a/app/templates/courses/teacher-classes-view.jade b/app/templates/courses/teacher-classes-view.jade index 2ffe473b4..830f48861 100644 --- a/app/templates/courses/teacher-classes-view.jade +++ b/app/templates/courses/teacher-classes-view.jade @@ -77,7 +77,7 @@ mixin classRow(classroom) if classroom.get('members').length == 0 +addStudentsButton(classroom) else - - var courses = classroom.get('courses').map(function(c) { return view.courses.get(c._id); }); + - var courses = classroom.getSortedCourses().map(function(c) { return view.courses.get(c._id); }); - var courseLabelsArray = view.helper.courseLabelsArray(courses); each trimCourse, index in classroom.get('courses') || [] - var course = view.courses.get(trimCourse._id); diff --git a/app/views/courses/TeacherClassView.coffee b/app/views/courses/TeacherClassView.coffee index 8dec7245a..8f8fd1aae 100644 --- a/app/views/courses/TeacherClassView.coffee +++ b/app/views/courses/TeacherClassView.coffee @@ -83,6 +83,7 @@ module.exports = class TeacherClassView extends RootView @classroom = new Classroom({ _id: classroomID }) @supermodel.trackRequest @classroom.fetch() @onKeyPressStudentSearch = _.debounce(@onKeyPressStudentSearch, 200) + @sortedCourses = [] @students = new Users() @listenTo @classroom, 'sync', -> @@ -164,6 +165,7 @@ module.exports = class TeacherClassView extends RootView null onLoaded: -> + @sortedCourses = @classroom.getSortedCourses() @removeDeletedStudents() # TODO: Move this to mediator listeners? For both classroom and students? @calculateProgressAndLevels() diff --git a/app/views/play/level/LevelLoadingView.coffee b/app/views/play/level/LevelLoadingView.coffee index ed97cfb39..7218d319b 100644 --- a/app/views/play/level/LevelLoadingView.coffee +++ b/app/views/play/level/LevelLoadingView.coffee @@ -184,7 +184,8 @@ module.exports = class LevelLoadingView extends CocoView #{problem.category} - #{problem.score} points """, sanitize: false else - html = marked utils.filterMarkdownCodeLanguages(utils.i18n(@intro, 'body')) + language = @session?.get('codeLanguage') + html = marked utils.filterMarkdownCodeLanguages(utils.i18n(@intro, 'body'), language) @$el.find('.intro-doc').removeClass('hidden').find('.intro-doc-content').html html @resize() diff --git a/app/views/play/level/tome/SpellPaletteEntryView.coffee b/app/views/play/level/tome/SpellPaletteEntryView.coffee index 07bd109a7..6fdf09cbf 100644 --- a/app/views/play/level/tome/SpellPaletteEntryView.coffee +++ b/app/views/play/level/tome/SpellPaletteEntryView.coffee @@ -47,22 +47,30 @@ module.exports = class SpellPaletteEntryView extends CocoView Backbone.Mediator.publish 'tome:palette-hovered', thang: @thang, prop: @doc.name, entry: @ soundIndex = Math.floor(Math.random() * 4) @playSound "spell-palette-entry-open-#{soundIndex}", 0.75 - popover = @$el.data('bs.popover') - popover?.$tip?.i18n() - codeLanguage = @options.language - oldEditor.destroy() for oldEditor in @aceEditors - @aceEditors = [] - aceEditors = @aceEditors - # Initialize Ace for each popover code snippet - popover?.$tip?.find('.docs-ace').each -> - aceEditor = utils.initializeACE @, codeLanguage - aceEditors.push aceEditor + @afterRenderPopover() - onMouseEnter: (e) -> - # Make sure the doc has the updated Thang so it can regenerate its prop value + # NOTE: This can't be run twice without resetting the popover content HTML + # in between. If you do, Ace will break. + afterRenderPopover: -> + popover = @$el.data('bs.popover') + popover?.$tip?.i18n() + codeLanguage = @options.language + oldEditor.destroy() for oldEditor in @aceEditors + @aceEditors = [] + aceEditors = @aceEditors + # Initialize Ace for each popover code snippet that still needs it + popover?.$tip?.find('.docs-ace').each -> + aceEditor = utils.initializeACE @, codeLanguage + aceEditors.push aceEditor + + resetPopoverContent: -> @$el.data('bs.popover').options.content = @docFormatter.formatPopover() @$el.popover('setContent') - @$el.popover 'show' unless @popoverPinned or @otherPopoverPinned + + onMouseEnter: (e) -> + return if @popoverPinned or @otherPopoverPinned + @resetPopoverContent() + @$el.popover 'show' onMouseLeave: (e) -> @$el.popover 'hide' unless @popoverPinned or @otherPopoverPinned @@ -76,8 +84,9 @@ module.exports = class SpellPaletteEntryView extends CocoView @playSound 'spell-palette-entry-unpin' else @popoverPinned = true - @$el.popover 'show' + @resetPopoverContent() @$el.add('.spell-palette-popover.popover').addClass 'pinned' + @$el.popover 'show' x = $('') $('.spell-palette-popover.popover').append x x.on 'click', @onClick diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee index f3a759558..fe8d07c0a 100644 --- a/app/views/play/level/tome/SpellView.coffee +++ b/app/views/play/level/tome/SpellView.coffee @@ -12,7 +12,7 @@ LevelComponent = require 'models/LevelComponent' UserCodeProblem = require 'models/UserCodeProblem' utils = require 'core/utils' CodeLog = require 'models/CodeLog' -Zatanna = require './editor/zatanna' +Autocomplete = require './editor/autocomplete' module.exports = class SpellView extends CocoView id: 'spell-view' @@ -45,7 +45,7 @@ module.exports = class SpellView extends CocoView 'tome:spell-statement-index-updated': 'onStatementIndexUpdated' 'tome:change-language': 'onChangeLanguage' 'tome:change-config': 'onChangeEditorConfig' - 'tome:update-snippets': 'addZatannaSnippets' + 'tome:update-snippets': 'addAutocompleteSnippets' 'tome:insert-snippet': 'onInsertSnippet' 'tome:spell-beautify': 'onSpellBeautify' 'tome:maximize-toggled': 'onMaximizeToggled' @@ -459,7 +459,7 @@ module.exports = class SpellView extends CocoView if (e.command.name is 'insertstring' and intersects()) or (e.command.name in ['Backspace', 'throttle-backspaces'] and intersectsLeft()) or (e.command.name is 'del' and intersectsRight()) - @zatanna?.off?() + @autocomplete?.off?() pulseLockedCode() return false else if e.command.name in ['enter-skip-delimiters', 'Enter', 'Return'] @@ -468,41 +468,41 @@ module.exports = class SpellView extends CocoView e.editor.navigateLineStart() return false else if e.command.name in ['Enter', 'Return'] and not e.editor?.completer?.popup?.isOpen - @zatanna?.on?() + @autocomplete?.on?() return e.editor.execCommand 'enter-skip-delimiters' - @zatanna?.on?() + @autocomplete?.on?() e.command.exec e.editor, e.args or {} - initAutocomplete: (@autocomplete) -> + initAutocomplete: (@autocompleteOn) -> # TODO: Turn on more autocompletion based on level sophistication # TODO: E.g. using the language default snippets yields a bunch of crazy non-beginner suggestions # TODO: Options logic shouldn't exist both here and in updateAutocomplete() return if @spell.language is 'html' popupFontSizePx = @options.level.get('autocompleteFontSizePx') ? 16 - @zatanna = new Zatanna @ace, + @autocomplete = new Autocomplete @ace, basic: false liveCompletion: false snippetsLangDefaults: false completers: keywords: false - snippets: @autocomplete + snippets: @autocompleteOn autoLineEndings: javascript: ';' popupFontSizePx: popupFontSizePx popupLineHeightPx: 1.5 * popupFontSizePx popupWidthPx: 380 - updateAutocomplete: (@autocomplete) -> - @zatanna?.set 'snippets', @autocomplete + updateAutocomplete: (@autocompleteOn) -> + @autocomplete?.set 'snippets', @autocompleteOn - addZatannaSnippets: (e) -> + addAutocompleteSnippets: (e) -> # Snippet entry format: # content: code inserted into document # meta: displayed right-justfied in popup # name: displayed left-justified in popup, and what's being matched # tabTrigger: fallback for name field - return unless @zatanna and @autocomplete - @zatanna.addCodeCombatSnippets @options.level, @, e + return unless @autocomplete and @autocompleteOn + @autocomplete.addCodeCombatSnippets @options.level, @, e translateFindNearest: -> # If they have advanced glasses but are playing a level which assumes earlier glasses, we'll adjust the sample code to use the more advanced APIs instead. @@ -582,7 +582,7 @@ module.exports = class SpellView extends CocoView @createTranslationView() unless @translationView @toolbarView?.toggleFlow false @updateAether false, false - # @addZatannaSnippets() + # @addAutocompleteSnippets() @highlightCurrentLine() cast: (preload=false, realTime=false, justBegin=false) -> @@ -1219,7 +1219,7 @@ module.exports = class SpellView extends CocoView onChangeLanguage: (e) -> return unless @spell.canWrite() @aceSession.setMode utils.aceEditModes[e.language] - @zatanna?.set 'language', utils.aceEditModes[e.language].substr('ace/mode/') + @autocomplete?.set 'language', utils.aceEditModes[e.language].substr('ace/mode/') wasDefault = @getSource() is @spell.originalSource @spell.setLanguage e.language @reloadCode true if wasDefault @@ -1287,7 +1287,7 @@ module.exports = class SpellView extends CocoView @debugView?.destroy() @translationView?.destroy() @toolbarView?.destroy() - @zatanna?.addSnippets [], @editorLang if @editorLang? + @autocomplete?.addSnippets [], @editorLang if @editorLang? $(window).off 'resize', @onWindowResize window.clearTimeout @saveSpadeTimeout @saveSpadeTimeout = null diff --git a/app/views/play/level/tome/editor/zatanna.coffee b/app/views/play/level/tome/editor/autocomplete.coffee similarity index 97% rename from app/views/play/level/tome/editor/zatanna.coffee rename to app/views/play/level/tome/editor/autocomplete.coffee index 8a672351e..562ffaec0 100644 --- a/app/views/play/level/tome/editor/zatanna.coffee +++ b/app/views/play/level/tome/editor/autocomplete.coffee @@ -23,7 +23,7 @@ defaults = # TODO: Create list of manual test cases -module.exports = class Zatanna +module.exports = class Autocomplete Tokenizer = '' BackgroundTokenizer = '' @@ -43,7 +43,7 @@ module.exports = class Zatanna #TODO: Renable option validation if we care #validationResult = optionsValidator @options #unless validationResult.valid - # throw new Error "Invalid Zatanna options: " + JSON.stringify(validationResult.errors, null, 4) + # throw new Error "Invalid Autocomplete options: " + JSON.stringify(validationResult.errors, null, 4) ace.config.loadModule 'ace/ext/language_tools', () => @snippetManager = ace.require('ace/snippets').snippetManager @@ -154,7 +154,7 @@ module.exports = class Zatanna off: -> @paused = true doLiveCompletion: (e) => - # console.log 'Zatanna doLiveCompletion', e + # console.log 'Autocomplete doLiveCompletion', e return unless @options.basic or @options.liveCompletion or @options.completers.snippets return if @paused @@ -172,6 +172,9 @@ module.exports = class Zatanna # Bake a fresh autocomplete every keystroke editor.completer?.detach() if hasCompleter + # Skip common single letter variable names + return if /^x$|^y$/i.test(prefix) + # Only autocomplete if there's a prefix that can be matched if (prefix) unless (editor.completer) @@ -330,7 +333,7 @@ module.exports = class Zatanna if haveFindNearest and not haveFindNearestEnemy spellView.translateFindNearest() - # window.zatannaInstance = @zatanna # For debugging. Make sure to not leave active when committing. + # window.AutocompleteInstance = @Autocomplete # For debugging. Make sure to not leave active when committing. # window.snippetEntries = snippetEntries lang = utils.aceEditModes[e.language].substr 'ace/mode/'.length @addSnippets snippetEntries, lang diff --git a/app/views/play/level/tome/editor/snippets.coffee b/app/views/play/level/tome/editor/snippets.coffee index 6e234def8..e76b79ce3 100644 --- a/app/views/play/level/tome/editor/snippets.coffee +++ b/app/views/play/level/tome/editor/snippets.coffee @@ -37,8 +37,8 @@ module.exports = (SnippetManager, autoLineEndings) -> range = new Range cursor.row, cursor.column - 1 - prevWord.length, cursor.row, cursor.column editor.session.remove range else - # console.log "Zatanna cursor.column=#{cursor.column} snippet='#{snippet}' line='#{line}' prevWord='#{prevWord}'" - # console.log "Zatanna prevWordIndex=#{prevWordIndex}" + # console.log "Snippets cursor.column=#{cursor.column} snippet='#{snippet}' line='#{line}' prevWord='#{prevWord}'" + # console.log "Snippets prevWordIndex=#{prevWordIndex}" # Lookup original completion # TODO: Can we identify correct completer somehow? @@ -51,10 +51,10 @@ module.exports = (SnippetManager, autoLineEndings) -> break if originalCompletion if originalCompletion? - # console.log 'Zatanna original completion', originalCompletion + # console.log 'Snippets original completion', originalCompletion # Get original snippet prefix (accounting for extra '\n' and possibly autoLineEndings at end) lang = editor.session.getMode()?.$id?.substr 'ace/mode/'.length - # console.log 'Zatanna lang', lang, autoLineEndings[lang]?.length + # console.log 'Snippets lang', lang, autoLineEndings[lang]?.length extraEndLength = 1 extraEndLength += autoLineEndings[lang].length if autoLineEndings[lang]? if snippetIndex = originalCompletion.content.indexOf snippet.substr(0, snippet.length - extraEndLength) @@ -62,21 +62,21 @@ module.exports = (SnippetManager, autoLineEndings) -> else originalPrefix = '' snippetStart = cursor.column - originalPrefix.length - # console.log "Zatanna originalPrefix='#{originalPrefix}' snippetStart=#{snippetStart}" + # console.log "Snippets originalPrefix='#{originalPrefix}' snippetStart=#{snippetStart}" if snippetStart > 0 and snippetStart <= line.length extraIndex = snippetStart - 1 - # console.log "Zatanna prev char='#{line[extraIndex]}'" + # console.log "Snippets prev char='#{line[extraIndex]}'" if line[extraIndex] is '.' # Fuzzy string match previous word before '.', and remove if a match to beginning of snippet originalObject = originalCompletion.content.substring(0, originalCompletion.content.indexOf('.')) prevObjectIndex = extraIndex - 1 - # console.log "Zatanna prevObjectIndex=#{prevObjectIndex}" + # console.log "Snippets prevObjectIndex=#{prevObjectIndex}" if prevObjectIndex >= 0 and /\w/.test(line[prevObjectIndex]) prevObjectIndex-- while prevObjectIndex >= 0 and /\w/.test(line[prevObjectIndex]) prevObjectIndex++ if prevObjectIndex < 0 or not /\w/.test(line[prevObjectIndex]) - # console.log "Zatanna prevObjectIndex=#{prevObjectIndex} extraIndex=#{extraIndex}" + # console.log "Snippets prevObjectIndex=#{prevObjectIndex} extraIndex=#{extraIndex}" prevObject = line.substring prevObjectIndex, extraIndex #TODO: We use to use fuzziac here, but we forgot why. Using @@ -87,7 +87,7 @@ module.exports = (SnippetManager, autoLineEndings) -> if fuzzer finalScore = fuzzer.score prevObject - # console.log "Zatanna originalObject='#{originalObject}' prevObject='#{prevObject}'", finalScore + # console.log "Snippets originalObject='#{originalObject}' prevObject='#{prevObject}'", finalScore if finalScore > 0.5 range = new Range cursor.row, prevObjectIndex, cursor.row, snippetStart editor.session.remove range @@ -113,7 +113,7 @@ module.exports = (SnippetManager, autoLineEndings) -> baseInsertSnippet.call @, editor, snippet getCompletions: (editor, session, pos, prefix, callback) -> - # console.log "Zatanna getCompletions pos.column=#{pos.column} prefix=#{prefix}" + # console.log "Snippets getCompletions pos.column=#{pos.column} prefix=#{prefix}" # Completion format: # prefix: text that will be replaced by snippet # caption: displayed left-justified in popup, and what's being matched @@ -149,7 +149,7 @@ module.exports = (SnippetManager, autoLineEndings) -> continue unless caption [snippet, fuzzScore] = scrubSnippet s.content, caption, line, prefix, pos, lang, autoLineEndings, s.captureReturn completions.push - content: s.content # Used internally by Zatanna, not by ace autocomplete + content: s.content # Used internally by Snippets, not by ace autocomplete caption: caption snippet: snippet score: fuzzScore * s.importance ? 1.0 @@ -162,7 +162,7 @@ module.exports = (SnippetManager, autoLineEndings) -> @completions = _.filter(completions, (x) -> x.caption.indexOf prefix is 0) return callback null, @completions - # console.log 'Zatanna snippet completions', completions + # console.log 'Snippets snippet completions', completions @completions = completions callback null, completions @@ -170,7 +170,7 @@ module.exports = (SnippetManager, autoLineEndings) -> # TODO: https://github.com/ajaxorg/ace/commit/7b01a4273e91985c9177f53d238d6b83fe99dc56 # TODO: But, if it was we could use this and pass a 'completer: @' property for each completion # insertMatch: (editor, data) -> - # console.log 'Zatanna snippets insertMatch', editor, data + # console.log 'Snippets snippets insertMatch', editor, data # if data.snippet # SnippetManager.insertSnippet editor, data.snippet # else @@ -193,7 +193,7 @@ getFullIdentifier = (doc, pos) -> text.substring start, end scrubSnippet = (snippet, caption, line, input, pos, lang, autoLineEndings, captureReturn) -> - # console.log "Zatanna snippet=#{snippet} caption=#{caption} line=#{line} input=#{input} pos.column=#{pos.column} lang=#{lang}" + # console.log "Snippets snippet=#{snippet} caption=#{caption} line=#{line} input=#{input} pos.column=#{pos.column} lang=#{lang}" fuzzScore = 0.1 # input will be replaced by snippet # trim snippet prefix and suffix if already in the document (line) @@ -223,7 +223,7 @@ scrubSnippet = (snippet, caption, line, input, pos, lang, autoLineEndings, captu # TODO: This is broken for attack(find in Python, but seems ok in JavaScript. # Don't eat existing matched parentheses - # console.log "Zatanna checking parentheses lineSuffix=#{lineSuffix} pos.column=#{pos.column} input.length=#{input.length}, prevChar=#{line[pos.column - input.length - 1]} line.length=#{line.length} nextChar=#{line[pos.column]}" + # console.log "Snippets checking parentheses lineSuffix=#{lineSuffix} pos.column=#{pos.column} input.length=#{input.length}, prevChar=#{line[pos.column - input.length - 1]} line.length=#{line.length} nextChar=#{line[pos.column]}" if pos.column - input.length >= 0 and line[pos.column - input.length - 1] is '(' and pos.column < line.length and line[pos.column] is ')' and lineSuffix is ')' lineSuffix = '' @@ -238,9 +238,9 @@ scrubSnippet = (snippet, caption, line, input, pos, lang, autoLineEndings, captu # If at end of line # And, no parentheses are before snippet. E.g. 'if (' # And, line doesn't start with whitespace followed by 'if ' or 'elif ' - # console.log "Zatanna autoLineEndings linePrefixIndex='#{linePrefixIndex}'" + # console.log "Snippets autoLineEndings linePrefixIndex='#{linePrefixIndex}'" if lineSuffix.length is 0 and /^\s*$/.test line.slice pos.column - # console.log 'Zatanna atLineEnd', pos.column, lineSuffix.length, line.slice(pos.column + lineSuffix.length), line + # console.log 'Snippets atLineEnd', pos.column, lineSuffix.length, line.slice(pos.column + lineSuffix.length), line toLinePrefix = line.substring 0, linePrefixIndex if linePrefixIndex < 0 or linePrefixIndex >= 0 and not /[\(\)]/.test(toLinePrefix) and not /^[ \t]*(?:if\b|elif\b)/.test(toLinePrefix) snippet += autoLineEndings[lang] if snippetLines is 0 and autoLineEndings[lang] @@ -249,7 +249,7 @@ scrubSnippet = (snippet, caption, line, input, pos, lang, autoLineEndings, captu if captureReturn and /^\s*$/.test(toLinePrefix) snippet = captureReturn + linePrefix + snippet - # console.log "Zatanna snippetPrefix=#{snippetPrefix} linePrefix=#{linePrefix} snippetSuffix=#{snippetSuffix} lineSuffix=#{lineSuffix} snippet=#{snippet} score=#{fuzzScore}" + # console.log "Snippets snippetPrefix=#{snippetPrefix} linePrefix=#{linePrefix} snippetSuffix=#{snippetSuffix} lineSuffix=#{lineSuffix} snippet=#{snippet} score=#{fuzzScore}" else fuzzScore += score snippet, input diff --git a/scripts/mongodb/updateCourses.js b/scripts/mongodb/updateCourses.js index bc87db27f..2182f3e94 100644 --- a/scripts/mongodb/updateCourses.js +++ b/scripts/mongodb/updateCourses.js @@ -1,15 +1,19 @@ -// Update course data +// Update courses // Usage: // mongo
:/