forked from phcode-dev/staging.phcode.dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLanguageManager.js
More file actions
1 lines (1 loc) · 13.8 KB
/
LanguageManager.js
File metadata and controls
1 lines (1 loc) · 13.8 KB
1
define(function(require,exports,module){var CodeMirror=require("thirdparty/CodeMirror/lib/codemirror"),EventDispatcher=require("utils/EventDispatcher"),Async=require("utils/Async"),FileUtils=require("file/FileUtils"),Strings=require("strings"),_defaultLanguagesJSON=require("text!language/languages.json"),_=require("thirdparty/lodash"),PreferencesManager,_fallbackLanguage=null,_pendingLanguages={},_languages={},_baseFileExtensionToLanguageMap={},_fileExtensionToLanguageMap=Object.create(_baseFileExtensionToLanguageMap),_fileNameToLanguageMap={},_filePathToLanguageMap={},_modeToLanguageMap={},_ready,_EXTENSION_MAP_PREF="language.fileExtensions",_NAME_MAP_PREF="language.fileNames",_prefState={};function _validateNonEmptyString(value,description,deferred){var reportError=deferred?deferred.reject:console.error;return"[object String]"!==Object.prototype.toString.call(value)?(reportError(description+" must be a string"),!1):""!==value||(reportError(description+" must not be empty"),!1)}function _patchCodeMirror(){var _original_CodeMirror_defineMode=CodeMirror.defineMode;function _wrapped_CodeMirror_defineMode(name){CodeMirror.modes[name]?console.error('There already is a CodeMirror mode with the name "'+name+'"'):_original_CodeMirror_defineMode.apply(CodeMirror,arguments)}CodeMirror.defineMode=_wrapped_CodeMirror_defineMode}function _setLanguageForMode(mode,language){_modeToLanguageMap[mode]?console.warn('CodeMirror mode "'+mode+'" is already used by language '+_modeToLanguageMap[mode]._name+" - cannot fully register language "+language._name+" using the same mode. Some features will treat all content with this mode as language "+_modeToLanguageMap[mode]._name):_modeToLanguageMap[mode]=language}function getLanguage(id){return _languages[id]}function getLanguageForExtension(extension){return _fileExtensionToLanguageMap[extension.toLowerCase()]}function getLanguageForPath(path,ignoreOverride){var fileName,language=_filePathToLanguageMap[path],extension,parts;if(!ignoreOverride&&language)return language;if(fileName=FileUtils.getBaseName(path).toLowerCase(),!(language=_fileNameToLanguageMap[fileName]))for(""===(parts=fileName.split("."))[0]&&parts.shift(),parts.shift();!language&&parts.length;)extension=parts.join("."),language=_fileExtensionToLanguageMap[extension],parts.shift();return language||_fallbackLanguage}function getLanguages(){return $.extend({},_languages)}function _getLanguageForMode(mode){var language=_modeToLanguageMap[mode];return language||(console.log("Called LanguageManager._getLanguageForMode with a mode for which no language has been registered:",mode),_fallbackLanguage)}function _triggerLanguageAdded(language){_languages[language.getId()]=language,exports.trigger("languageAdded",language)}function _triggerLanguageModified(language){exports.trigger("languageModified",language)}function setLanguageOverrideForPath(fullPath,language){var oldLang=getLanguageForPath(fullPath);language?_filePathToLanguageMap[fullPath]=language:delete _filePathToLanguageMap[fullPath];var newLang=getLanguageForPath(fullPath);_triggerLanguageModified(oldLang),_triggerLanguageModified(newLang)}function _resetPathLanguageOverrides(){_filePathToLanguageMap={}}function getCompoundFileExtension(fullPath){var baseName=FileUtils.getBaseName(fullPath),parts=baseName.split(".");parts.shift(),"."===baseName[0]&&parts.shift();for(var extension=[parts.pop()],i=parts.length;i--&&getLanguageForExtension(parts[i]);)extension.unshift(parts[i]);return extension.join(".")}function Language(){this._fileExtensions=[],this._fileNames=[],this._modeToLanguageMap={},this._lineCommentSyntax=[]}function defineLanguage(id,definition){var result=new $.Deferred;if(_pendingLanguages[id])return result.reject('Language "'+id+'" is waiting to be resolved.'),result.promise();if(_languages[id])return result.reject('Language "'+id+'" is already defined'),result.promise();var language=new Language,name=definition.name,fileExtensions=definition.fileExtensions,fileNames=definition.fileNames,blockComment=definition.blockComment,lineComment=definition.lineComment,i,l;function _finishRegisteringLanguage(){if(fileExtensions)for(i=0,l=fileExtensions.length;i<l;i++)language.addFileExtension(fileExtensions[i]);if(fileNames)for(i=0,l=fileNames.length;i<l;i++)language.addFileName(fileNames[i]);language._setBinary(!!definition.isBinary),_languages[language.getId()]=language,PreferencesManager&&(_updateFromPrefs(_EXTENSION_MAP_PREF),_updateFromPrefs(_NAME_MAP_PREF))}return!language._setId(id)||!language._setName(name)||blockComment&&!language.setBlockCommentSyntax(blockComment[0],blockComment[1])||lineComment&&!language.setLineCommentSyntax(lineComment)?(result.reject(),result.promise()):(definition.isBinary?(_finishRegisteringLanguage(),result.resolve(language)):(_pendingLanguages[id]=language,language._loadAndSetMode(definition.mode).done(function(){_setLanguageForMode(language.getMode(),language),_finishRegisteringLanguage(),_triggerLanguageAdded(language),result.resolve(language)}).fail(function(error){console.error(error),result.reject(error)}).always(function(){delete _pendingLanguages[id]})),result.promise())}function _restoreOverriddenDefault(name,state){var language;state.overridden[name]&&(getLanguage(state.overridden[name])[state.add](name),delete state.overridden[name])}function _updateFromPrefs(pref){var newMapping=PreferencesManager.get(pref),newNames=Object.keys(newMapping),state=_prefState[pref],last=state.last,overridden=state.overridden;newNames.forEach(function(name){var language;newMapping[name]!==last[name]&&(last[name]&&(language=getLanguage(last[name]))&&(language[state.remove](name),_restoreOverriddenDefault(name,state)),(language=exports[state.get](name))&&(language[state.remove](name),overridden[name]||(overridden[name]=language.getId())),(language=getLanguage(newMapping[name]))&&language[state.add](name)),getLanguage(newMapping[name])||(overridden[name]&&_restoreOverriddenDefault(name,state),delete newMapping[name])}),_.difference(Object.keys(last),newNames).forEach(function(name){var language=getLanguage(last[name]);language&&(language[state.remove](name),_restoreOverriddenDefault(name,state))}),state.last=newMapping}_prefState[_EXTENSION_MAP_PREF]={last:{},overridden:{},add:"addFileExtension",remove:"removeFileExtension",get:"getLanguageForExtension"},_prefState[_NAME_MAP_PREF]={last:{},overridden:{},add:"addFileName",remove:"removeFileName",get:"getLanguageForPath"},Language.prototype._id=null,Language.prototype._name=null,Language.prototype._mode=null,Language.prototype._fileExtensions=null,Language.prototype._fileNames=null,Language.prototype._lineCommentSyntax=null,Language.prototype._modeToLanguageMap=null,Language.prototype._blockCommentSyntax=null,Language.prototype._isBinary=!1,Language.prototype.getId=function(){return this._id},Language.prototype._setId=function(id){return!!_validateNonEmptyString(id,"Language ID")&&(id.match(/^[a-z0-9]+(_[a-z0-9]+)*$/)?(this._id=id,!0):(console.error('Invalid language ID "'+id+'": Only groups of lower case letters and numbers are allowed, separated by underscores.'),!1))},Language.prototype.getName=function(){return this._name},Language.prototype._setName=function(name){return!!_validateNonEmptyString(name,"name")&&(this._name=name,!0)},Language.prototype.getMode=function(){return this._mode},Language.prototype._loadAndSetMode=function(mode){var result=new $.Deferred,self=this,mimeMode;if(Array.isArray(mode)){if(2!==mode.length)return result.reject("Mode must either be a string or an array containing two strings"),result.promise();mimeMode=mode[1],mode=mode[0]}if(!_validateNonEmptyString(mode,"mode",result))return result.reject(),result.promise();var finish=function(){if(CodeMirror.modes[mode]){var modeConfig;if(mimeMode)if(!CodeMirror.mimeModes[mimeMode])return void result.reject('CodeMirror MIME mode "'+mimeMode+'" not found');self._mode=mimeMode||mode,self._wasModified(),result.resolve(self)}else result.reject('CodeMirror mode "'+mode+'" is not loaded')};return CodeMirror.modes[mode]?finish():require(["thirdparty/CodeMirror/mode/"+mode+"/"+mode],finish),result.promise()},Language.prototype.getFileExtensions=function(){return this._fileExtensions.concat()},Language.prototype.getFileNames=function(){return this._fileNames.concat()},Language.prototype.addFileExtension=function(extension){Array.isArray(extension)?extension.forEach(this._addFileExtension.bind(this)):this._addFileExtension(extension)},Language.prototype._addFileExtension=function(extension){if("."===extension.charAt(0)&&(extension=extension.substr(1)),extension=extension.toLowerCase(),-1===this._fileExtensions.indexOf(extension)){this._fileExtensions.push(extension);var language=_fileExtensionToLanguageMap[extension];language?console.warn('Cannot register file extension "'+extension+'" for '+this._name+", it already belongs to "+language._name):_fileExtensionToLanguageMap[extension]=this,this._wasModified()}else _fileExtensionToLanguageMap[extension]||(_fileExtensionToLanguageMap[extension]=this,this._wasModified())},Language.prototype.removeFileExtension=function(extension){Array.isArray(extension)?extension.forEach(this._removeFileExtension.bind(this)):this._removeFileExtension(extension)},Language.prototype._removeFileExtension=function(extension){"."===extension.charAt(0)&&(extension=extension.substr(1)),extension=extension.toLowerCase();var index=this._fileExtensions.indexOf(extension);-1!==index&&(this._fileExtensions.splice(index,1),delete _fileExtensionToLanguageMap[extension],this._wasModified())},Language.prototype.addFileName=function(name){Array.isArray(name)?name.forEach(this._addFileName.bind(this)):this._addFileName(name)},Language.prototype._addFileName=function(name){if(name=name.toLowerCase(),-1===this._fileNames.indexOf(name)){this._fileNames.push(name);var language=_fileNameToLanguageMap[name];language?console.warn('Cannot register file name "'+name+'" for '+this._name+", it already belongs to "+language._name):_fileNameToLanguageMap[name]=this,this._wasModified()}},Language.prototype.removeFileName=function(name){Array.isArray(name)?name.forEach(this._removeFileName.bind(this)):this._removeFileName(name)},Language.prototype._removeFileName=function(name){name=name.toLowerCase();var index=this._fileNames.indexOf(name);-1!==index&&(this._fileNames.splice(index,1),delete _fileNameToLanguageMap[name],this._wasModified())},Language.prototype.hasLineCommentSyntax=function(){return this._lineCommentSyntax.length>0},Language.prototype.getLineCommentPrefixes=function(){return this._lineCommentSyntax},Language.prototype.setLineCommentSyntax=function(prefix){var prefixes=Array.isArray(prefix)?prefix:[prefix],i;if(prefixes.length){for(this._lineCommentSyntax=[],i=0;i<prefixes.length;i++)_validateNonEmptyString(String(prefixes[i]),Array.isArray(prefix)?"prefix["+i+"]":"prefix"),this._lineCommentSyntax.push(prefixes[i]);this._wasModified()}else console.error("The prefix array should not be empty");return!0},Language.prototype.hasBlockCommentSyntax=function(){return Boolean(this._blockCommentSyntax)},Language.prototype.getBlockCommentPrefix=function(){return this._blockCommentSyntax&&this._blockCommentSyntax.prefix},Language.prototype.getBlockCommentSuffix=function(){return this._blockCommentSyntax&&this._blockCommentSyntax.suffix},Language.prototype.setBlockCommentSyntax=function(prefix,suffix){return!(!_validateNonEmptyString(prefix,"prefix")||!_validateNonEmptyString(suffix,"suffix"))&&(this._blockCommentSyntax={prefix:prefix,suffix:suffix},this._wasModified(),!0)},Language.prototype.getLanguageForMode=function(mode){return mode===this._mode?this:this._modeToLanguageMap[mode]||_getLanguageForMode(mode)},Language.prototype._setLanguageForMode=function(mode,language){return mode===this._mode&&language!==this?(console.error("A language must always map its mode to itself"),!1):(this._modeToLanguageMap[mode]=language,this._wasModified(),!0)},Language.prototype.isFallbackLanguage=function(){return this===_fallbackLanguage},Language.prototype._wasModified=function(){_languages[this._id]&&_triggerLanguageModified(this)},Language.prototype.isBinary=function(){return this._isBinary},Language.prototype._setBinary=function(isBinary){this._isBinary=isBinary},EventDispatcher.makeEventDispatcher(exports),_patchCodeMirror(),CodeMirror.defineMIME("text/x-brackets-html",{name:"htmlmixed",scriptTypes:[{matches:/\/x-handlebars|\/x-mustache|\/ng-template$|^text\/html$/i,mode:"htmlmixed"},{matches:/^text\/(babel|jsx)$/i,mode:"jsx"}]}),CodeMirror.defineMIME("image/svg+xml","xml"),_defaultLanguagesJSON=JSON.parse(_defaultLanguagesJSON),(_ready=Async.doInParallel(Object.keys(_defaultLanguagesJSON),function(key){return defineLanguage(key,_defaultLanguagesJSON[key])},!1)).always(function(){var html=getLanguage("html");html._setLanguageForMode("xml",html),_setLanguageForMode("html",html);var php=getLanguage("php");php._setLanguageForMode("clike",php);var scss=getLanguage("scss"),stylus;scss._setLanguageForMode("css",scss),_setLanguageForMode("stylus",getLanguage("stylus")),_fallbackLanguage=getLanguage("unknown"),require(["preferences/PreferencesManager"],function(pm){PreferencesManager=pm,pm.definePreference(_EXTENSION_MAP_PREF,"object",{},{description:Strings.DESCRIPTION_LANGUAGE_FILE_EXTENSIONS}).on("change",function(){_updateFromPrefs(_EXTENSION_MAP_PREF)}),pm.definePreference(_NAME_MAP_PREF,"object",{},{description:Strings.DESCRIPTION_LANGUAGE_FILE_NAMES}).on("change",function(){_updateFromPrefs(_NAME_MAP_PREF)}),_updateFromPrefs(_EXTENSION_MAP_PREF),_updateFromPrefs(_NAME_MAP_PREF)})}),exports._EXTENSION_MAP_PREF=_EXTENSION_MAP_PREF,exports._NAME_MAP_PREF=_NAME_MAP_PREF,exports._resetPathLanguageOverrides=_resetPathLanguageOverrides,exports.ready=_ready,exports.defineLanguage=defineLanguage,exports.getLanguage=getLanguage,exports.getLanguageForExtension=getLanguageForExtension,exports.getLanguageForPath=getLanguageForPath,exports.getLanguages=getLanguages,exports.setLanguageOverrideForPath=setLanguageOverrideForPath,exports.getCompoundFileExtension=getCompoundFileExtension});