PreferencesManager
The prefix used in the generated client ID
var CLIENT_ID_PREFIX = "com.adobe.brackets.";
// Private Properties
var preferencesKey,
prefStorage,
persistentStorage,
extensionPaths,
doLoadPreferences = false;Context to look up preferences for the currently edited file. This is undefined because this is the default behavior of PreferencesSystem.get.
var CURRENT_FILE;Context to look up preferences in the current project.
var CURRENT_PROJECT = {};The local storage ID
var PREFERENCES_CLIENT_ID = "com.adobe.brackets.preferences"; function _adjustScopeOrderForProject(scopeOrder, includeProject) {
var hasProject = scopeOrder.indexOf("project") > -1;
if (hasProject === includeProject) {
return scopeOrder;
}
var newScopeOrder;
if (includeProject) {
var before = scopeOrder.indexOf("user");
if (before === -1) {
before = scopeOrder.length - 2;
}
newScopeOrder = _.take(scopeOrder, before);
newScopeOrder.push("project");
newScopeOrder.push.apply(newScopeOrder, _.drop(scopeOrder, before));
} else {
newScopeOrder = _.without(scopeOrder, "project");
}
return newScopeOrder;
} function _buildContext(filename, languageId) {
var ctx = {};
if (filename) {
ctx.path = filename;
} else {
ctx.path = currentFilename;
}
if (languageId) {
ctx.language = languageId;
} else {
ctx.language = currentLanguageId;
}
ctx.scopeOrder = _includeProjectScope(ctx.path) ?
scopeOrderWithProject :
scopeOrderWithoutProject;
return ctx;
}
function _getContext(context) {
context = context || {};
return _buildContext(context.path, context.language);
} function _getExtensionPaths() {
if (!extensionPaths) {
var dirPath = FileUtils.getNativeBracketsDirectoryPath();
extensionPaths = [
dirPath + "/extensions/default/",
dirPath + "/extensions/dev/",
ExtensionLoader.getUserExtensionPath() + "/"
];
}
return extensionPaths;
} function _handleOpenPreferences() {
var fullPath = getUserPrefFile(),
file = FileSystem.getFileForPath(fullPath);
file.exists(function (err, doesExist) {
if (doesExist) {
CommandManager.execute(Commands.FILE_OPEN, { fullPath: fullPath });
} else {
FileUtils.writeText(file, "", true)
.done(function () {
CommandManager.execute(Commands.FILE_OPEN, { fullPath: fullPath });
});
}
});
}
CommandManager.register(Strings.CMD_OPEN_PREFERENCES, Commands.FILE_OPEN_PREFERENCES, _handleOpenPreferences); function _includeProjectScope(filename) {
filename = filename || currentFilename;
if (!filename || !projectDirectory) {
return false;
}
return FileUtils.getRelativeFilename(projectDirectory, filename) !== undefined;
} function _initStorage(storage) {
persistentStorage = storage;
if (doLoadPreferences) {
prefStorage = JSON.parse(persistentStorage.getItem(preferencesKey));
}
// initialize empty preferences if none were found in storage
if (!prefStorage) {
_reset();
}
}
// Check localStorage for a preferencesKey. Production and unit test keys
// are used to keep preferences separate within the same storage implementation.
preferencesKey = localStorage.getItem("preferencesKey");
if (!preferencesKey) {
// use default key if none is found
preferencesKey = PREFERENCES_CLIENT_ID;
doLoadPreferences = true;
} else {
// using a non-default key, check for additional settings
doLoadPreferences = !!(localStorage.getItem("doLoadPreferences"));
}
// Use localStorage by default
_initStorage(localStorage);
// Public API
exports.getPreferenceStorage = getPreferenceStorage;
exports.savePreferences = savePreferences;
exports.getClientID = getClientID;
// Unit test use only
exports._reset = _reset;
exports._getExtensionPaths = _getExtensionPaths;
// New code follows. The code above (with the exception of the imports) is
// deprecated.
var currentFilename = null, // the filename currently being edited
currentLanguageId = null, // the language id of the file currently being edited
projectDirectory = null,
projectScopeIsIncluded = true; function _reset() {
prefStorage = {};
// Note that storage.clear() is not used. Production and unit test code
// both rely on the same backing storage but unique item keys.
persistentStorage.setItem(preferencesKey, JSON.stringify(prefStorage));
} function _setCurrentFile(newFilename) {
var oldFilename = currentFilename;
if (oldFilename === newFilename) {
return;
}
currentFilename = newFilename;
_toggleProjectScope();
PreferencesImpl.manager.signalContextChanged(_buildContext(oldFilename, currentLanguageId),
_buildContext(newFilename, currentLanguageId));
} function _setCurrentLanguage(newLanguageId) {
var oldLanguageId = currentLanguageId;
if (oldLanguageId === newLanguageId) {
return;
}
currentLanguageId = newLanguageId;
PreferencesImpl.manager.signalContextChanged(_buildContext(currentFilename, oldLanguageId),
_buildContext(currentFilename, newLanguageId));
}
PreferencesImpl.manager.contextBuilder = _getContext; function _setProjectSettingsFile(settingsFile) {
projectDirectory = FileUtils.getDirectoryPath(settingsFile);
_toggleProjectScope();
PreferencesImpl.projectPathLayer.setPrefFilePath(settingsFile);
PreferencesImpl.projectStorage.setPath(settingsFile);
} function _toggleProjectScope() {
if (_includeProjectScope() === projectScopeIsIncluded) {
return;
}
if (projectScopeIsIncluded) {
PreferencesImpl.manager.removeFromScopeOrder("project");
} else {
PreferencesImpl.manager.addToScopeOrder("project", "user");
}
projectScopeIsIncluded = !projectScopeIsIncluded;
} function _updateCurrentProjectContext() {
var defaultScopeOrder = PreferencesImpl.manager._getScopeOrder({});
scopeOrderWithProject = _adjustScopeOrderForProject(defaultScopeOrder, true);
scopeOrderWithoutProject = _adjustScopeOrderForProject(defaultScopeOrder, false);
CURRENT_PROJECT.scopeOrder = scopeOrderWithProject;
}
_updateCurrentProjectContext();
PreferencesImpl.manager.on("scopeOrderChange", _updateCurrentProjectContext);Converts from the old localStorage-based preferences to the new-style preferences according to the "rules" given.
rules is an object, the keys of which refer to the preference names.
The value tells the converter what to do. The following values are available:
user: convert to a user-level preferenceuser newkey: convert to a user-level preference, changing the key to newkeyOnce a key has been converted, it will not be converted again.
function convertPreferences(clientID, rules, isViewState, prefCheckCallback) {
DeprecationWarning.deprecationWarning("PreferencesManager.convertPreferences() has been deprecated. " +
"Please upgrade to the current Preferences system " +
"(https://github.com/adobe/brackets/wiki/Preferences-System#conversion-from-the-pre-36-preferences-system).");
PreferencesImpl.smUserScopeLoading.done(function () {
PreferencesImpl.userScopeLoading.done(function () {
if (!clientID || (typeof clientID === "object" && (!clientID.id || !clientID.uri))) {
console.error("Invalid clientID");
return;
}
var prefs = getPreferenceStorage(clientID, null, true);
if (!prefs) {
return;
}
var prefsID = typeof clientID === "object" ? getClientID(clientID) : clientID;
if (prefStorage.convertedKeysMap === undefined) {
prefStorage.convertedKeysMap = {};
}
var convertedKeysMap = prefStorage.convertedKeysMap;
prefs.convert(rules, convertedKeysMap[prefsID], isViewState, prefCheckCallback)
.done(function (complete, convertedKeys) {
prefStorage.convertedKeysMap[prefsID] = convertedKeys;
savePreferences();
});
}).fail(function (error) {
console.error("Error while converting ", typeof clientID === "object" ? getClientID(clientID) : clientID);
console.error(error);
});
});
}
// Constants for preference lookup contexts.This method returns a standardized ClientID for a given requireJS module object
function getClientID(module) {
var paths = exports._getExtensionPaths();
var pathUrl, clientID;
paths.some(function (path) {
if (module.uri.toLocaleLowerCase().indexOf(path.toLocaleLowerCase()) === 0) {
pathUrl = path;
return true;
}
});
if (pathUrl) {
clientID = CLIENT_ID_PREFIX + module.uri.replace(pathUrl, "");
} else {
clientID = CLIENT_ID_PREFIX + module.id;
}
return clientID;
}Creates an extension-specific preferences manager using the prefix given.
A . character will be appended to the prefix. So, a preference named foo
with a prefix of myExtension will be stored as myExtension.foo in the
preferences files.
function getExtensionPrefs(prefix) {
return PreferencesImpl.manager.getPrefixedSystem(prefix);
}Retreive the preferences data for the given clientID.
function getPreferenceStorage(clientID, defaults, _doNotCreate) {
// No one should be calling this to access the old preference storage except for
// migrating the old preferences to the new model. So if this is called without
// having _doNotCreate set to true, then the caller is using the old preferences model.
if (!_doNotCreate) {
var clientString = typeof clientID === "object" ? clientID.uri : clientID;
DeprecationWarning.deprecationWarning("PreferencesManager.getPreferenceStorage() called with client id '" +
clientString + "' has been deprecated. Use PreferencesManager.definePreference() instead.");
}
if (!clientID || (typeof clientID === "object" && (!clientID.id || !clientID.uri))) {
console.error("Invalid clientID");
return;
}
if (typeof clientID === "object") {
clientID = getClientID(clientID);
}
var prefs = prefStorage[clientID];
if (prefs === undefined) {
if (_doNotCreate) {
return;
}
// create a new empty preferences object
prefs = (defaults && JSON.stringify(defaults)) ? defaults : {};
prefStorage[clientID] = prefs;
} else if (defaults) {
// add new defaults
_.forEach(defaults, function (value, key) {
if (prefs[key] === undefined) {
prefs[key] = value;
}
});
}
return new OldPreferenceStorage(clientID, prefs);
}Get the full path to the user-level preferences file.
function getUserPrefFile() {
return PreferencesImpl.userPrefFile;
}Convenience function that gets a view state
function getViewState(id, context) {
return PreferencesImpl.stateManager.get(id, context);
}Save all preference clients.
function savePreferences() {
// save all preferences
persistentStorage.setItem(preferencesKey, JSON.stringify(prefStorage));
}Convenience function that sets a preference and then saves the file, mimicking the old behavior a bit more closely.
function setValueAndSave(id, value, options) {
DeprecationWarning.deprecationWarning("PreferencesManager.setValueAndSave() called for " + id + ". Use PreferencesManager.set() instead.", true);
var changed = exports.set(id, value, options).stored;
PreferencesImpl.manager.save();
return changed;
}Convenience function that sets a view state and then saves the file
function setViewState(id, value, context, doNotSave) {
PreferencesImpl.stateManager.set(id, value, context);
if (!doNotSave) {
PreferencesImpl.stateManager.save();
}
}
AppInit.appReady(function () {
PreferencesImpl.manager.resumeChangeEvents();
});
// Private API for unit testing and use elsewhere in Brackets core
exports._isUserScopeCorrupt = PreferencesImpl.isUserScopeCorrupt;
exports._setCurrentFile = _setCurrentFile;
exports._setCurrentLanguage = _setCurrentLanguage;
exports._setProjectSettingsFile = _setProjectSettingsFile;
exports._smUserScopeLoading = PreferencesImpl.smUserScopeLoading;
exports._stateProjectLayer = PreferencesImpl.stateProjectLayer;
exports._reloadUserPrefs = PreferencesImpl.reloadUserPrefs;
exports._buildContext = _buildContext;
// Public API
// Context names for preference lookups
exports.CURRENT_FILE = CURRENT_FILE;
exports.CURRENT_PROJECT = CURRENT_PROJECT;
exports.ready = PreferencesImpl.managerReady;
exports.getUserPrefFile = getUserPrefFile;
exports.get = PreferencesImpl.manager.get.bind(PreferencesImpl.manager);
exports.set = PreferencesImpl.manager.set.bind(PreferencesImpl.manager);
exports.save = PreferencesImpl.manager.save.bind(PreferencesImpl.manager);
exports.on = PreferencesImpl.manager.on.bind(PreferencesImpl.manager);
exports.off = PreferencesImpl.manager.off.bind(PreferencesImpl.manager);
exports.getPreference = PreferencesImpl.manager.getPreference.bind(PreferencesImpl.manager);
exports.getAllPreferences = PreferencesImpl.manager.getAllPreferences.bind(PreferencesImpl.manager);
exports.getExtensionPrefs = getExtensionPrefs;
exports.setValueAndSave = setValueAndSave;
exports.getViewState = getViewState;
exports.setViewState = setViewState;
exports.addScope = PreferencesImpl.manager.addScope.bind(PreferencesImpl.manager);
exports.stateManager = PreferencesImpl.stateManager;
exports.FileStorage = PreferencesBase.FileStorage;
exports.SETTINGS_FILENAME = PreferencesImpl.SETTINGS_FILENAME;
exports.definePreference = PreferencesImpl.manager.definePreference.bind(PreferencesImpl.manager);
exports.fileChanged = PreferencesImpl.manager.fileChanged.bind(PreferencesImpl.manager);
exports.convertPreferences = convertPreferences;
});