Merge branch 'jasonsanjose/fix-live-dev-ci' of github.com:adobe/brackets into jasonsanjose/fix-live-dev-ci

This commit is contained in:
Jason San Jose 2013-04-04 14:23:04 -07:00
Родитель 471cb7e238 e041d23c8e
Коммит 96f1026306
16 изменённых файлов: 1050 добавлений и 74 удалений

Просмотреть файл

@ -117,7 +117,7 @@ define(function DOMHelpersModule(require, exports, module) {
*/
function _findTag(src, skip) {
var from, to, inc;
from = _find(src, [/<[a-z!\/]/, 2], skip);
from = _find(src, [/<[a-z!\/]/i, 2], skip);
if (from < 0) {
return null;
}
@ -125,9 +125,9 @@ define(function DOMHelpersModule(require, exports, module) {
// html comments
to = _find(src, "-->", from + 4);
inc = 3;
} else if (src.substr(from, 7) === "<script") {
} else if (src.substr(from, 7).toLowerCase() === "<script") {
// script tag
to = _find(src, "</script>", from + 7);
to = _find(src.toLowerCase(), "</script>", from + 7);
inc = 9;
} else {
to = _find(src, ">", from + 1, true);
@ -208,6 +208,12 @@ define(function DOMHelpersModule(require, exports, module) {
if (content[content.length - 2] === "/") {
payload.closed = true;
}
// Special handling for script tag since we've already collected
// everything up to the end tag.
if (payload.nodeName === "SCRIPT") {
payload.closed = true;
}
}
return payload;
}

Просмотреть файл

@ -224,7 +224,12 @@ function RemoteFunctions(experimental) {
var elementBounds = element.getBoundingClientRect(),
highlight = window.document.createElement("div"),
styles = window.getComputedStyle(element);
// Don't highlight elements with 0 width & height
if (elementBounds.width === 0 && elementBounds.height === 0) {
return;
}
highlight.className = HIGHLIGHT_CLASSNAME;
var stylesToSet = {
@ -241,7 +246,8 @@ function RemoteFunctions(experimental) {
"border-bottom-right-radius": styles.borderBottomRightRadius,
"border-style": "solid",
"border-width": "1px",
"border-color": "rgb(94,167,255)"
"border-color": "rgb(94,167,255)",
"box-sizing": "border-box"
};
var animateStartValues = {

Просмотреть файл

@ -59,7 +59,7 @@ define(function (require, exports, module) {
return true;
}
if (/(!doctype|area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param|embed)/i
if (/(!doctype|area|base|basefont|br|wbr|col|frame|hr|img|input|isindex|link|meta|param|embed)/i
.test(payload.nodeName)) {
return true;
}
@ -90,6 +90,10 @@ define(function (require, exports, module) {
var tag;
DOMHelpers.eachNode(text, function (payload) {
// Ignore closing empty tags like </input> since they're invalid.
if (payload.closing && _isEmptyTag(payload)) {
return;
}
if (payload.nodeType === 1 && payload.nodeName) {
// Set unclosedLength for the last tag
if (tagStack.length > 0) {
@ -106,15 +110,12 @@ define(function (require, exports, module) {
// Empty tag
if (_isEmptyTag(payload)) {
// Only push img and input. Ignore all other empty tags
if (/(img|input)/i.test(payload.nodeName)) {
tags.push({
name: payload.nodeName,
tagID: tagID++,
offset: payload.sourceOffset,
length: payload.sourceLength
});
}
tags.push({
name: payload.nodeName,
tagID: tagID++,
offset: payload.sourceOffset,
length: payload.sourceLength
});
} else if (payload.closing) {
// Closing tag
var i,

Просмотреть файл

@ -142,7 +142,8 @@ define(function (require, exports, module) {
* cancels Quick Open (via Esc), those changes are automatically reverted.
*/
function addQuickOpenPlugin(pluginDef) {
if (pluginDef.fileTypes) {
// Backwards compatibility (for now) for old fileTypes field, if newer languageIds not specified
if (pluginDef.fileTypes && !pluginDef.languageIds) {
console.warn("Using fileTypes for QuickOpen plugins is deprecated. Use languageIds instead.");
pluginDef.languageIds = pluginDef.fileTypes.map(function (extension) {
return LanguageManager.getLanguageForPath("file." + extension).getId();
@ -399,9 +400,10 @@ define(function (require, exports, module) {
* list items are re-rendered. Both happen synchronously just after we return. Called even when results is empty.
*/
QuickNavigateDialog.prototype._handleResultsReady = function (e, results) {
// Give visual clue when there are no results
var isNoResults = (results.length === 0 && !this._isValidLineNumberQuery(this.$searchField.val()));
this.$searchField.toggleClass("no-results", isNoResults);
// Give visual clue when there are no results (unless we're in "Go To Line" mode, where there
// are never results, or we're in file search mode and waiting for the index to get rebuilt)
var isNoResults = (results.length === 0 && (fileList || currentPlugin) && !this._isValidLineNumberQuery(this.$searchField.val()));
this.$searchField.toggleClass("no-results", Boolean(isNoResults));
};
/**
@ -543,8 +545,8 @@ define(function (require, exports, module) {
var i;
for (i = 0; i < plugins.length; i++) {
var plugin = plugins[i];
var LanguageIdMatch = plugin.languageIds.indexOf(languageId) !== -1 || plugin.languageIds.length === 0;
if (LanguageIdMatch && plugin.match && plugin.match(query)) {
var languageIdMatch = plugin.languageIds.indexOf(languageId) !== -1 || plugin.languageIds.length === 0;
if (languageIdMatch && plugin.match && plugin.match(query)) {
currentPlugin = plugin;
// Look up the StringMatcher for this plugin.
@ -786,12 +788,12 @@ define(function (require, exports, module) {
// Start fetching the file list, which will be needed the first time the user enters an un-prefixed query. If FileIndexManager's
// caches are out of date, this list might take some time to asynchronously build. See searchFileList() for how this is handled.
fileList = null;
fileListPromise = FileIndexManager.getFileInfoList("all")
.done(function (files) {
fileList = files;
fileListPromise = null;
});
this._filenameMatcher.reset();
}.bind(this));
};
function getCurrentEditorSelectedText() {
@ -833,8 +835,11 @@ define(function (require, exports, module) {
beginSearch("@", getCurrentEditorSelectedText());
}
}
// Listen for a change of project to invalidate our file list
$(ProjectManager).on("projectOpen", function () {
fileList = null;
});
// TODO: allow QuickOpenJS to register it's own commands and key bindings
CommandManager.register(Strings.CMD_QUICK_OPEN, Commands.NAVIGATE_QUICK_OPEN, doFileSearch);

2
src/thirdparty/CodeMirror2 поставляемый

@ -1 +1 @@
Subproject commit 6a33096e6021fa5c48abf2867e7b68569168e24a
Subproject commit 20cbf22edfefcf06892907120b779a228e0030ab

Просмотреть файл

@ -761,11 +761,7 @@ define(function (require, exports, module) {
* (This object's caches are all stored in "_" prefixed properties.)
*/
function StringMatcher() {
// We keep track of the last query to know when we need to invalidate.
this._lastQuery = null;
this._specialsCache = {};
this._noMatchCache = {};
this.reset();
}
/**
@ -782,6 +778,17 @@ define(function (require, exports, module) {
*/
StringMatcher.prototype._noMatchCache = null;
/**
* Clears the caches. Use this in the event that the caches may be invalid.
*/
StringMatcher.prototype.reset = function () {
// We keep track of the last query to know when we need to invalidate.
this._lastQuery = null;
this._specialsCache = {};
this._noMatchCache = {};
};
/**
* Performs a single match using the stringMatch function. See stringMatch for full documentation.
*

Просмотреть файл

@ -76,24 +76,60 @@ define(function (require, exports, module) {
* @type {boolean}
*/
var _fontSizePrefsLoaded = false;
/**
* @private
* Removes the styles used to update the font size and updates the editor if refresh is true
* @param {boolean} refresh - True to refresh the current full editor
* Removes the styles used to update the font size
*/
function _removeDynamicFontSize(refresh) {
function _removeDynamicFontSize() {
$("#" + DYNAMIC_FONT_STYLE_ID).remove();
if (refresh) {
EditorManager.getCurrentFullEditor().refreshAll();
}
/**
* @private
* Sets the font size and restores the scroll position as best as possible.
* TODO: Remove the viewportTop hack and direclty use scrollPos.y once #3115 is fixed.
* @param {string} fontSizeStyle A string with the font size and the size unit
* @param {string} lineHeightStyle A string with the line height and a the size unit
*/
function _setSizeAndRestoreScroll(fontSizeStyle, lineHeightStyle) {
var editor = EditorManager.getCurrentFullEditor(),
oldWidth = editor._codeMirror.defaultCharWidth(),
oldHeight = editor.getTextHeight(),
scrollPos = editor.getScrollPos(),
viewportTop = $(".CodeMirror-lines", editor.getRootElement()).parent().position().top,
scrollTop = scrollPos.y - viewportTop;
// It's necessary to inject a new rule to address all editors.
_removeDynamicFontSize();
var style = $("<style type='text/css'></style>").attr("id", DYNAMIC_FONT_STYLE_ID);
style.html(".CodeMirror {" +
"font-size: " + fontSizeStyle + " !important;" +
"line-height: " + lineHeightStyle + " !important;}");
$("head").append(style);
editor.refreshAll();
// Calculate the new scroll based on the old font sizes and scroll position
var newWidth = editor._codeMirror.defaultCharWidth(),
newHeight = editor.getTextHeight(),
deltaX = scrollPos.x / oldWidth,
deltaY = scrollTop / oldHeight,
scrollPosX = scrollPos.x + Math.round(deltaX * (newWidth - oldWidth)),
scrollPosY = scrollPos.y + Math.round(deltaY * (newHeight - oldHeight));
// Scroll the document back to its original position, but not on the first load since the position
// was saved with the new height and already been restored.
if (_fontSizePrefsLoaded) {
editor.setScrollPos(scrollPosX, scrollPosY);
}
}
/**
* @private
* Increases or decreases the editor's font size.
* @param {number} negative number to make the font smaller; positive number to make it bigger.
* @param {number} adjustment Negative number to make the font smaller; positive number to make it bigger
* @return {boolean} true if adjustment occurred, false if it did not occur
*/
function _adjustFontSize(adjustment) {
@ -136,48 +172,28 @@ define(function (require, exports, module) {
return false;
}
// It's necessary to inject a new rule to address all editors.
_removeDynamicFontSize(false);
var style = $("<style type='text/css'></style>").attr("id", DYNAMIC_FONT_STYLE_ID);
style.html(".CodeMirror {" +
"font-size: " + fsStr + " !important;" +
"line-height: " + lhStr + " !important;}");
$("head").append(style);
var editor = EditorManager.getCurrentFullEditor();
editor.refreshAll();
// Scroll the document back to its original position. This can only happen
// if the font size is specified in pixels (which it currently is).
if (fsUnits === "px") {
var scrollPos = editor.getScrollPos();
var scrollDeltaX = Math.round(scrollPos.x / lhOld);
var scrollDeltaY = Math.round(scrollPos.y / lhOld);
scrollDeltaX = (adjustment >= 0 ? scrollDeltaX : -scrollDeltaX);
scrollDeltaY = (adjustment >= 0 ? scrollDeltaY : -scrollDeltaY);
editor.setScrollPos((scrollPos.x + scrollDeltaX),
(scrollPos.y + scrollDeltaY));
}
_setSizeAndRestoreScroll(fsStr, lhStr);
return true;
}
/** Increases the font size by 1 */
function _handleIncreaseFontSize() {
if (_adjustFontSize(1)) {
_prefs.setValue("fontSizeAdjustment", _prefs.getValue("fontSizeAdjustment") + 1);
}
}
/** Decreases the font size by 1 */
function _handleDecreaseFontSize() {
if (_adjustFontSize(-1)) {
_prefs.setValue("fontSizeAdjustment", _prefs.getValue("fontSizeAdjustment") - 1);
}
}
/** Restores the font size to the original size */
function _handleRestoreFontSize() {
_removeDynamicFontSize(true);
_adjustFontSize(-_prefs.getValue("fontSizeAdjustment"));
_prefs.setValue("fontSizeAdjustment", 0);
}
@ -198,7 +214,7 @@ define(function (require, exports, module) {
// Font Size preferences only need to be loaded one time
if (!_fontSizePrefsLoaded) {
_removeDynamicFontSize(false);
_removeDynamicFontSize();
_adjustFontSize(_prefs.getValue("fontSizeAdjustment"));
_fontSizePrefsLoaded = true;
}
@ -216,10 +232,10 @@ define(function (require, exports, module) {
/**
* @private
* Calculates the first and last visible lines of the focused editor
* @param {!number} textHeight
* @param {!number} scrollTop
* @param {!number} editorHeight
* @param {!number} viewportFrom
* @param {number} textHeight
* @param {number} scrollTop
* @param {number} editorHeight
* @param {number} viewportFrom
* @return {{first: number, last: number}}
*/
function _getLinesInView(textHeight, scrollTop, editorHeight, viewportFrom) {
@ -237,7 +253,7 @@ define(function (require, exports, module) {
/**
* @private
* Scroll the viewport one line up or down.
* @param {number} -1 to scroll one line up; 1 to scroll one line down.
* @param {number} direction -1 to scroll one line up; 1 to scroll one line down.
*/
function _scrollLine(direction) {
var editor = EditorManager.getCurrentFullEditor(),
@ -306,10 +322,12 @@ define(function (require, exports, module) {
}
}
/** Scrolls one line up */
function _handleScrollLineUp() {
_scrollLine(-1);
}
/** Scrolls one line down */
function _handleScrollLineDown() {
_scrollLine(1);
}
@ -326,7 +344,7 @@ define(function (require, exports, module) {
KeyBindingManager.addBinding(Commands.VIEW_SCROLL_LINE_UP);
KeyBindingManager.addBinding(Commands.VIEW_SCROLL_LINE_DOWN);
// Init PreferenceStorage
// Initialize the PreferenceStorage
_prefs = PreferencesManager.getPreferenceStorage(module, _defaultPrefs);
// Update UI when opening or closing a document

Просмотреть файл

@ -24,7 +24,7 @@
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */
define(function (require, exports, module) {
'use strict';
"use strict";
require("spec/CodeHint-test");
require("spec/CodeHintUtils-test");
@ -41,6 +41,7 @@ define(function (require, exports, module) {
require("spec/ExtensionUtils-test");
require("spec/FileIndexManager-test");
require("spec/FindReplace-test");
require("spec/HTMLInstrumentation-test");
require("spec/InlineEditorProviders-test");
require("spec/InstallExtensionDialog-test");
require("spec/KeyBindingManager-test");
@ -57,6 +58,7 @@ define(function (require, exports, module) {
require("spec/QuickOpen-test");
require("spec/StringMatch-test");
require("spec/UpdateNotification-test");
require("spec/ViewCommandHandlers-test");
require("spec/ViewUtils-test");
require("spec/WorkingSetView-test");
});

Просмотреть файл

@ -0,0 +1,53 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
//<![CDATA[
document.write("<");
//]]>
</SCRIPT>
<STYLE type="text/css">
/*<![CDATA[*/
body { background-image: url("marble.png?width=300&height=300") }
/*]]>*/
</style>
</head>
<body>
<P><b>bold <i>and italic</b> text</i></P>
A paragraph with no opening tag</p>
<h2>a header with <br> a<wbr>line</wbr>break</h2>
<name>custom tag</name>
<table width="200" border="1">
<caption>A table with some 'tr' tags missing</caption>
<th>Name
<th>Address</th>
<th>Phone
<tr>
<td>Name
<td>Address
<td>Phone
</tr>
<tr>
<td>Name
<td>Address</td>
<td>Phone
</tr>
</table>
<form name="form1" method="post" action="http://somesite.com/prog/adduser">
<input type="button" name="prev" id="prev" value="<Prev" />
<input type="button" name="next" id="next" value="Next>"></input>
<label for="select"></label>
<select name="select" id="select">
<option value="1">item1
<option value="2">item2</option>
<option value="3">item3
</select>
</form>
<hr>
<a href="http:\\nowhere.com"><p>an unclosed paragraph inside a link</a>
<hr />
</body>
</html>

Просмотреть файл

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
<p>A paragraph with no closing tag
<h1>h1<wbr>tag that auto closes the preceding p tag</h1>
<div>
<ul>
<li>first item
<li>second item<br> with a line break</li>
<li>3rd item
</ul>
</div>
<table width="200" border="1">
<tr>
<th>Name
<th>Address</th>
<th>Phone
<tr>
<td>Name
<td>Address
<td>Phone
</tr>
<tr>
<td>Name
<td><pre>Address</pre></td>
<td>Phone
</tr>
</table>
<form name="form1" method="post" action="http://somesite.com/prog/adduser">
<input type="button" name="prev" id="prev" value="<Prev">
<input type="button" name="next" id="next" value="Next>">
<hr>
<label for="select">Select your magic number:</label>
<select name="select" id="select">
<option value="1">item1
<option value="2">item2</option>
<option value="3">item3
</select>
</form>
<p><mark>selected color</mark></p>
<script type="text/javascript">
//<![CDATA[
document.write("<");
//]]>
</script>
<FOOTER>SOME FOOTNOTE</FOOTER>

Просмотреть файл

@ -0,0 +1,146 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>GETTING STARTED WITH BRACKETS</title>
<meta name="description" content="An interactive getting started guide for Brackets.">
<link rel="stylesheet" href="test.css">
</head>
<body>
<h1>GETTING STARTED WITH BRACKETS</h1>
<h2>This is your guide!</h2>
<!--
MADE WITH <3 AND JAVASCRIPT
-->
<p>
Welcome to an early preview of Brackets, a new open-source editor for the next generation of
the web. Were big fans of standards and want to build better tooling for JavaScript, HTML and CSS
and related open web technologies. This is our humble beginning.
</p>
<!--
WHAT IS BRACKETS?
-->
<p>
<em>You are looking at an early build of Brackets.</em>
In many ways, Brackets is a different type of editor. One notable difference is that this editor
is written in JavaScript. So while Brackets might not be ready for your day-to-day use quite yet,
we are using it every day to build Brackets.
</p>
<h2>We're trying out a few new things</h2>
<!--
THE RELATIONSHIP BETWEEN HTML, CSS AND JAVASCRIPT
-->
<h3>Quick Edit for CSS and JavaScript</h3>
<p>
When editing HTML, use the <kbd>Cmd/Ctrl + E</kbd> shortcut to open a quick inline editor that
displays all the related CSS. Make a tweak to your CSS, hit <kbd>ESC</kbd> and youre back to
editing HTML. Or just leave the CSS rules open and theyll become part of your HTML editor.
If you hit <kbd>ESC</kbd> outside of a quick editor, theyll all collapse. No more switching between
documents and losing your context.
</p>
<samp>
Want to see it in action? Place your cursor on the <!-- <samp> --> tag above and press
<kbd>Cmd/Ctrl + E</kbd>. You should see a CSS quick editor appear above. On the right you will see
a list of the CSS rules that are related to this tag. Simply scroll the rules with
<kbd>Alt + Up/Down</kbd> to find the one you want to edit.
</samp>
<a href="screenshots/brackets-quick-edit.png">
<img alt="A screenshot showing CSS Quick Edit" src="screenshots/brackets-quick-edit.png" />
</a>
<p>
You can use the same shortcut in JavaScript code to view the body of a function you're calling, by
placing the cursor on the function name. Or open a graphical color picker by placing the cursor on
any color in hex, rgb or hsl format. For now inline editors cannot be nested, so you can only use
Quick Edit while the cursor is in a "full size" editor.
</p>
<!--
LIVE PREVIEW
-->
<h3>Preview CSS changes live in the browser</h3>
<p>
You know that "save/reload dance" we've been doing for years? The one where you make changes in
your editor, hit save, switch to the browser and then refresh to finally see the result?
With Brackets, you don't have to do that dance.
</p>
<p>
Brackets will open a <em>live connection</em> to your local browser and push CSS updates as you
type! You might already be doing something like this today with browser-based tools, but with Brackets
there is no need to copy and paste the final CSS back into the editor. Your code runs in the
browser, but lives in your editor!
</p>
<samp>
If you have Google Chrome installed, you can try this out yourself. Click on the lightning bolt
icon in the top right or hit <kbd>Cmd/Ctrl + Alt + P</kbd>. When Live Preview is enabled on
an HTML document, all linked CSS documents can be edited in real-time. The icon will change from
gray to gold when Brackets establishes a connection to your browser.
Now, place your cursor on the <!-- <img> --> tag above and use <kbd>Cmd/Ctrl + E</kbd> to open up the
defined CSS rules. Try changing the size of the border from 1px to 10px or change the background
color from "dimgray" to "hotpink". If you have Brackets and your browser running side-by-side, you
will see your changes instantly reflected in your browser. Cool, right?
</samp>
<p class="note">
Today, Brackets only supports Live Preview for CSS. We are currently working on Live Preview support
for HTML and JavaScript. In the current version, changes to HTML or JavaScript files are automatically
reloaded when you save. Live previews are only possible with Google Chrome. We want to bring this
functionality to all major browsers, and we're looking forward to working with those vendors to do so.
</p>
<!--
LET US KNOW WHAT YOU THINK
-->
<h2>Get Involved</h2>
<p>
Brackets is an open-source project. Web developers from around the world are contributing to build
a better code editor. Let us know what you think, share your ideas or contribute directly to the
project.
</p>
<ul>
<li><a href="http://brackets.io">Brackets.io</a></li>
<li><a href="http://blog.brackets.io">Brackets Team Blog</a></li>
<li><a href="http://github.com/adobe/brackets">Brackets on GitHub</a></li>
<li><a href="http://github.com/adobe/brackets/wiki">Brackets Wiki</a></li>
<li><a href="http://groups.google.com/group/brackets-dev">Brackets Developer Mailing List</a></li>
<li><a href="https://twitter.com/#!/brackets">@Brackets on Twitter</a></li>
<li>Chat with Brackets developers on IRC in #brackets on Freenode</li>
</ul>
</body>
</html>
<!--
[[[[[[[[[[[[[[[ ]]]]]]]]]]]]]]]
[:::::::::::::: ::::::::::::::]
[:::::::::::::: ::::::::::::::]
[::::::[[[[[[[: :]]]]]]]::::::]
[:::::[ ]:::::]
[:::::[ ]:::::]
[:::::[ ]:::::]
[:::::[ ]:::::]
[:::::[ CODE THE WEB ]:::::]
[:::::[ http://brackets.io ]:::::]
[:::::[ ]:::::]
[:::::[ ]:::::]
[:::::[ ]:::::]
[:::::[ ]:::::]
[::::::[[[[[[[: :]]]]]]]::::::]
[:::::::::::::: ::::::::::::::]
[:::::::::::::: ::::::::::::::]
[[[[[[[[[[[[[[[ ]]]]]]]]]]]]]]]
-->

Просмотреть файл

@ -0,0 +1,499 @@
/*
* Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, $, describe, beforeEach, afterEach, it, runs, waitsFor, expect, spyOn */
define(function (require, exports, module) {
"use strict";
// Load dependent modules
var NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem,
FileUtils = require("file/FileUtils"),
HTMLInstrumentation = require("language/HTMLInstrumentation"),
SpecRunnerUtils = require("spec/SpecRunnerUtils");
var testPath = SpecRunnerUtils.getTestPath("/spec/HTMLInstrumentation-test-files"),
WellFormedFileEntry = new NativeFileSystem.FileEntry(testPath + "/wellformed.html"),
NotWellFormedFileEntry = new NativeFileSystem.FileEntry(testPath + "/omitEndTags.html"),
InvalidHTMLFileEntry = new NativeFileSystem.FileEntry(testPath + "/invalidHTML.html"),
editor,
instrumentedHTML,
elementCount,
elementIds = {};
function init(spec, fileEntry) {
spec.fileContent = null;
if (fileEntry) {
runs(function () {
FileUtils.readAsText(fileEntry)
.done(function (text) {
spec.fileContent = text;
});
});
waitsFor(function () { return (spec.fileContent !== null); }, 1000);
}
}
describe("HTML Instrumentation", function () {
function getIdToTagMap(instrumentedHTML, map) {
var count = 0;
var elementIdRegEx = /<(\w+?)\s+(?:[^<]*?\s)*?data-brackets-id='(\S+?)'/gi,
match,
tagID,
tagName;
do {
match = elementIdRegEx.exec(instrumentedHTML);
if (match) {
tagID = match[2];
tagName = match[1];
// Verify that the newly found ID is unique.
expect(map[tagID]).toBeUndefined();
map[tagID] = tagName.toLowerCase();
count++;
}
} while (match);
return count;
}
function checkTagIdAtPos(pos, expectedTag) {
var tagID = HTMLInstrumentation._getTagIDAtDocumentPos(editor, pos);
if (!expectedTag) {
expect(tagID).toBe(-1);
} else {
expect(elementIds[tagID]).toBe(expectedTag);
}
}
function verifyMarksCreated() {
var cm = editor._codeMirror,
marks = cm.getAllMarks();
expect(marks.length).toBeGreaterThan(0);
}
describe("HTML Instrumentation in wellformed HTML", function () {
beforeEach(function () {
init(this, WellFormedFileEntry);
runs(function () {
editor = SpecRunnerUtils.createMockEditor(this.fileContent, "html").editor;
expect(editor).toBeTruthy();
spyOn(editor.document, "getText").andCallThrough();
instrumentedHTML = HTMLInstrumentation.generateInstrumentedHTML(editor.document);
elementCount = getIdToTagMap(instrumentedHTML, elementIds);
if (elementCount) {
HTMLInstrumentation._markText(editor);
verifyMarksCreated();
}
});
});
afterEach(function () {
SpecRunnerUtils.destroyMockEditor(editor.document);
editor = null;
instrumentedHTML = "";
elementCount = 0;
elementIds = {};
});
it("should instrument all start tags except some empty tags", function () {
runs(function () {
expect(elementCount).toEqual(49);
});
});
it("should have created cache and never call document.getText() again", function () {
runs(function () {
// scanDocument call here is to test the cache.
// HTMLInstrumentation.generateInstrumentedHTML call in "beforeEach"
// in turn calls scanDocument. Each function calls document.getText once
// and hence we've already had 2 calls from "beforeEach", but the following
// call should not call it again.
HTMLInstrumentation.scanDocument(editor.document);
expect(editor.document.getText.callCount).toBe(2);
});
});
it("should have recreated cache when document timestamp is different", function () {
runs(function () {
// update document timestamp with current time.
editor.document.diskTimestamp = new Date();
// This is an intentional repeat call to recreate the cache.
HTMLInstrumentation.scanDocument(editor.document);
// 2 calls from generateInstrumentedHTML call and one call
// from above scanDocument call. so total is 3.
expect(editor.document.getText.callCount).toBe(3);
});
});
it("should get 'img' tag for cursor positions inside img tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 58, ch: 4 }, "img"); // before <img
checkTagIdAtPos({ line: 58, ch: 95 }, "img"); // after />
checkTagIdAtPos({ line: 58, ch: 65 }, "img"); // inside src attribute value
});
});
it("should get the parent 'a' tag for cursor positions between 'img' and its parent 'a' tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 58, ch: 1 }, "a"); // before " <img"
checkTagIdAtPos({ line: 59, ch: 0 }, "a"); // before </a>
});
});
it("No tag at cursor positions outside of the 'html' tag", function () {
runs(function () {
checkTagIdAtPos({ line: 0, ch: 4 }, ""); // inside 'doctype' tag
checkTagIdAtPos({ line: 146, ch: 0 }, ""); // after </html>
});
});
it("Should get parent tag (body) for all cursor positions inside an html comment", function () {
runs(function () {
checkTagIdAtPos({ line: 15, ch: 1 }, "body"); // cursor between < and ! in the comment start
checkTagIdAtPos({ line: 16, ch: 15 }, "body");
checkTagIdAtPos({ line: 17, ch: 3 }, "body"); // cursor after -->
});
});
it("should get 'meta/link' tag for cursor positions in meta/link tags, not 'head' tag", function () {
runs(function () {
checkTagIdAtPos({ line: 5, ch: 64 }, "meta");
checkTagIdAtPos({ line: 8, ch: 12 }, "link");
});
});
it("Should get 'title' tag at cursor positions (either in the content or begin/end tag)", function () {
runs(function () {
checkTagIdAtPos({ line: 6, ch: 11 }, "title"); // inside the begin tag
checkTagIdAtPos({ line: 6, ch: 30 }, "title"); // in the content
checkTagIdAtPos({ line: 6, ch: 50 }, "title"); // inside the end tag
});
});
it("Should get 'h2' tag at cursor positions (either in the content or begin or end tag)", function () {
runs(function () {
checkTagIdAtPos({ line: 13, ch: 1 }, "h2"); // inside the begin tag
checkTagIdAtPos({ line: 13, ch: 20 }, "h2"); // in the content
checkTagIdAtPos({ line: 13, ch: 27 }, "h2"); // inside the end tag
});
});
});
describe("HTML Instrumentation in valid but not wellformed HTML", function () {
beforeEach(function () {
init(this, NotWellFormedFileEntry);
runs(function () {
editor = SpecRunnerUtils.createMockEditor(this.fileContent, "html").editor;
expect(editor).toBeTruthy();
instrumentedHTML = HTMLInstrumentation.generateInstrumentedHTML(editor.document);
elementCount = getIdToTagMap(instrumentedHTML, elementIds);
if (elementCount) {
HTMLInstrumentation._markText(editor);
verifyMarksCreated();
}
});
});
afterEach(function () {
SpecRunnerUtils.destroyMockEditor(editor.document);
editor = null;
instrumentedHTML = "";
elementCount = 0;
elementIds = {};
});
it("should instrument all start tags except some empty tags", function () {
runs(function () {
expect(elementCount).toEqual(41);
});
});
it("should get 'p' tag for cursor positions before the succeding start tag of an unclosed 'p' tag", function () {
runs(function () {
checkTagIdAtPos({ line: 8, ch: 36 }, "p"); // at the end of the line that has p start tag
checkTagIdAtPos({ line: 8, ch: 2 }, "p"); // at the beginning of the <p>
checkTagIdAtPos({ line: 8, ch: 4 }, "p"); // inside <p> tag
checkTagIdAtPos({ line: 8, ch: 5 }, "p"); // after <p> tag
checkTagIdAtPos({ line: 9, ch: 0 }, "p"); // before <h1> tag, but considered to be the end of 'p' tag
});
});
it("should get 'h1' tag for cursor positions inside 'h1' that is following an unclosed 'p' tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 9, ch: 20 }, "h1"); // inside text content of h1 tag
checkTagIdAtPos({ line: 9, ch: 52 }, "h1"); // inside </h1>
});
});
it("should get 'wbr' tag for cursor positions inside <wbr>, not its parent 'h1' tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 9, ch: 10 }, "wbr"); // inside <wbr> that is in h1 content
});
});
it("should get 'li' tag for cursor positions inside the content of an unclosed 'li' tag", function () {
runs(function () {
checkTagIdAtPos({ line: 12, ch: 12 }, "li"); // inside first list item
checkTagIdAtPos({ line: 14, ch: 12 }, "li"); // inside third list item
checkTagIdAtPos({ line: 15, ch: 0 }, "li"); // before </ul> tag that follows an unclosed 'li'
});
});
it("should get 'br' tag for cursor positions inside <br>, not its parent 'li' tag", function () {
runs(function () {
checkTagIdAtPos({ line: 13, ch: 22 }, "br"); // inside the <br> tag of the second list item
});
});
it("should get 'ul' tag for cursor positions within 'ul' but outside of any unclosed 'li'.", function () {
runs(function () {
checkTagIdAtPos({ line: 12, ch: 0 }, "ul"); // before first '<li>' tag
checkTagIdAtPos({ line: 15, ch: 8 }, "ul"); // inside </ul>
});
});
it("should get 'table' tag for cursor positions that are not in any unclosed child tags", function () {
runs(function () {
checkTagIdAtPos({ line: 17, ch: 17 }, "table"); // inside an attribute of table tag
checkTagIdAtPos({ line: 21, ch: 0 }, "table"); // after a 'th' but before the start tag of another one
checkTagIdAtPos({ line: 32, ch: 6 }, "table"); // inside </table> tag
});
});
it("should get 'input' tag for cursor positions inside one of the 'input' tags.", function () {
runs(function () {
checkTagIdAtPos({ line: 34, ch: 61 }, "input"); // at the end of first input tag
checkTagIdAtPos({ line: 35, ch: 4 }, "input"); // at the first position of the 2nd input tag
});
});
it("should get 'option' tag for cursor positions in any unclosed 'option' tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 40, ch: 0 }, "option"); // before second '<option>' tag
checkTagIdAtPos({ line: 41, ch: 28 }, "option"); // after third option tag that is unclosed
});
});
it("should NOT get 'option' tag for cursor positions in the parent tags of an unclosed 'option'.", function () {
runs(function () {
checkTagIdAtPos({ line: 42, ch: 5 }, "select"); // inside '</select>' tag
checkTagIdAtPos({ line: 43, ch: 5 }, "form"); // inside '</form>' tag
});
});
it("should get 'label' tag for cursor positions in the 'label' tag or its content.", function () {
runs(function () {
checkTagIdAtPos({ line: 37, ch: 17 }, "label"); // in the attribute of 'label' tag
checkTagIdAtPos({ line: 37, ch: 49 }, "label"); // in the text content
checkTagIdAtPos({ line: 37, ch: 55 }, "label"); // in the end 'label' tag
});
});
it("should get 'form' tag for cursor positions NOT in any form element.", function () {
runs(function () {
checkTagIdAtPos({ line: 35, ch: 0 }, "form"); // between two input tags
checkTagIdAtPos({ line: 43, ch: 2 }, "form"); // before </form> tag
});
});
it("should get 'hr' tag for cursor positions in <hr> tag, not its parent <form> tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 36, ch: 6 }, "hr"); // inside <hr>
});
});
it("should get 'script' tag for cursor positions anywhere inside the tag including CDATA.", function () {
runs(function () {
checkTagIdAtPos({ line: 46, ch: 6 }, "script"); // before '<' of CDATA
checkTagIdAtPos({ line: 48, ch: 7 }, "script"); // right before '>' of CDATA
checkTagIdAtPos({ line: 45, ch: 18 }, "script"); // inside an attribute value of 'script' tag
checkTagIdAtPos({ line: 47, ch: 20 }, "script"); // before '<' of a literal string
checkTagIdAtPos({ line: 49, ch: 9 }, "script"); // inside 'script' end tag
});
});
it("should get 'footer' tag that is explicitly using all uppercase tag names.", function () {
runs(function () {
checkTagIdAtPos({ line: 50, ch: 3 }, "footer"); // in <FOOTER>
checkTagIdAtPos({ line: 50, ch: 20 }, "footer"); // in the text content
checkTagIdAtPos({ line: 50, ch: 30 }, "footer"); // in </FOOTER>
});
});
});
describe("HTML Instrumentation in an HTML page with some invalid markups", function () {
beforeEach(function () {
init(this, InvalidHTMLFileEntry);
runs(function () {
editor = SpecRunnerUtils.createMockEditor(this.fileContent, "html").editor;
expect(editor).toBeTruthy();
instrumentedHTML = HTMLInstrumentation.generateInstrumentedHTML(editor.document);
elementCount = getIdToTagMap(instrumentedHTML, elementIds);
if (elementCount) {
HTMLInstrumentation._markText(editor);
verifyMarksCreated();
}
});
});
afterEach(function () {
SpecRunnerUtils.destroyMockEditor(editor.document);
editor = null;
instrumentedHTML = "";
elementCount = 0;
elementIds = {};
});
it("should instrument all start tags except some empty tags", function () {
runs(function () {
expect(elementCount).toEqual(39);
});
});
it("should get 'script' tag for cursor positions anywhere inside the tag including CDATA.", function () {
runs(function () {
checkTagIdAtPos({ line: 6, ch: 11 }, "script"); // before '<' of CDATA
checkTagIdAtPos({ line: 8, ch: 12 }, "script"); // right before '>' of CDATA
checkTagIdAtPos({ line: 5, ch: 33 }, "script"); // inside an attribute value of 'script' tag
checkTagIdAtPos({ line: 7, ch: 25 }, "script"); // after '<' of a literal string
checkTagIdAtPos({ line: 9, ch: 9 }, "script"); // inside 'script' end tag
});
});
it("should get 'style' tag for cursor positions anywhere inside the tag including CDATA.", function () {
runs(function () {
checkTagIdAtPos({ line: 11, ch: 11 }, "style"); // before '<' of CDATA
checkTagIdAtPos({ line: 13, ch: 12 }, "style"); // right before '>' of CDATA
checkTagIdAtPos({ line: 10, ch: 26 }, "style"); // before '>' of the 'style' tag
checkTagIdAtPos({ line: 12, ch: 33 }, "style"); // inside a property value
checkTagIdAtPos({ line: 14, ch: 9 }, "style"); // inside 'style' end tag
});
});
it("should get 'i' tag for cursor positions before </b>, inside </b> and after </b>.", function () {
runs(function () {
checkTagIdAtPos({ line: 18, ch: 20 }, "i"); // after <i> and before </b>
checkTagIdAtPos({ line: 18, ch: 30 }, "i"); // inside </b>
checkTagIdAtPos({ line: 18, ch: 34 }, "i"); // between </b> and </i>
});
});
it("should get 'body' tag in a paragraph that has missing <p> tag, but has </p>", function () {
runs(function () {
checkTagIdAtPos({ line: 19, ch: 15 }, "body"); // before </p>
checkTagIdAtPos({ line: 19, ch: 38 }, "body"); // inside </p>
});
});
it("should get 'hr' tag for cursor positions in any forms of <hr> tag", function () {
runs(function () {
checkTagIdAtPos({ line: 48, ch: 7 }, "hr"); // inside <hr>
checkTagIdAtPos({ line: 50, ch: 9 }, "hr"); // inside <hr />
});
});
it("should get 'h2' tag for cursor positions between <wbr> and its invalide end tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 20, ch: 35 }, "h2"); // in the text between <wbr> and </wbr>
});
});
it("should get 'wbr' tag for cursor positions inside <wbr>, not its parent <h2> tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 20, ch: 30 }, "wbr"); // inside <wbr>
});
});
it("should get 'h2' tag for cursor positions inside invalid </wbr> tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 20, ch: 40 }, "h2"); // inside </wbr>
});
});
it("should get 'name' tag for cursor positions before <name> and </name>.", function () {
runs(function () {
checkTagIdAtPos({ line: 21, ch: 8 }, "name"); // inside <name>
checkTagIdAtPos({ line: 21, ch: 12 }, "name"); // inside content of 'mame' tag
checkTagIdAtPos({ line: 21, ch: 22 }, "name"); // inside </name>
});
});
it("should get 'th' tag for cursor positions in any 'th' and their text contents.", function () {
runs(function () {
checkTagIdAtPos({ line: 24, ch: 16 }, "th"); // inside first th content
checkTagIdAtPos({ line: 25, ch: 21 }, "th"); // inside second </th>
checkTagIdAtPos({ line: 26, ch: 17 }, "th"); // at the end of third th content
checkTagIdAtPos({ line: 27, ch: 0 }, "th"); // before the next <tr>
});
});
it("should get 'input' tag for cursor positions in any input tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 39, ch: 57 }, "input"); // inside value attribute that has <
checkTagIdAtPos({ line: 39, ch: 64 }, "input"); // between / and > of input tag
checkTagIdAtPos({ line: 40, ch: 61 }, "input"); // inside value attribute that has >
checkTagIdAtPos({ line: 40, ch: 63 }, "input"); // right before the invalid </input>
});
});
it("should get 'form' tag for cursor positions in any invalid end tag inside the form.", function () {
runs(function () {
checkTagIdAtPos({ line: 40, ch: 65 }, "form"); // inside </input>
});
});
it("should get 'p' tag for cursor positions inside an unclosed paragraph nested in a link.", function () {
runs(function () {
checkTagIdAtPos({ line: 49, ch: 71 }, "p"); // before </a> but after <p> tag
});
});
it("should get 'a' tag for cursor positions not in the unclosed 'p' child tag.", function () {
runs(function () {
checkTagIdAtPos({ line: 49, ch: 32 }, "a"); // inside </a>
checkTagIdAtPos({ line: 49, ch: 72 }, "a"); // inside </a>
});
});
});
});
});

Просмотреть файл

@ -594,7 +594,7 @@ define(function (require, exports, module) {
});
describe("StringMatcher", function () {
it("should manage its caches properly", function () {
beforeEach(function () {
this.addMatchers({
toBeInCache: function (matcher, cacheName) {
var value = matcher[cacheName][this.actual];
@ -607,7 +607,9 @@ define(function (require, exports, module) {
return value !== undefined;
}
});
});
it("should manage its caches properly", function () {
var matcher = new StringMatch.StringMatcher();
expect(matcher._noMatchCache).toEqual({});
expect(matcher._specialsCache).toEqual({});
@ -646,6 +648,16 @@ define(function (require, exports, module) {
var hasOwnPropertyResult = matcher.match("hasOwnProperty", "h");
expect(hasOwnPropertyResult).toBeTruthy();
});
it("can reset the caches", function () {
var matcher = new StringMatch.StringMatcher();
matcher.match("foo", "spec/live");
expect("foo").toBeInCache(matcher, "_specialsCache");
expect("foo").toBeInCache(matcher, "_noMatchCache");
matcher.reset();
expect("foo").not.toBeInCache(matcher, "_specialsCache");
expect("foo").not.toBeInCache(matcher, "_noMatchCache");
});
});
});
});

Просмотреть файл

@ -0,0 +1,3 @@
.testClass {
color: red;
}

Просмотреть файл

@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>Simple Test</title>
<link rel="stylesheet" href="test.css">
</head>
<body>
<p class="testClass">Brackets is awesome!</p>
</body>
</html>

Просмотреть файл

@ -0,0 +1,156 @@
/*
* Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, describe, beforeEach, it, runs, expect, waitsForDone */
define(function (require, exports, module) {
"use strict";
var CommandManager, // loaded from brackets.test
Commands, // loaded from brackets.test
EditorManager, // loaded from brackets.test
FileViewController,
SpecRunnerUtils = require("spec/SpecRunnerUtils");
describe("ViewCommandHandlers", function () {
this.category = "integration";
var testPath = SpecRunnerUtils.getTestPath("/spec/ViewCommandHandlers-test-files"),
testWindow;
var CSS_FILE = testPath + "/test.css",
HTML_FILE = testPath + "/test.html";
beforeEach(function () {
var promise;
// Create a new window that will be shared by ALL tests in this spec.
if (!testWindow) {
SpecRunnerUtils.createTestWindowAndRun(this, function (w) {
testWindow = w;
// Load module instances from brackets.test
CommandManager = testWindow.brackets.test.CommandManager;
Commands = testWindow.brackets.test.Commands;
EditorManager = testWindow.brackets.test.EditorManager;
FileViewController = testWindow.brackets.test.FileViewController;
SpecRunnerUtils.loadProjectInTestWindow(testPath);
});
runs(function () {
promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: HTML_FILE});
waitsForDone(promise, "Open into working set");
});
runs(function () {
// Open inline editor onto test.css's ".testClass" rule
promise = SpecRunnerUtils.toggleQuickEditAtOffset(EditorManager.getCurrentFullEditor(), {line: 8, ch: 11});
waitsForDone(promise, "Open inline editor");
});
}
});
function getEditors() {
var editor = EditorManager.getCurrentFullEditor();
return {
editor: editor,
inline: editor.getInlineWidgets()[0].editors[0]
};
}
describe("Adjust the Font Size", function () {
it("should increase the font size in both editor and inline editor", function () {
runs(function () {
var editors = getEditors();
var expectedSize = editors.editor.getTextHeight() + 2;
CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
expect(editors.editor.getTextHeight()).toBe(expectedSize);
expect(editors.inline.getTextHeight()).toBe(expectedSize);
});
});
it("should decrease the font size in both editor and inline editor", function () {
runs(function () {
var editors = getEditors();
var expectedSize = editors.editor.getTextHeight() - 2;
CommandManager.execute(Commands.VIEW_DECREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_DECREASE_FONT_SIZE);
expect(editors.editor.getTextHeight()).toBe(expectedSize);
expect(editors.inline.getTextHeight()).toBe(expectedSize);
});
});
it("should restore the font size in both editor and inline editor", function () {
runs(function () {
var editors = getEditors();
var expectedSize = editors.editor.getTextHeight();
CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_RESTORE_FONT_SIZE);
expect(editors.editor.getTextHeight()).toBe(expectedSize);
expect(editors.inline.getTextHeight()).toBe(expectedSize);
});
});
it("should keep the same font size when opening another document", function () {
var promise, expectedSize, editor;
runs(function () {
editor = EditorManager.getCurrentFullEditor();
expectedSize = editor.getTextHeight() + 1;
promise = CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
waitsForDone(promise, "Increase font size");
});
runs(function () {
// Open another document and bring it to the front
waitsForDone(FileViewController.openAndSelectDocument(CSS_FILE, FileViewController.PROJECT_MANAGER),
"FILE_OPEN on file timeout", 1000);
});
runs(function () {
editor = EditorManager.getCurrentFullEditor();
expect(editor.getTextHeight()).toBe(expectedSize);
});
// This must be in the last spec in the suite.
runs(function () {
this.after(function () {
SpecRunnerUtils.closeTestWindow();
});
});
});
});
});
});