Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Made Language.addFileExtension public #3051

Merged
merged 5 commits into from
Mar 13, 2013
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/document/DocumentManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,26 @@ define(function (require, exports, module) {
*/
function _handleLanguageAdded(event, language) {
CollectionUtils.forEach(_openDocuments, function (doc, key) {
doc._updateLanguage();
// No need to look at the new language if this document has one already
if (doc.getLanguage().isFallbackLanguage()) {
doc._updateLanguage();
}
});
}

/**
* @private
* Update document
*/
function _handleLanguageModified(event, language) {
CollectionUtils.forEach(_openDocuments, function (doc, key) {
var docLanguage = doc.getLanguage();
// A modified language can affect a document
// - if its language was modified
// - if the document doesn't have a language yet and its file extension was added to the modified language
if (docLanguage === language || docLanguage.isFallbackLanguage()) {
doc._updateLanguage();
}
});
}

Expand Down Expand Up @@ -1255,4 +1274,5 @@ define(function (require, exports, module) {

// Handle Language change events
$(LanguageManager).on("languageAdded", _handleLanguageAdded);
$(LanguageManager).on("languageModified", _handleLanguageModified);
});
8 changes: 6 additions & 2 deletions src/editor/EditorStatusBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ define(function (require, exports, module) {

function _onActiveEditorChange(event, current, previous) {
if (previous) {
$(previous).off("cursorActivity.statusbar");
$(previous).off("change.statusbar");
$(previous).off(".statusbar");
$(previous.document).off(".statusbar");
previous.document.releaseRef();
}

if (!current) {
Expand All @@ -133,6 +134,9 @@ define(function (require, exports, module) {
window.setTimeout(function () { _updateFileInfo(current); }, 0);
});

current.document.addRef();
$(current.document).on("languageChanged.statusbar", function () { _updateLanguageInfo(current); });

_updateCursorInfo(null, current);
_updateLanguageInfo(current);
_updateFileInfo(current);
Expand Down
54 changes: 44 additions & 10 deletions src/language/LanguageManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,27 @@ define(function (require, exports, module) {
return _fallbackLanguage;
}

/**
* @private
* Notify listeners when a language is added
* @param {!Language} language The new language
*/
function _triggerLanguageAdded(language) {
// finally, store language to _language map
_languages[language.getId()] = language;
$(exports).triggerHandler("languageAdded", [language]);
}

/**
* @private
* Notify listeners when a language is modified
* @param {!Language} language The modified language
*/
function _triggerLanguageModified(language) {
$(exports).triggerHandler("languageModified", [language]);
}


/**
* @constructor
* Model for a language.
Expand Down Expand Up @@ -330,6 +351,7 @@ define(function (require, exports, module) {
// This mode is now only about what to tell CodeMirror
// The base mode was only necessary to load the proper mode file
self._mode = mimeMode || mode;
self._wasModified();

result.resolve(self);
};
Expand Down Expand Up @@ -357,9 +379,8 @@ define(function (require, exports, module) {
* Private for now since dependent code would need to by kept in sync with such changes.
* See https://github.com/adobe/brackets/issues/2966 for plans to make this public.
* @param {!string} extension A file extension used by this language
* @private
*/
Language.prototype._addFileExtension = function (extension) {
Language.prototype.addFileExtension = function (extension) {
extension = _normalizeFileExtension(extension);

if (this._fileExtensions.indexOf(extension) === -1) {
Expand All @@ -376,6 +397,8 @@ define(function (require, exports, module) {
// $(this).triggerHandler("fileExtensionAdded", [extension]);
// $(exports).triggerHandler("fileExtensionAdded", [extension, this]);
}

this._wasModified();
}
};

Expand Down Expand Up @@ -403,6 +426,7 @@ define(function (require, exports, module) {
_validateNonEmptyString(prefix, "prefix");

this._lineCommentSyntax = { prefix: prefix };
this._wasModified();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this useful to notify when the comment markup changes? I appreciate the completeness but I don't think there should be anything actionable unless for some reason a client cached the comment markup values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is for completion... I have a hard time coming up with use cases, too. But it's also a non-issue since the languageModified event is only triggered for languages that are already registered, so this would only happen for languages that get different comment settings after having been defined.

Would you prefer to have it removed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it's fine as-is. Thanks.

};

/**
Expand Down Expand Up @@ -439,6 +463,7 @@ define(function (require, exports, module) {
_validateNonEmptyString(suffix, "suffix");

this._blockCommentSyntax = { prefix: prefix, suffix: suffix };
this._wasModified();
};

/**
Expand Down Expand Up @@ -467,18 +492,27 @@ define(function (require, exports, module) {
throw new Error("A language must always map its mode to itself");
}
this._modeToLanguageMap[mode] = language;
this._wasModified();
};

/**
* Determines whether this is the fallback language or not
* @return {boolean} True if this is the fallback language, false otherwise
*/
Language.prototype.isFallbackLanguage = function () {
return this === _fallbackLanguage;
};

/**
* Trigger the "languageModified" event if this language is registered already
* @see _triggerLanguageModified
* @private
* Notify listeners when a language is added
* @param {!Language} language The new language
*/
function _triggerLanguageAdded(language) {
// finally, store language to _language map
_languages[language.getId()] = language;
$(exports).triggerHandler("languageAdded", [language]);
}
Language.prototype._wasModified = function () {
if (_languages[this._id]) {
_triggerLanguageModified(this);
}
};

/**
* Defines a language.
Expand Down Expand Up @@ -523,7 +557,7 @@ define(function (require, exports, module) {
// register language file extensions after mode has loaded
if (fileExtensions) {
for (i = 0; i < fileExtensions.length; i++) {
language._addFileExtension(fileExtensions[i]);
language.addFileExtension(fileExtensions[i]);
}
}

Expand Down
40 changes: 40 additions & 0 deletions test/spec/LanguageManager-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,46 @@ define(function (require, exports, module) {
});
});

it("should update the document's language when a language is modified", function () {
var unknown,
doc,
spy,
modifiedLanguage,
promise;

runs(function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping this in a runs() block should not be necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

// Create a shell script file
doc = SpecRunnerUtils.createMockActiveDocument({ filename: "test.foo" });

// Initial language will be unknown (shell is not a default language)
unknown = LanguageManager.getLanguage("unknown");

// listen for event
spy = jasmine.createSpy("languageChanged event handler");
$(doc).on("languageChanged", spy);

// sanity check language
expect(doc.getLanguage()).toBe(unknown);

// make active
doc.addRef();

modifiedLanguage = LanguageManager.getLanguage("html");
modifiedLanguage.addFileExtension("foo");

// language should change
expect(doc.getLanguage()).toBe(modifiedLanguage);
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toEqual(1);

// check callback args (arg 0 is a jQuery event)
expect(spy.mostRecentCall.args[1]).toBe(unknown);
expect(spy.mostRecentCall.args[2]).toBe(modifiedLanguage);

// cleanup
doc.releaseRef();
});
});
});
});
});